-1

Thing I need to do is resize Image where ImageFormat is PNG.

Now I do this:

 public static byte[] ResizeImage(Image image, int width, int height)
    {
        byte[] result = new byte[65000];
        var destRect = new Rectangle(0, 0, width, height);
        var destImage = new Bitmap(width, height);

        destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);

        using (var graphics = Graphics.FromImage(destImage))
        {
            graphics.CompositingMode = CompositingMode.SourceCopy;
            graphics.CompositingQuality = CompositingQuality.HighQuality;
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

            using (var wrapMode = new ImageAttributes())
            {
                wrapMode.SetWrapMode(WrapMode.TileFlipXY);
                graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
            }
        }
        using (MemoryStream stream = new MemoryStream())
        {
            destImage.Save(stream, ImageFormat.Png);
            result = stream.ToArray();

            return result;
        }
    }

The thing is at the "final stage" I need this image in byte array. This resizing method doesn't work well, because it makes this image "heavier".

Normally I use this method to convert image to PNG:

   public byte[] imageToByteArray(Image imageIn) {
        MemoryStream ms = new MemoryStream();
        imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Png);

        return ms.ToArray();
    }

But the final "weight"(after imageTobyteArray) doesn't satisfy me, so I want to resize it to make it "lighter"(Resize method).

But in the final result my Resize method makes it like twice heavier, any ideas?

@for example after I take screenshot of my desktop(1366x768) and I use imageTobyteArray it takes 60 000 bytes, then I resize it(for example 1200x768) and it takes like 150 000 bytes in byteArray. Shouldn't be it less than 60 000 after resize? Correct me if my thinking is wrong

KKKk
  • 93
  • 2
  • 15
  • I think you might have an error further upstream. A snapshot of a 1366 x 768 portion of my screen results in a 140k jpg; 132k png byte array. A decent quality image of that size doesnt seem possible in < 65k. Some random 100x100 avatars I have handy are 18k! – Ňɏssa Pøngjǣrdenlarp Dec 19 '15 at 00:56
  • Resizing interpolates the colors, which is likely to increase the number of colors in the image, thereby reducing its compressibilitiy. If you can resample instead of resizing, using a nearest-neighbor method, the new image should be about as compressible as the original. If your library offers a nearest-neighbor InterpolationMode, try that. – Glenn Randers-Pehrson Dec 20 '15 at 16:04

1 Answers1

2

You seem to be confusing image complexity with image size.

Take a look at the actual pixels in your original 1366x768 image. Notice how clean the image looks? How the edges of things are nice and sharp, the color count is fairly low, etc? That's because that images is (relatively) simple.

Now resize that image using any method you like and look at the pixels again. Edges have become fuzzy, blurred by the resize process. Color counts are well up, etc. In short, image complexity has increased.

Smooth gradients in the image compress really badly, as do large color counts and so on. That's why your smaller but much more complex image compresses poorly with PNG. If you want small file sizes for complex images, use JPEG and suffer the compression artifacts.

Corey
  • 15,524
  • 2
  • 35
  • 68