WPF Bitmapimage resizing is messed up in windows 11 24H2

rakesh kumar 0 Reputation points
2024-10-15T20:43:28.44+00:00

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;
}

public static ImageSource ResizedImageToImageSource(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 resizedImage;
    }
    catch (Exception ce)
    {
        Utility.Log(ce);
    }
    return source;
}

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);
}
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,781 questions
Windows 11
Windows 11
A Microsoft operating system designed for productivity, creativity, and ease of use.
9,746 questions
{count} votes

2 answers

Sort by: Most helpful
  1. 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

  2. Alexander Magdysyuk 5 Reputation points
    2024-10-21T20:36:12.0233333+00:00

    Looks like I cannot post my solution here with links: I just replaced GDI+ with not free library "MESCIUS Document Solutions for Imaging".

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.