Looks like I cannot post my solution here with links: I just replaced GDI+ with not free library "MESCIUS Document Solutions for Imaging".
WPF Bitmapimage resizing is messed up in windows 11 24H2
There is a WPF ImageControl that takes local file as source.
Before saving it on server, I am trying to resize the image so that I dont store huge files. I am also trying to reduce the image quality if image size exceeds 12 kb even after resizing.
But in few images, all of a sudden only "a part of image" is getting saved. I cannot reproduce it on my PC but PC that is showing this behaviors have recently being updated to windows 11 24H2.
I wonder if any of the above code is impacted with windows 11 24H2.
private const int MaxHeight = 240;
private const int MaxWidth = 200;
private const long CompressionQuality = 75L;
private const int CompressOnSizeExceeding = 12288;
public static byte[] ProcessBitMapSourceToByteArrayWithCompression(BitmapSource bitmapSource,
long imageQuality = CompressionQuality,
ImageFormat imageFormat = null)
{
if (bitmapSource == null) return null;
var bytes = CompressImageDimensions(bitmapSource);
if (bytes == null) return null;
if (bytes.Length < CompressOnSizeExceeding)
return bytes;
if (imageFormat == null)
imageFormat = ImageFormat.Jpeg;
return CompressImageQuality(bytes, imageQuality, imageFormat);
}
private static byte[] CompressImageDimensions(BitmapSource bitmapSource,
int maxHeight = MaxHeight, int newWidth = MaxWidth)
{
try
{
if (bitmapSource == null)
throw new ArgumentNullException("bitmapSource");
if (bitmapSource.PixelWidth < newWidth)
{
newWidth = bitmapSource.PixelWidth;
}
int newHeight = bitmapSource.PixelHeight * newWidth / bitmapSource.PixelWidth;
if (newHeight > maxHeight)
{
newWidth = bitmapSource.PixelWidth * maxHeight / bitmapSource.PixelHeight;
newHeight = maxHeight;
}
using (var memStream = new MemoryStream())
{
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(ResizeImageToBitmapFrame(bitmapSource, newWidth, newHeight, 0));
encoder.Save(memStream);
return memStream.ToArray();
}
}
catch (Exception ce)
{
Utility.Log(ce);
}
return null;
}
private static BitmapFrame ResizeImageToBitmapFrame(ImageSource source, int width, int height, int margin)
{
try
{
var rect = new Rect(margin, margin, width - margin * 2, height - margin * 2);
var group = new DrawingGroup();
RenderOptions.SetBitmapScalingMode(group, BitmapScalingMode.Fant);
group.Children.Add(new ImageDrawing(source, rect));
var drawingVisual = new DrawingVisual();
using (var drawingContext = drawingVisual.RenderOpen())
drawingContext.DrawDrawing(group);
var resizedImage = new RenderTargetBitmap(
width, height, // Resized dimensions
96, 96, // Default DPI values
PixelFormats.Default); // Default pixel format
resizedImage.Render(drawingVisual);
return BitmapFrame.Create(resizedImage);
}
catch (Exception ce)
{
FileLogger.WriteLog(ce);
throw;
}
}
private static byte[] CompressImageQuality(byte[] bytes, long imageQuality, ImageFormat imageFormat)
{
if (bytes == null || bytes.Length == 0) return null;
try
{
var ic = new ImageConverter();
var sourceImage = (Image) ic.ConvertFrom(bytes);
var imageQualitysParameter = new EncoderParameter(
Encoder.Quality, imageQuality);
var codecParameter = new EncoderParameters(1);
codecParameter.Param[0] = imageQualitysParameter;
//Find and choose JPEG codec
ImageCodecInfo jpegCodec = GetEncoder(imageFormat);
//Save compressed image
using (var memoryStream = new MemoryStream())
{
sourceImage?.Save(memoryStream, jpegCodec, codecParameter);
return memoryStream.ToArray();
}
}
catch (Exception ce)
{
Utility.Log(ce);
}
return null;
}
private static ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
return codecs.FirstOrDefault(codec => codec.FormatID == format.Guid);
}
4 answers
Sort by: Most helpful
-
Deleted
This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.
Comments have been turned off. Learn more
-
-
Hongrui Yu-MSFT 2,865 Reputation points Microsoft Vendor
2024-10-24T05:24:02.3766667+00:00 Hi,@rakesh kumar.
This is a known issue in the WIC jpeg encoder (which GDI+ uses). The Windows team is aware, and it has been fixed. It should show up in servicing soon (next month or two most likely).
Related Documents: https://github.com/dotnet/winforms/issues/12339
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
-
Deleted
This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.
Comments have been turned off. Learn more