fixed rotated image for pets and product as well
This commit is contained in:
@@ -380,7 +380,7 @@ public class PetController {
|
||||
setGraphic(null);
|
||||
return;
|
||||
}
|
||||
DesktopImageSupport.loadImageInto(imageView, item, 24, 24);
|
||||
DesktopImageSupport.loadImageInto(imageView, item, 48, 48);
|
||||
setGraphic(container);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -12,6 +12,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
public final class DesktopImageSupport {
|
||||
|
||||
private static final Map<String, Image> IMAGE_CACHE = new ConcurrentHashMap<>();
|
||||
private static final Map<String, Integer> ORIENTATION_CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
private DesktopImageSupport() {
|
||||
}
|
||||
@@ -22,32 +23,49 @@ public final class DesktopImageSupport {
|
||||
imageView.setPreserveRatio(true);
|
||||
imageView.setSmooth(true);
|
||||
imageView.setImage(null);
|
||||
imageView.setRotate(0);
|
||||
|
||||
if (imageUrl == null || imageUrl.isBlank()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (imageUrl.startsWith("file:")) {
|
||||
Image image = new Image(imageUrl, 0, 0, true, true);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
byte[] bytes = java.net.URI.create(imageUrl).toURL().openStream().readAllBytes();
|
||||
int orientation = readExifOrientation(bytes);
|
||||
Image image = new Image(new ByteArrayInputStream(bytes));
|
||||
if (!image.isError()) {
|
||||
Platform.runLater(() -> {
|
||||
imageView.setImage(image);
|
||||
imageView.setRotate(exifOrientationToAngle(orientation));
|
||||
});
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}, "desktop-image-loader").start();
|
||||
return;
|
||||
}
|
||||
|
||||
Image cached = IMAGE_CACHE.get(imageUrl);
|
||||
if (cached != null) {
|
||||
imageView.setImage(cached);
|
||||
imageView.setRotate(exifOrientationToAngle(ORIENTATION_CACHE.getOrDefault(imageUrl, 1)));
|
||||
return;
|
||||
}
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
byte[] bytes = ApiClient.getInstance().getBytes(imageUrl);
|
||||
int orientation = readExifOrientation(bytes);
|
||||
Image image = new Image(new ByteArrayInputStream(bytes));
|
||||
if (!image.isError()) {
|
||||
IMAGE_CACHE.put(imageUrl, image);
|
||||
Platform.runLater(() -> imageView.setImage(image));
|
||||
ORIENTATION_CACHE.put(imageUrl, orientation);
|
||||
Platform.runLater(() -> {
|
||||
imageView.setImage(image);
|
||||
imageView.setRotate(exifOrientationToAngle(orientation));
|
||||
});
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
@@ -57,6 +75,59 @@ public final class DesktopImageSupport {
|
||||
public static void evict(String imageUrl) {
|
||||
if (imageUrl != null && !imageUrl.isBlank()) {
|
||||
IMAGE_CACHE.remove(imageUrl);
|
||||
ORIENTATION_CACHE.remove(imageUrl);
|
||||
}
|
||||
}
|
||||
|
||||
private static double exifOrientationToAngle(int orientation) {
|
||||
return switch (orientation) {
|
||||
case 3 -> 180;
|
||||
case 6 -> 90;
|
||||
case 8 -> -90;
|
||||
default -> 0;
|
||||
};
|
||||
}
|
||||
|
||||
private static int readExifOrientation(byte[] data) {
|
||||
try {
|
||||
if (data.length < 2 || (data[0] & 0xFF) != 0xFF || (data[1] & 0xFF) != 0xD8) return 1;
|
||||
int offset = 2;
|
||||
while (offset + 4 < data.length) {
|
||||
if ((data[offset] & 0xFF) != 0xFF) break;
|
||||
int marker = data[offset + 1] & 0xFF;
|
||||
int segLen = ((data[offset + 2] & 0xFF) << 8) | (data[offset + 3] & 0xFF);
|
||||
if (marker == 0xE1 && offset + 9 < data.length
|
||||
&& data[offset + 4] == 'E' && data[offset + 5] == 'x'
|
||||
&& data[offset + 6] == 'i' && data[offset + 7] == 'f'
|
||||
&& data[offset + 8] == 0 && data[offset + 9] == 0) {
|
||||
int tiff = offset + 10;
|
||||
boolean le = data[tiff] == 'I';
|
||||
int ifdOffset = readInt(data, tiff + 4, le);
|
||||
int ifd = tiff + ifdOffset;
|
||||
int entries = readShort(data, ifd, le);
|
||||
for (int i = 0; i < entries; i++) {
|
||||
int e = ifd + 2 + i * 12;
|
||||
if (e + 9 < data.length && readShort(data, e, le) == 0x0112) {
|
||||
return readShort(data, e + 8, le);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (marker == 0xDA) break;
|
||||
offset += 2 + segLen;
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int readShort(byte[] data, int offset, boolean le) {
|
||||
return le
|
||||
? (data[offset] & 0xFF) | ((data[offset + 1] & 0xFF) << 8)
|
||||
: ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
|
||||
}
|
||||
|
||||
private static int readInt(byte[] data, int offset, boolean le) {
|
||||
return le
|
||||
? (data[offset] & 0xFF) | ((data[offset + 1] & 0xFF) << 8) | ((data[offset + 2] & 0xFF) << 16) | ((data[offset + 3] & 0xFF) << 24)
|
||||
: ((data[offset] & 0xFF) << 24) | ((data[offset + 1] & 0xFF) << 16) | ((data[offset + 2] & 0xFF) << 8) | (data[offset + 3] & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user