2020-08-05 14:06:42 -07:00
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System ;
2020-06-01 12:35:37 -07:00
using System.IO ;
2020-10-29 17:52:35 -07:00
using System.Reflection ;
2020-06-01 12:35:37 -07:00
using System.Security.Cryptography ;
using System.Windows.Media ;
using System.Windows.Media.Imaging ;
2024-09-16 16:09:43 -04:00
2020-10-29 17:52:35 -07:00
using Wox.Plugin.Logger ;
2020-06-01 12:35:37 -07:00
namespace Wox.Infrastructure.Image
{
public class ImageHashGenerator : IImageHashGenerator
{
2020-10-29 17:52:35 -07:00
[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")]
2024-03-14 18:05:43 +03:00
public string GetHashFromImage ( ImageSource image , string filePath )
2020-06-01 12:35:37 -07:00
{
2022-03-14 16:44:17 +01:00
if ( ! ( image is BitmapSource bitmapSource ) )
2020-06-01 12:35:37 -07:00
{
return null ;
}
try
{
using ( var outStream = new MemoryStream ( ) )
{
2024-03-14 18:05:43 +03:00
// Dynamically selecting the encoder based on the file extension to preserve the original image format characteristics as much as possible.
BitmapEncoder encoder = GetEncoderByFileExtension ( filePath ) ;
2022-03-14 16:44:17 +01:00
var bitmapFrame = BitmapFrame . Create ( bitmapSource ) ;
2020-06-01 12:35:37 -07:00
bitmapFrame . Freeze ( ) ;
2024-03-14 18:05:43 +03:00
encoder . Frames . Add ( bitmapFrame ) ;
encoder . Save ( outStream ) ;
2020-06-01 12:35:37 -07:00
var byteArray = outStream . GetBuffer ( ) ;
2023-03-16 15:51:31 +01:00
return Convert . ToBase64String ( SHA1 . HashData ( byteArray ) ) ;
2020-06-01 12:35:37 -07:00
}
}
2020-10-29 17:52:35 -07:00
catch ( System . Exception e )
2020-06-01 12:35:37 -07:00
{
2020-10-29 17:52:35 -07:00
Log . Exception ( $"Failed to get hash from image" , e , MethodBase . GetCurrentMethod ( ) . DeclaringType ) ;
2020-06-01 12:35:37 -07:00
return null ;
}
}
2024-03-14 18:05:43 +03:00
public static BitmapEncoder GetEncoderByFileExtension ( string filePath )
{
string fileExtension = Path . GetExtension ( filePath ) . ToLowerInvariant ( ) ;
switch ( fileExtension )
{
case ".png" :
return new PngBitmapEncoder ( ) ;
case ".jpg" :
case ".jpeg" :
return new JpegBitmapEncoder ( ) ;
case ".bmp" :
return new BmpBitmapEncoder ( ) ;
default :
// Default to PNG if the format is unknown or unsupported because PNG is a lossless compression format
return new PngBitmapEncoder ( ) ;
}
}
2020-06-01 12:35:37 -07:00
}
2020-08-05 14:06:42 -07:00
}