Merge branch 'main' into AttachmentsToChat
This commit is contained in:
@@ -30,6 +30,16 @@
|
|||||||
<artifactId>javafx-web</artifactId>
|
<artifactId>javafx-web</artifactId>
|
||||||
<version>${javafx.version}</version>
|
<version>${javafx.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjfx</groupId>
|
||||||
|
<artifactId>javafx-swing</artifactId>
|
||||||
|
<version>${javafx.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
|
<artifactId>imageio-webp</artifactId>
|
||||||
|
<version>3.11.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ module org.example.petshopdesktop {
|
|||||||
requires javafx.controls;
|
requires javafx.controls;
|
||||||
requires javafx.fxml;
|
requires javafx.fxml;
|
||||||
requires javafx.web;
|
requires javafx.web;
|
||||||
|
requires javafx.swing;
|
||||||
requires java.desktop;
|
requires java.desktop;
|
||||||
requires java.sql;
|
requires java.sql;
|
||||||
requires java.net.http;
|
requires java.net.http;
|
||||||
|
|||||||
@@ -1,22 +1,55 @@
|
|||||||
package org.example.petshopdesktop.util;
|
package org.example.petshopdesktop.util;
|
||||||
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
import javafx.embed.swing.SwingFXUtils;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import org.example.petshopdesktop.api.ApiClient;
|
import org.example.petshopdesktop.api.ApiClient;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public final class DesktopImageSupport {
|
public final class DesktopImageSupport {
|
||||||
|
|
||||||
private static final Map<String, Image> IMAGE_CACHE = new ConcurrentHashMap<>();
|
private static final Map<String, Image> IMAGE_CACHE = new ConcurrentHashMap<>();
|
||||||
private static final Map<String, Integer> ORIENTATION_CACHE = new ConcurrentHashMap<>();
|
private static final Map<String, Integer> ORIENTATION_CACHE = new ConcurrentHashMap<>();
|
||||||
|
private static final AtomicBoolean PLUGINS_SCANNED = new AtomicBoolean(false);
|
||||||
|
|
||||||
private DesktopImageSupport() {
|
private DesktopImageSupport() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ensurePlugins() {
|
||||||
|
if (PLUGINS_SCANNED.compareAndSet(false, true)) {
|
||||||
|
ImageIO.scanForPlugins();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isWebP(byte[] data) {
|
||||||
|
return data.length >= 12
|
||||||
|
&& data[0] == 'R' && data[1] == 'I' && data[2] == 'F' && data[3] == 'F'
|
||||||
|
&& data[8] == 'W' && data[9] == 'E' && data[10] == 'B' && data[11] == 'P';
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Image decodeImage(byte[] bytes) {
|
||||||
|
if (isWebP(bytes)) {
|
||||||
|
ensurePlugins();
|
||||||
|
try {
|
||||||
|
BufferedImage bi = ImageIO.read(new ByteArrayInputStream(bytes));
|
||||||
|
if (bi != null) {
|
||||||
|
return SwingFXUtils.toFXImage(bi, null);
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Image img = new Image(new ByteArrayInputStream(bytes));
|
||||||
|
return img.isError() ? null : img;
|
||||||
|
}
|
||||||
|
|
||||||
public static void loadImageInto(ImageView imageView, String imageUrl, double width, double height) {
|
public static void loadImageInto(ImageView imageView, String imageUrl, double width, double height) {
|
||||||
imageView.setFitWidth(width);
|
imageView.setFitWidth(width);
|
||||||
imageView.setFitHeight(height);
|
imageView.setFitHeight(height);
|
||||||
@@ -34,8 +67,8 @@ public final class DesktopImageSupport {
|
|||||||
try {
|
try {
|
||||||
byte[] bytes = java.net.URI.create(imageUrl).toURL().openStream().readAllBytes();
|
byte[] bytes = java.net.URI.create(imageUrl).toURL().openStream().readAllBytes();
|
||||||
int orientation = readExifOrientation(bytes);
|
int orientation = readExifOrientation(bytes);
|
||||||
Image image = new Image(new ByteArrayInputStream(bytes));
|
Image image = decodeImage(bytes);
|
||||||
if (!image.isError()) {
|
if (image != null) {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
imageView.setImage(image);
|
imageView.setImage(image);
|
||||||
imageView.setRotate(exifOrientationToAngle(orientation));
|
imageView.setRotate(exifOrientationToAngle(orientation));
|
||||||
@@ -58,8 +91,8 @@ public final class DesktopImageSupport {
|
|||||||
try {
|
try {
|
||||||
byte[] bytes = ApiClient.getInstance().getBytes(imageUrl);
|
byte[] bytes = ApiClient.getInstance().getBytes(imageUrl);
|
||||||
int orientation = readExifOrientation(bytes);
|
int orientation = readExifOrientation(bytes);
|
||||||
Image image = new Image(new ByteArrayInputStream(bytes));
|
Image image = decodeImage(bytes);
|
||||||
if (!image.isError()) {
|
if (image != null) {
|
||||||
IMAGE_CACHE.put(imageUrl, image);
|
IMAGE_CACHE.put(imageUrl, image);
|
||||||
ORIENTATION_CACHE.put(imageUrl, orientation);
|
ORIENTATION_CACHE.put(imageUrl, orientation);
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
|
|||||||
Reference in New Issue
Block a user