Низкокачественная растровая копия исходного растрового изображения становится больше после снижения качества - PullRequest
0 голосов
/ 19 сентября 2019

Я пытаюсь создать копии исходного изображения более низкого качества, чем оригинал.И все работает с jpeg.

При работе с bmp, хотя - с самым низким качеством , я могу установить: 0.Мп низкого качества намного больше оригинала.

Размеры при сохранении на диск:

jpg: 2248x3264 lowqualityImageq0: 129 КБ оригинал: 4,86 ​​МБ

bmp: 2248x3264 lowqualityImageq0: 30,4 МБ оригинал: 37,6 КБ

JPG считывается из реальной фотографии, в то время как bmp создается в памяти :

    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");

Где LowQualityImages возвращает массив, в котором каждый элемент создается следующим образом:

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

При работе с изображениями в формате JPEG чтение с диска - единственное, что я изменяю, это encoderInfo параметр в "image/jpeg".


Почему «lowQualityImage» (с качеством 0) становится больше, чем оригинал в случае bmp?

...