Loss of transparency in System.Drawing.Image when using ImageResizer to resize

For my current WPF application, I need to zoom out System.Drawing.Image(objects that I download from PNG files (some with a transparent background). I tried several approaches for resizing images, and they all worked fine in terms of a smaller image afterwards. But, unfortunately, they all make images free of their transparency.

My last attempt was to use ImageResizer's external library to do the job, as I expected it to handle this problem easily, but I still have the same problem: The original image is displayed with a transparent background; The modified image with a black background is displayed.

Here is my code for using the ImageResizer library:

ImageResizer.Instructions inst = new ImageResizer.Instructions("width=" + newWidth.ToString() + ";height=" + newHeight.ToString() + ";format=png;mode=max");
ImageResizer.ImageJob job = new ImageResizer.ImageJob(originalImage, typeof(System.Drawing.Bitmap), inst);
job.Build();
return job.Result as System.Drawing.Image;

These are my other two approaches, which also basically provide the same result (Image resized: yet; Transparency saved: Nope):

return originalImage.GetThumbnailImage(newWidth, newHeight, null, IntPtr.Zero); // Transparency gets lost

return new System.Drawing.Bitmap(originalImage, new System.Drawing.Size(newWidth, newHeight));  // Transparency gets lost

Any ideas on what I should do to maintain transparency when resizing?

Hi

Ralph

+4
source share
2 answers

Even if you use WPF, you work with objects System.Drawing.Image, so you can do this:

    public static Bitmap ResizeImage(Image imgToResize, int newHeight)
    {
        int sourceWidth = imgToResize.Width;
        int sourceHeight = imgToResize.Height;

        float nPercentH = ((float)newHeight / (float)sourceHeight);

        int destWidth = Math.Max((int)Math.Round(sourceWidth * nPercentH), 1); // Just in case;
        int destHeight = newHeight;

        Bitmap b = new Bitmap(destWidth, destHeight);
        using (Graphics g = Graphics.FromImage((Image)b))
        {
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
            g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
        }

        return b;
    }

After that, be sure to save it using the PNG encoder:

    public static System.Drawing.Imaging.ImageCodecInfo GetEncoder(System.Drawing.Imaging.ImageFormat format)
    {
        ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
        foreach (ImageCodecInfo codec in codecs)
        {
            if (codec.FormatID == format.Guid)
            {
                return codec;
            }
        }
        return null;
    }

and then

    codec = GetEncoder(ImageFormat.Png);
    newBitmap.Save(newFile, codec, null);

(Note: I am using the standard .Net class libraries, not a third-party library, I hope that OK.)

Update

, WPF, WPF ?

public static class BitmapHelper
{
    public static void SaveToPng(this BitmapSource bitmap, string fileName)
    {
        var encoder = new PngBitmapEncoder();
        SaveUsingEncoder(bitmap, fileName, encoder);
    }

    public static void SaveUsingEncoder(this BitmapSource bitmap, string fileName, BitmapEncoder encoder)
    {
        BitmapFrame frame = BitmapFrame.Create(bitmap);
        encoder.Frames.Add(frame);

        using (var stream = File.Create(fileName))
        {
            encoder.Save(stream);
        }
    }

    public static void ImageLoadResizeAndSave(string inFile, string outFile, int newPixelHeight)
    {
        BitmapImage image = new BitmapImage();
        image.BeginInit();
        image.UriSource = new Uri(inFile);
        image.EndInit();

        var newImage = BitmapHelper.ResizeImageToHeight(image, newPixelHeight);

        BitmapHelper.SaveToPng(newImage, outFile);
    }

    /// <summary>
    /// Resize the image to have the selected height, keeping the width proportionate.
    /// </summary>
    /// <param name="imgToResize"></param>
    /// <param name="newHeight"></param>
    /// <returns></returns>
    public static BitmapSource ResizeImageToHeight(BitmapSource imgToResize, int newPixelHeight)
    {
        double sourceWidth = imgToResize.PixelWidth;
        double sourceHeight = imgToResize.PixelHeight;

        var nPercentH = ((double)newPixelHeight / sourceHeight);

        double destWidth = Math.Max((int)Math.Round(sourceWidth * nPercentH), 1); // Just in case;
        double destHeight = newPixelHeight;

        var bitmap = new TransformedBitmap(imgToResize, new ScaleTransform(destWidth / imgToResize.PixelWidth, destHeight / imgToResize.PixelHeight));

        return bitmap;
    }
}

, , WPF?

+1

ImageResizer .

( ) , , ImageResizer. , typeof(System.Drawing.Bitmap), .

var i = new Instructions(){ Width = newWidth,Height = newHeight, OutputFormat= OutputFormat.Png, Mode= FitMode.Max};
new ImageJob(originalImage, "output.png", i).Build();

ImageResizer , .


, , . , , . , , , 32- -.

+2

All Articles