From 8e205ebca2ed75d220e1750b6b6e88b443f9b346 Mon Sep 17 00:00:00 2001 From: Harkamal Randhawa Date: Tue, 14 Apr 2026 00:17:43 -0600 Subject: [PATCH] add webp support desktop --- desktop/pom.xml | 10 +++++ desktop/src/main/java/module-info.java | 1 + .../util/DesktopImageSupport.java | 41 +++++++++++++++++-- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/desktop/pom.xml b/desktop/pom.xml index fe513dc6..6ecf5c6b 100644 --- a/desktop/pom.xml +++ b/desktop/pom.xml @@ -30,6 +30,16 @@ javafx-web ${javafx.version} + + org.openjfx + javafx-swing + ${javafx.version} + + + com.twelvemonkeys.imageio + imageio-webp + 3.11.0 + org.junit.jupiter diff --git a/desktop/src/main/java/module-info.java b/desktop/src/main/java/module-info.java index a13de731..93a6704e 100644 --- a/desktop/src/main/java/module-info.java +++ b/desktop/src/main/java/module-info.java @@ -2,6 +2,7 @@ module org.example.petshopdesktop { requires javafx.controls; requires javafx.fxml; requires javafx.web; + requires javafx.swing; requires java.desktop; requires java.sql; requires java.net.http; diff --git a/desktop/src/main/java/org/example/petshopdesktop/util/DesktopImageSupport.java b/desktop/src/main/java/org/example/petshopdesktop/util/DesktopImageSupport.java index e9521231..dba81e76 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/util/DesktopImageSupport.java +++ b/desktop/src/main/java/org/example/petshopdesktop/util/DesktopImageSupport.java @@ -1,22 +1,55 @@ package org.example.petshopdesktop.util; import javafx.application.Platform; +import javafx.embed.swing.SwingFXUtils; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import org.example.petshopdesktop.api.ApiClient; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; public final class DesktopImageSupport { private static final Map IMAGE_CACHE = new ConcurrentHashMap<>(); private static final Map ORIENTATION_CACHE = new ConcurrentHashMap<>(); + private static final AtomicBoolean PLUGINS_SCANNED = new AtomicBoolean(false); 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) { imageView.setFitWidth(width); imageView.setFitHeight(height); @@ -34,8 +67,8 @@ public final class DesktopImageSupport { 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()) { + Image image = decodeImage(bytes); + if (image != null) { Platform.runLater(() -> { imageView.setImage(image); imageView.setRotate(exifOrientationToAngle(orientation)); @@ -58,8 +91,8 @@ public final class DesktopImageSupport { try { byte[] bytes = ApiClient.getInstance().getBytes(imageUrl); int orientation = readExifOrientation(bytes); - Image image = new Image(new ByteArrayInputStream(bytes)); - if (!image.isError()) { + Image image = decodeImage(bytes); + if (image != null) { IMAGE_CACHE.put(imageUrl, image); ORIENTATION_CACHE.put(imageUrl, orientation); Platform.runLater(() -> {