From 340e624d72746bc11a9521b3d0b0f2bcef3366b3 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Fri, 3 Jan 2025 12:10:28 +0000 Subject: [PATCH] feat: Add support for WebP image format in clipboard and thumbnail handling --- lib/components/thumbnail.dart | 8 ++++++++ lib/platform/to_png.dart | 4 ++++ lib/platform/to_png_none.dart | 4 ++++ lib/utils/clipboard.dart | 17 ++++++++++++++--- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/lib/components/thumbnail.dart b/lib/components/thumbnail.dart index ce20f47..7e5ccb8 100644 --- a/lib/components/thumbnail.dart +++ b/lib/components/thumbnail.dart @@ -12,6 +12,7 @@ import '../api/file.dart'; import '../api/gallery.dart'; import '../globals.dart'; import '../utils.dart'; +import '../utils/clipboard.dart'; import '../viewer/single.dart'; import 'image.dart'; @@ -84,6 +85,7 @@ class _Thumbnail extends State { double? _iconSize; bool _disposed = false; String? _originalUrl; + ImageFmt _fmt = ImageFmt.jpg; void _onNsfwChanged(dynamic args) { final arguments = args as (String, bool)?; if (arguments == null) return; @@ -146,6 +148,9 @@ class _Thumbnail extends State { if (cache != null) { setState(() { _data = cache!.$1; + var headers = Headers.fromMap(cache!.$2); + _fmt = ImageFmt.fromMimeType(headers.value("content-type")) ?? + ImageFmt.jpg; _uri = cache!.$3 ?? _originalUrl; _isLoading = false; _cancel = null; @@ -168,6 +173,8 @@ class _Thumbnail extends State { 'Failed to get thumbnail: ${re.response.statusCode} ${re.response.statusMessage}'); } _uri = re.response.realUri.toString(); + _fmt = ImageFmt.fromMimeType(re.response.headers.value("content-type")) ?? + ImageFmt.jpg; final data = Uint8List.fromList(re.data); if (!_cancel!.isCancelled) { if (isImageCacheEnabled) { @@ -273,6 +280,7 @@ class _Thumbnail extends State { uri: _uri, originalUri: oUri, fileName: _fileName, + fmt: _fmt, dir: _dir, isNsfw: auth.canEditGallery == true ? () => widget._pMeta.isNsfw : null, diff --git a/lib/platform/to_png.dart b/lib/platform/to_png.dart index 9f54015..cd35f95 100644 --- a/lib/platform/to_png.dart +++ b/lib/platform/to_png.dart @@ -5,3 +5,7 @@ import 'package:image/image.dart'; Future jpgToPng(Uint8List data) async { return encodePng(decodeJpg(data)!); } + +Future webpToPng(Uint8List data) async { + return encodePng(decodeWebP(data)!); +} diff --git a/lib/platform/to_png_none.dart b/lib/platform/to_png_none.dart index 6685024..b1663da 100644 --- a/lib/platform/to_png_none.dart +++ b/lib/platform/to_png_none.dart @@ -3,3 +3,7 @@ import 'dart:typed_data'; Future jpgToPng(Uint8List data) async { throw UnimplementedError(); } + +Future webpToPng(Uint8List data) async { + throw UnimplementedError(); +} diff --git a/lib/utils/clipboard.dart b/lib/utils/clipboard.dart index b6b99ac..27e6049 100644 --- a/lib/utils/clipboard.dart +++ b/lib/utils/clipboard.dart @@ -8,7 +8,8 @@ import '../utils.dart'; enum ImageFmt { jpg, png, - gif; + gif, + webp; String toMimeType() { switch (this) { @@ -18,6 +19,8 @@ enum ImageFmt { return "image/png"; case ImageFmt.gif: return "image/gif"; + case ImageFmt.webp: + return "image/webp"; } } @@ -26,6 +29,8 @@ enum ImageFmt { switch (mime) { case "image/jpeg": return ImageFmt.jpg; + case "image/webp": + return ImageFmt.webp; case "image/png": return ImageFmt.png; case "image/gif": @@ -46,11 +51,17 @@ Future copyImageToClipboard(Uint8List data, ImageFmt fmt) async { ? Formats.jpeg(data) : fmt == ImageFmt.gif ? Formats.gif(data) - : Formats.png(data)); + : fmt == ImageFmt.png + ? Formats.png(data) + : Formats.webp(data)); } else { item.add(fmt == ImageFmt.gif ? Formats.gif(data) - : Formats.png(fmt == ImageFmt.jpg ? await jpgToPng(data) : data)); + : Formats.png(fmt == ImageFmt.jpg + ? await jpgToPng(data) + : fmt == ImageFmt.webp + ? await webpToPng(data) + : data)); } await SystemClipboard.instance!.write([item]); }