0

I am trying to create copies of an original image that is of lower quality than the original. And everything works with jpeg.

When working with bmp though - with the lowest quality I can set: 0. The low quality mp is much larger than the original.

This is the sizes when saved to disk:

jpg: 2248x3264 lowqualityImageq0: 129 KB original: 4.86 MB

bmp: 2248x3264 lowqualityImageq0: 30.4 MB original: 37.6KB

The jpg is read from a real photo while the bmp is created in memory:

    var bitmap = new Bitmap(2448, 3264);
    for(int x = 0; x < bitmap.Width; x ++)
    {
        for(int y = 0; y < bitmap.Height ; y ++)
        {
            bitmap.SetPixel(x, y, Color.Red);
        }
    }
    bitmap.Save("./myimg.bmp");
    var low = bitmap.LowQualityImages(2)[0]; // creating one img with quality 0 and one with 50 - picking 0. see details below
    low.Save("./myimgq0.bmp");

Where LowQualityImages return an array where each item is created like this:

// https://stackoverflow.com/questions/4161873/reduce-image-size-c-sharp
static Bitmap LowQualityImage(Bitmap image, int quality, string encoderInfo = "image/bmp")
{
    /*
    var img = new Bitmap(image); // can't use clone ?
    // var img = (Bitmap)image.Clone();
    */
    var img = Copy(image);
    if (quality < 0 || quality > 100)
        throw new ArgumentOutOfRangeException("quality must be between 0 and 100.");

    // Encoder parameter for image quality 
    EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
    ImageCodecInfo codec = GetEncoderInfo(encoderInfo);
    EncoderParameters encoderParams = new EncoderParameters(1);
    encoderParams.Param[0] = qualityParam;
    var memoryStream = new MemoryStream();
    img.Save(memoryStream, codec, encoderParams); https://stackoverflow.com/questions/22235156/reducing-jpeg-image-quality-without-saving
    var lowQualityImage = (Bitmap)Image.FromStream(memoryStream);
    // memoryStream.Close(); causing error and does not seem to have to be called: https://stackoverflow.com/questions/4274590/memorystream-close-or-memorystream-dispose
    return lowQualityImage;

}
static ImageCodecInfo GetEncoderInfo(string mimeType)
{
    // Get image codecs for all image formats 
    ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

    // Find the correct image codec 
    for (int i = 0; i < codecs.Length; i++)
        if (codecs[i].MimeType == mimeType)
            return codecs[i];

    return null;
}

static Bitmap Copy(this Bitmap bitmap)
{
    var copy = new Bitmap(bitmap.Width, bitmap.Height);
    for(int x = 0; x < bitmap.Width; x ++)
    {
        for(int y = 0; y < bitmap.Height; y ++)
        {
            copy.SetPixel(x, y, bitmap.GetPixel(x, y));
        }
    }
    return copy;
}

When running with jpeg images read from disk - the only thing I change is the encoderInfo parameter to "image/jpeg".


Why does the "lowQualityImage" (with quality 0) becomes larger than the original in the case of bmp?

lolelo
  • 698
  • 6
  • 18
  • because noise in original jpeg is bigger than uncompressed original ... and this noise is bad for compression – Selvin Sep 19 '19 at 09:26
  • @TaW No not really. How is the quality level I set related? Additionally when making a bmp with only 1 pixel the low quality copy is smaller. – lolelo Sep 19 '19 at 09:36
  • wait, are you asking why bmp is bigger than jpeg? (Bitmap.Save("..bmp") saves file in bmp format which obviosuly is uncompressed) Bitmap with given size(HxW) will always have the same size – Selvin Sep 19 '19 at 09:41
  • @Selvin No. Why attempting to reduce bmp quality results in larger size than original. Just included jpeg to compare and make sure by code works – lolelo Sep 19 '19 at 09:56
  • 3
    *Why does the "lowQualityImage" (with quality 0) becomes larger than the original in the case of bmp?* the answer is: **because bmp is uncompressed** – Selvin Sep 19 '19 at 10:00
  • 1
    @lolelo you can test it by giving it different quality values from 0 to 100, the result will always be the same, 30.4MB – Innat3 Sep 19 '19 at 10:01
  • @Innat3 Yes just tested it's always the same. Setting quality to 50 also gives 30.4MB. I did not realize compression and image quality more or less is the same thing? – lolelo Sep 19 '19 at 10:03
  • The low quality copies still ends up larger with `"image/jpeg"` encoding - when original is created in memory. – lolelo Sep 19 '19 at 10:40
  • Seems like "noise" has to be present in order lower the image quality. I found what I was originally looking for here: https://stackoverflow.com/questions/23781364/generating-a-random-jpg-image-from-console-application – lolelo Sep 19 '19 at 15:26

0 Answers0