From ed5cd09d3403dfb748a3ffd82aed7888e4dd9023 Mon Sep 17 00:00:00 2001 From: AIDA64S Date: Tue, 18 Jun 2024 16:54:49 +0800 Subject: [PATCH] add webp support --- .../org/teacon/slides/cache/ImageCache.java | 2 +- .../org/teacon/slides/cache/WebpToPng.java | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/teacon/slides/cache/WebpToPng.java diff --git a/src/main/java/org/teacon/slides/cache/ImageCache.java b/src/main/java/org/teacon/slides/cache/ImageCache.java index 4aa83f3..6fdc047 100644 --- a/src/main/java/org/teacon/slides/cache/ImageCache.java +++ b/src/main/java/org/teacon/slides/cache/ImageCache.java @@ -73,7 +73,7 @@ public CompletableFuture getResource(@Nonnull URI location, boolean onli final HttpCacheContext context = HttpCacheContext.create(); try (CloseableHttpResponse response = createResponse(location, context, online)) { try { - return IOUtils.toByteArray(response.getEntity().getContent()); + return WebpToPng.webpToPng(IOUtils.toByteArray(response.getEntity().getContent())); } catch (IOException e) { if (online) { Slideshow.LOGGER.warn("Failed to read bytes from remote source.", e); diff --git a/src/main/java/org/teacon/slides/cache/WebpToPng.java b/src/main/java/org/teacon/slides/cache/WebpToPng.java new file mode 100644 index 0000000..1bc4b75 --- /dev/null +++ b/src/main/java/org/teacon/slides/cache/WebpToPng.java @@ -0,0 +1,48 @@ +package org.teacon.slides.cache; + +import org.teacon.slides.Slideshow; + +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.stream.MemoryCacheImageInputStream; +import javax.imageio.stream.MemoryCacheImageOutputStream; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.util.Iterator; + +public final class WebpToPng { + private static boolean isWebP(byte[] webp) { + if (webp.length < 12) { + return false; + } + boolean isRiff = webp[0] == 'R' && webp[1] == 'I' && webp[2] == 'F' && webp[3] == 'F'; + boolean isWebp = webp[8] == 'W' && webp[9] == 'E' && webp[10] == 'B' && webp[11] == 'P'; + return isRiff && isWebp; + } + + public static byte[] webpToPng(byte[] webp) { + try { + if (!isWebP(webp)) { + return webp; + } + Iterator imageReader = ImageIO.getImageReadersByFormatName("webp"); + if (!imageReader.hasNext()) { + return webp; + } + ImageReader webpReader = imageReader.next(); + try (ByteArrayInputStream bais = new ByteArrayInputStream(webp); MemoryCacheImageInputStream inputStream = new MemoryCacheImageInputStream(bais)) { + webpReader.setInput(inputStream); + BufferedImage bufferedImage = webpReader.read(0); + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); MemoryCacheImageOutputStream outputStream = new MemoryCacheImageOutputStream(baos)) { + ImageIO.write(bufferedImage, "png", outputStream); + outputStream.flush(); + return baos.toByteArray(); + } + } + } catch (Exception e) { + Slideshow.LOGGER.warn("Failed to convert webp to PNG", e); + return webp; + } + } +} \ No newline at end of file