/ src / modules / launcher / Wox.Infrastructure / Image / ImageHashGenerator.cs
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  }