Как я могу преобразовать файл изображения gif с разрядностью 24 до разрядности 8?

#c# #winforms

Вопрос:

Попробовал это

 var test = System.IO.Directory.GetFiles(@"D:Downloaded ImagesNew folder",
                                     "*.gif", SearchOption.AllDirectories).OrderBy(x => x).ToArray();

            for (int i = 0; i < test.Length; i  )
            {
                Bitmap orig = new Bitmap(test[i]);
                Bitmap clone = new Bitmap(orig.Width, orig.Height,
                    System.Drawing.Imaging.PixelFormat.Format8bppIndexed);

                using (Graphics gr = Graphics.FromImage(clone))
                {
                    gr.DrawImage(orig, new Rectangle(0, 0, clone.Width, clone.Height));
                }
            }
 

Если я изменю эту строку на 24, она будет работать нормально, но изображения уже имеют разрядность 24

 System.Drawing.Imaging.PixelFormat.Format24bppRgb
 

Когда я изменю строку на 8

 System.Drawing.Imaging.PixelFormat.Format8bppIndexed
 

Я получаю исключение
На линии

 using (Graphics gr = Graphics.FromImage(clone))
 

Система.Исключение: «Графический объект не может быть создан из изображения, имеющего формат индексированных пикселей».

Опция Format8bppRgb отсутствует.

Ответ №1:

Format8bppRgb Выбора нет, потому что 8-битные изображения либо в оттенках серого без цвета, либо в цвете с палитрой и, следовательно, всегда индексируются.

Если ваша цель состоит в том, чтобы сделать идентичную копию исходного 8-битного изображения, вы можете использовать следующий Clone() метод:

 System.Drawing.Bitmap orig = new System.Drawing.Bitmap(GifFile);
System.Drawing.Bitmap clone = orig.Clone(new System.Drawing.Rectangle(0, 0, orig.Width, orig.Height), System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
 

Однако, если ваша цель состоит в том, чтобы использовать графику для рисования других объектов на растровом изображении, вы можете преобразовать 8-битное изображение в 24-битное, нарисовать на нем, а затем преобразовать его обратно в 8-битное. В документации Microsoft здесь объясняется, что графика.FromImage не работает, если «изображение имеет формат индексированных пикселей», например 8-разрядное.

Преобразование в 24-битное довольно просто, но преобразование обратно в 8-битное может быть сложным, потому что вам нужно будет создать подходящую палитру и подобрать к ней цвета, чтобы не потерять слишком много исходных цветов или не изменить внешний вид изображения.

Если вы хотите использовать Graphics рисование без перехода с 8-разрядной версии, вы можете использовать профессиональный SDK для обработки изображений, такой как LEADTOOLS (раскрытие информации: я работаю на его поставщика). Вот код, который это делает:

 System.Drawing.Bitmap orig = new System.Drawing.Bitmap(GifFile);
Leadtools.RasterImage LEADClone = Leadtools.Drawing.RasterImageConverter.ConvertFromImage(orig, Leadtools.Drawing.ConvertFromImageOptions.None);
Leadtools.Drawing.RasterImageGdiPlusGraphicsContainer container = new Leadtools.Drawing.RasterImageGdiPlusGraphicsContainer(LEADClone);
container.Graphics.DrawImage(orig, new System.Drawing.Rectangle(0, 0, orig.Width, orig.Height));
 

SDK также содержит класс ColorResolutionCommand, который может преобразовываться в 8 бит (или любые биты на пиксель) и при необходимости создавать оптимизированные палитры.

Если вы хотите попробовать LEADTOOLS, вы можете получить бесплатную оценку здесь