C # Почему Bitmap.Save игнорирует PixelFormat Bitmap? - PullRequest
4 голосов
/ 13 января 2011

Мне нужно обработать и сохранить изображения в их исходном bpp (1 - для BnW, 8 - для серого, 24 - для цвета). После обработки у меня всегда 24bpp (из-за обработки с помощью Aforge.Net). Я передаю оригинальный bpp функции сохранения и использую следующий код для сохранения:

private static Bitmap changePixelFormat(Bitmap input, PixelFormat format)
    {
        Bitmap retval = new Bitmap(input.Width, input.Height, format);
        retval.SetResolution(input.HorizontalResolution, input.VerticalResolution);
        Graphics g = Graphics.FromImage(retval);
        g.DrawImage(input, 0, 0);
        g.Dispose();
        return retval;
    }

Когда я прохожу:

PixelFormat.Format8bppIndexed

Я получаю исключение: «Графический объект не может создать изображение в формате индексированных пикселей» в строке:

Graphics g = Graphics.FromImage(retval);

Я пробовал следующий код:

Bitmap s = new Bitmap("gray.jpg");
        Bitmap NewPicture = s.Clone(new Rectangle(0, 0, s.Width, s.Height),                   PixelFormat.Format8bppIndexed);

После этого «NewImage» имеет PixelFormat 8bppIndexed, но когда я сохраняю NewImage:

NewPicture.Save("hello.jpg", ImageFormat.Jpeg);

hello.jpg имеет 24bpp.

Мне нужно сохранить bpp и формат изображения исходного изображения.

Почему Bitmap.Save игнорирует PixelFormat для Bitmap?

=============================================== ========

Спасибо, ребята, я нашел решение: http://freeimage.sourceforge.net/license.html

С помощью этой бесплатной библиотеки можно сохранять изображения (особенно JPEG) в 8-битном оттенке серого.

Ответы [ 4 ]

5 голосов
/ 13 января 2011

Я почти уверен, что формат изображений JPEG не поддерживает индексированные изображения.Таким образом, даже если вы создали изображение с указанием PixelFormat.Format8bppIndexed, GDI + преобразует его в другой формат, когда вы пытаетесь сохранить его в формате JPEG.В этом случае вы уже определили, что это 24 bpp.

Вместо этого вам нужно сохранить изображение в формате BMP или GIF.Например:

NewPicture.Save("hello.jpg", ImageFormat.Bmp);

См. Таблицу форматов файлов изображений, поддерживающих индексированный цвет здесь, в Википедии .

4 голосов
/ 13 января 2011

Вот код, который преобразует растровое изображение в растровое изображение 1bpp / 8bpp. 1bpp / 8bpp в C #.

В вашем методе changePixelFormat вы можете проверить, к какому формату fixel он должен быть конвертирован, затем, если это 1bpp или 8 bpp, используйте код по ссылке, а для всех других форматов используйте ваш код.

Graphics.FromImage документация имеет замечания:

Если изображение имеет индексированный пиксель формат, этот метод выдает исключение с сообщением "A Графический объект не может быть создан из изображение с индексированным пикселем формат. "Индексированные форматы пикселей показано в следующем списке.

Format1bppIndexed

Format4bppIndexed

Format8bppIndexed

НОВАЯ ЧАСТЬ:

Вот что я нашел после короткого поиска в Google:

8bpp изображения в оттенках серого и 8bpp jpg не поддерживаются в версии gdiplus 1,0. В Windows 7 появилась новая версия gdiplus, которая поддерживает оттенки серого. изображения и более расширенная поддержка кодеков.

8bpp индексированные изображения JPEG поддерживаются с WIC API от Microsoft.

Вы можете попробовать это самостоятельно, загрузив WIC Explorer от Microsoft сайт загрузки.

GDI + 8-битная ошибка загрузки / сохранения

Стандартный JPEG поддерживает только 24-битное изображение.

0 голосов
/ 06 мая 2013

Используйте класс Graphics для неиндексированного изображения. Использовать Bitmap.LockBits и Bitmap.UnlockBits при обработке проиндексированных изображений

0 голосов
/ 23 апреля 2011

Если вы ищете истинное 8-битное растровое изображение в градациях серого, тогда я сделал подробный пост StackOverflow об этом . Он будет работать на любой операционной системе (Windows / Mac / Linux), а не только на Windows 7. Надеюсь, это поможет.

...