Remove drawAvatarJ2D (#2027)
This commit is contained in:
@@ -23,6 +23,7 @@ import javafx.beans.value.ObservableValue;
|
|||||||
import javafx.scene.canvas.Canvas;
|
import javafx.scene.canvas.Canvas;
|
||||||
import javafx.scene.canvas.GraphicsContext;
|
import javafx.scene.canvas.GraphicsContext;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.image.PixelReader;
|
||||||
import javafx.scene.image.PixelWriter;
|
import javafx.scene.image.PixelWriter;
|
||||||
import org.jackhuang.hmcl.Metadata;
|
import org.jackhuang.hmcl.Metadata;
|
||||||
import org.jackhuang.hmcl.auth.Account;
|
import org.jackhuang.hmcl.auth.Account;
|
||||||
@@ -30,13 +31,10 @@ import org.jackhuang.hmcl.auth.ServerResponseMalformedException;
|
|||||||
import org.jackhuang.hmcl.auth.microsoft.MicrosoftAccount;
|
import org.jackhuang.hmcl.auth.microsoft.MicrosoftAccount;
|
||||||
import org.jackhuang.hmcl.auth.yggdrasil.*;
|
import org.jackhuang.hmcl.auth.yggdrasil.*;
|
||||||
import org.jackhuang.hmcl.task.FileDownloadTask;
|
import org.jackhuang.hmcl.task.FileDownloadTask;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
|
||||||
import org.jackhuang.hmcl.util.ResourceNotFoundError;
|
import org.jackhuang.hmcl.util.ResourceNotFoundError;
|
||||||
import org.jackhuang.hmcl.util.StringUtils;
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
import org.jackhuang.hmcl.util.javafx.BindingMapping;
|
import org.jackhuang.hmcl.util.javafx.BindingMapping;
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
@@ -217,23 +215,25 @@ public final class TexturesLoader {
|
|||||||
|
|
||||||
// ==== Avatar ====
|
// ==== Avatar ====
|
||||||
public static void drawAvatar(Canvas canvas, Image skin) {
|
public static void drawAvatar(Canvas canvas, Image skin) {
|
||||||
canvas.getGraphicsContext2D().clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
|
GraphicsContext g = canvas.getGraphicsContext2D();
|
||||||
|
g.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||||
|
|
||||||
int size = (int) canvas.getWidth();
|
int size = (int) canvas.getWidth();
|
||||||
int scale = (int) skin.getWidth() / 64;
|
int scale = (int) skin.getWidth() / 64;
|
||||||
int faceOffset = (int) Math.round(size / 18.0);
|
int faceOffset = (int) Math.round(size / 18.0);
|
||||||
|
|
||||||
GraphicsContext g = canvas.getGraphicsContext2D();
|
|
||||||
try {
|
try {
|
||||||
g.setImageSmoothing(false);
|
g.setImageSmoothing(false);
|
||||||
drawAvatarFX(g, skin, size, scale, faceOffset);
|
drawAvatar(g, skin, size, scale, faceOffset);
|
||||||
} catch (NoSuchMethodError ignored) {
|
} catch (NoSuchMethodError ignored) {
|
||||||
// Earlier JavaFX did not support GraphicsContext::setImageSmoothing, fallback to Java 2D
|
// Earlier JavaFX did not support GraphicsContext::setImageSmoothing
|
||||||
drawAvatarJ2D(g, skin, size, scale, faceOffset);
|
// In order to prevent the blurring caused by bilinear interpolation,
|
||||||
|
// we use the self-implemented nearest neighbor interpolation to scale
|
||||||
|
drawAvatarSlow(g, skin, size, scale, faceOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void drawAvatarFX(GraphicsContext g, Image skin, int size, int scale, int faceOffset) {
|
private static void drawAvatar(GraphicsContext g, Image skin, int size, int scale, int faceOffset) {
|
||||||
g.drawImage(skin,
|
g.drawImage(skin,
|
||||||
8 * scale, 8 * scale, 8 * scale, 8 * scale,
|
8 * scale, 8 * scale, 8 * scale, 8 * scale,
|
||||||
faceOffset, faceOffset, size - 2 * faceOffset, size - 2 * faceOffset);
|
faceOffset, faceOffset, size - 2 * faceOffset, size - 2 * faceOffset);
|
||||||
@@ -242,27 +242,33 @@ public final class TexturesLoader {
|
|||||||
0, 0, size, size);
|
0, 0, size, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void drawAvatarJ2D(GraphicsContext g, Image skin, int size, int scale, int faceOffset) {
|
private static void drawAvatarSlow(GraphicsContext g, Image skin, int size, int scale, int faceOffset) {
|
||||||
BufferedImage bi = FXUtils.fromFXImage(skin);
|
PixelReader reader = skin.getPixelReader();
|
||||||
|
PixelWriter writer = g.getPixelWriter();
|
||||||
|
drawImage(writer, reader,
|
||||||
|
8 * scale, 8 * scale, 8 * scale, 8 * scale,
|
||||||
|
faceOffset, faceOffset, size - 2 * faceOffset, size - 2 * faceOffset);
|
||||||
|
drawImage(writer, reader,
|
||||||
|
40 * scale, 8 * scale, 8 * scale, 8 * scale,
|
||||||
|
0, 0, size, size);
|
||||||
|
}
|
||||||
|
|
||||||
BufferedImage avatar = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
|
/*
|
||||||
Graphics2D g2d = avatar.createGraphics();
|
* Scale and draw image using nearest-neighbor interpolation
|
||||||
|
*/
|
||||||
|
private static void drawImage(PixelWriter writer, PixelReader reader,
|
||||||
|
int sx, int sy, int sw, int sh,
|
||||||
|
int dx, int dy, int dw, int dh) {
|
||||||
|
double xScale = ((double) sw) / dw;
|
||||||
|
double yScale = ((double) sh) / dh;
|
||||||
|
|
||||||
g2d.drawImage(bi,
|
for (int xOffset = 0; xOffset < dw; xOffset++) {
|
||||||
faceOffset, faceOffset, size - faceOffset, size - faceOffset,
|
for (int yOffset = 0; yOffset < dh; yOffset++) {
|
||||||
8 * scale, 8 * scale, 16 * scale, 16 * scale,
|
int color = reader.getArgb(sx + (int) (xOffset * xScale), sy + (int) (yOffset * yScale));
|
||||||
null);
|
|
||||||
g2d.drawImage(bi,
|
|
||||||
0, 0, size, size,
|
|
||||||
40 * scale, 8 * scale, 48 * scale, 16 * scale, null);
|
|
||||||
|
|
||||||
g2d.dispose();
|
// Draw only non-transparent pixels
|
||||||
|
if ((color >>> 24) != 0)
|
||||||
PixelWriter pw = g.getPixelWriter();
|
writer.setArgb(dx + xOffset, dy + yOffset, color);
|
||||||
|
|
||||||
for (int x = 0; x < size; x++) {
|
|
||||||
for (int y = 0; y < size; y++) {
|
|
||||||
pw.setArgb(x, y, avatar.getRGB(x, y));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user