Skip to content

Commit 286eb92

Browse files
committed
Add support for webp
closes #73
1 parent f28b388 commit 286eb92

File tree

2 files changed

+40
-10
lines changed

2 files changed

+40
-10
lines changed

PasteIntoFile/ClipboardContents.cs

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using PasteIntoFile.Properties;
1717
using PdfSharp.Drawing;
1818
using PdfSharp.Pdf;
19+
using SkiaSharp;
1920

2021
namespace PasteIntoFile {
2122

@@ -171,7 +172,7 @@ public abstract class ImageLikeContent : BaseContent {
171172

172173

173174
public class ImageContent : ImageLikeContent {
174-
public static readonly string[] EXTENSIONS = { "png", "bmp", "gif", "jpg", "pdf", "tif", "ico" };
175+
public static readonly string[] EXTENSIONS = { "png", "webp", "jpg", "bmp", "gif", "pdf", "tif", "ico" };
175176
public ImageContent(Image image) {
176177
Data = image;
177178
}
@@ -181,16 +182,24 @@ public ImageContent(Image image) {
181182
public override void SaveAs(string path, string extension, bool append = false) {
182183
if (append)
183184
throw new AppendNotSupportedException();
184-
Image image = Preview(extension).Image;
185+
var image = Preview(extension).Image;
185186
if (image == null)
186187
throw new FormatException(string.Format(Resources.str_error_cliboard_format_missmatch, extension));
187188

189+
var stream = new MemoryStream();
190+
image.Save(stream, image.RawFormat);
191+
stream.Position = 0;
192+
188193
switch (NormalizeExtension(extension)) {
194+
case "webp":
195+
//SKImage.FromEncodedData(stream).Encode(SKEncodedImageFormat.Webp, 90).SaveTo(File.OpenWrite(path));
196+
var webp = SKBitmap.Decode(stream).PeekPixels().Encode(new SKWebpEncoderOptions(SKWebpEncoderCompression.Lossless, 100));
197+
using (var fs = new FileStream(path, FileMode.Create)) {
198+
webp.SaveTo(fs);
199+
return;
200+
}
189201
case "pdf":
190202
// convert image to ximage
191-
var stream = new MemoryStream();
192-
image.Save(stream, image.RawFormat);
193-
stream.Position = 0;
194203
XImage img = XImage.FromStream(stream);
195204
// create pdf document
196205
PdfDocument document = new PdfDocument();
@@ -225,8 +234,13 @@ public override PreviewHolder Preview(string extension) {
225234
extension = NormalizeExtension(extension);
226235
// Special formats with intermediate conversion types
227236
switch (extension) {
228-
case "pdf": extension = "png"; break;
229-
case "ico": return PreviewHolder.ForImage(ImageAsIcon.ToBitmap());
237+
case "pdf":
238+
case "webp":
239+
// Use png as intermediate format
240+
extension = "png";
241+
break;
242+
case "ico":
243+
return PreviewHolder.ForImage(ImageAsIcon.ToBitmap());
230244
}
231245
// Find suitable codec and convert image
232246
foreach (var encoder in ImageCodecInfo.GetImageEncoders()) {
@@ -277,7 +291,7 @@ public Icon ImageAsIcon {
277291
/// Like ImageContent, but only for formats which support alpha channel
278292
/// </summary>
279293
public class TransparentImageContent : ImageContent {
280-
public static new readonly string[] EXTENSIONS = { "png", "gif", "pdf", "tif", "ico" };
294+
public static new readonly string[] EXTENSIONS = { "png", "webp", "gif", "pdf", "tif", "ico" };
281295
public TransparentImageContent(Image image) : base(image) { }
282296
public override string[] Extensions => EXTENSIONS; // Note: gif has only alpha 100% or 0%
283297
}
@@ -286,7 +300,7 @@ public TransparentImageContent(Image image) : base(image) { }
286300
/// Like ImageContent, but only for formats which support animated frames
287301
/// </summary>
288302
public class AnimatedImageContent : ImageContent {
289-
public static new readonly string[] EXTENSIONS = { "gif" };
303+
public static new readonly string[] EXTENSIONS = { "gif" }; // TODO: in principle "webp" can also support animated frames
290304
public AnimatedImageContent(Image image) : base(image) { }
291305
public override string[] Extensions => EXTENSIONS;
292306
}
@@ -1003,7 +1017,22 @@ public static ClipboardContents FromFile(string path) {
10031017
} else {
10041018
container.Contents.Add(new ImageContent(img));
10051019
}
1006-
} catch { /* it's not */ }
1020+
} catch {
1021+
// Try again with Skia (to support webp)
1022+
try {
1023+
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read)) {
1024+
var img = SKBitmap.Decode(fs);
1025+
using (var stream = img.PeekPixels().Encode(SKPngEncoderOptions.Default).AsStream()) {
1026+
if (img.AlphaType == SKAlphaType.Opaque) {
1027+
container.Contents.Add(new ImageContent(Image.FromStream(stream)));
1028+
} else {
1029+
// TODO: FIXME: transparency seems to get lost during conversion
1030+
container.Contents.Add(new TransparentImageContent(Image.FromStream(stream)));
1031+
}
1032+
}
1033+
}
1034+
} catch { /* it's not */ }
1035+
}
10071036

10081037

10091038
// if it's text like (check for absence of zero byte)

PasteIntoFile/PasteIntoFile.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.2" />
5454
<PackageReference Include="PDFsharp" Version="1.50.5147" />
5555
<PackageReference Include="SharpClipboard" Version="3.5.2" />
56+
<PackageReference Include="SkiaSharp" Version="3.116.1" />
5657
</ItemGroup>
5758
<ItemGroup Condition="'$(Flavor)'=='Portable'">
5859
<PackageReference Include="PortableSettingsProvider" Version="0.2.4" />

0 commit comments

Comments
 (0)