сохранить JPG с меньшей битовой глубиной (например, от 24 до 16) (C #) - PullRequest
2 голосов
/ 29 октября 2010

Мне нужно конвертировать 24- и 32-битные JPEG-файлы и PNG-файлы на более низкую битовую глубину (16).Я нашел некоторый код для этого, но получающиеся изображения сохраняют битовую глубину исходного файла, хотя там размер файла меньше.

Image img = Image.FromFile(filePathOriginal);
Bitmap bmp = ConvertTo16bpp(img);
EncoderParameters parameters = new EncoderParameters();
parameters.Param[0] = new EncoderParameter(Encoder.ColorDepth, 16);
bmp.Save(filePathNew, jpgCodec, parameters);
bmp.Dispose();
img.Dispose();

...

private static Bitmap ConvertTo16bpp(Image img) {
    var bmp = new Bitmap(img.Width, img.Height, System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
    using (var gr = Graphics.FromImage(bmp))
    {
         gr.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height));
    }

    return bmp;
}

Есть идеи, что не так?

Спасибо, Фрэнк

Ответы [ 3 ]

3 голосов
/ 29 октября 2010

JPEG - это трехцветный формат.Обычно оно имеет 8 бит на цвет, но может иметь 12 или 16. Поэтому 24 = 3x8 бит цвета вполне разумно, но 16 или 32 просто невозможно.Это просто не делится на три.3x16 = 48 было бы возможно, но это более высокая глубина цвета.JPEG предназначен для фотографий, и не имеет смысла поддерживать более низкую битовую глубину, чем 3x8.Там нет никакой пользы в этом.

Теперь, что является 16-битным изображением в вашем коде?Это неточное приближение в памяти оригинала, использующее только 65535 цветов.Когда вы сохраните это обратно, вы получите 24-битный JPEG.Видимо ваш кодировщик JPEG не знает, как создать 48-битный JPEG.Даже если бы это было так, это было бы бесполезной тратой, так как образ в памяти все равно имеет только 65536 цветов.

Подводя итог: задача не в том, что идет не так.Там нет такого понятия, как 65536 цветных JPEG.

2 голосов
/ 20 июля 2018

JPEG - это трехцветный формат, который не позволяет сохранять как 16-битную глубину, но формат bmp позволяет. Я столкнулся с той же проблемой, и я решил ее, как показано ниже. Надеюсь, это поможет вам.

bmp.Save("test.jpeg", ImageFormat.Bmp);
2 голосов
/ 26 августа 2014

Этот вопрос немного устарел, но я добавлю его всем, кто ищет в будущем.

Если это 32-битный файл, то, скорее всего, он находится в цветовом пространстве CMYK.Это обычно используется для печати, но достаточно редко, что многие инструменты, которые используют RGB и отображают на экранах, а не для печати, не могут с этим справиться.

Вы можете преобразовать его в RGB, используя imagemagic:

convert imageInCMYK.jpg -colorspace RGB imageInRGB.jpg
...