ImageHashGenerator.cs
1 // Copyright (c) Microsoft Corporation 2 // The Microsoft Corporation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System; 6 using System.IO; 7 using System.Reflection; 8 using System.Security.Cryptography; 9 using System.Windows.Media; 10 using System.Windows.Media.Imaging; 11 12 using Wox.Plugin.Logger; 13 14 namespace Wox.Infrastructure.Image 15 { 16 public class ImageHashGenerator : IImageHashGenerator 17 { 18 [System.Diagnostics.CodeAnalysis.SuppressMessage("Security", "CA5350:Do Not Use Weak Cryptographic Algorithms", Justification = "Level of protection needed for the image data does not require a security guarantee")] 19 public string GetHashFromImage(ImageSource image, string filePath) 20 { 21 if (!(image is BitmapSource bitmapSource)) 22 { 23 return null; 24 } 25 26 try 27 { 28 using (var outStream = new MemoryStream()) 29 { 30 // Dynamically selecting the encoder based on the file extension to preserve the original image format characteristics as much as possible. 31 BitmapEncoder encoder = GetEncoderByFileExtension(filePath); 32 var bitmapFrame = BitmapFrame.Create(bitmapSource); 33 bitmapFrame.Freeze(); 34 encoder.Frames.Add(bitmapFrame); 35 encoder.Save(outStream); 36 var byteArray = outStream.GetBuffer(); 37 return Convert.ToBase64String(SHA1.HashData(byteArray)); 38 } 39 } 40 catch (System.Exception e) 41 { 42 Log.Exception($"Failed to get hash from image", e, MethodBase.GetCurrentMethod().DeclaringType); 43 return null; 44 } 45 } 46 47 public static BitmapEncoder GetEncoderByFileExtension(string filePath) 48 { 49 string fileExtension = Path.GetExtension(filePath).ToLowerInvariant(); 50 51 switch (fileExtension) 52 { 53 case ".png": 54 return new PngBitmapEncoder(); 55 case ".jpg": 56 case ".jpeg": 57 return new JpegBitmapEncoder(); 58 case ".bmp": 59 return new BmpBitmapEncoder(); 60 default: 61 // Default to PNG if the format is unknown or unsupported because PNG is a lossless compression format 62 return new PngBitmapEncoder(); 63 } 64 } 65 } 66 }