Подтвердить что ты не робот

Невозможно установить палитру в растровое изображение

Я писал PCX-декодер и пока что сам PCX файл отлично разбирается, но я не могу понять, как установить палитру растрового изображения.

Я создал растровое изображение так:

Bitmap bmp = new Bitmap(width,
                        height,
                        stride2,
                        System.Drawing.Imaging.PixelFormat.Format8bppIndexed,
                        pixels);

Но я не могу настроить палитру, используя следующий метод:

for (int i = 0; i < 256; i += 3)
{
    Color b = new Color();
    b = Color.FromArgb(palette[i], palette[i + 1], palette[i + 2]);
    bmp.Palette.Entries.SetValue(b, i);
}

В этом примере я прочитал каждый байт в палитре файла pcx и сохранил их в палитре []. оттуда я использовал это, чтобы установить записи в палитре растрового изображения. Как установить цвета?

4b9b3361

Ответ 1

Это тоже меня смутило. Кажется, bitmap.Palette возвращает клон палитры растровых изображений. После того как вы изменили свою копию, вам нужно reset растровое изображение с помощью bitmap.Palette = palette, например

ColorPalette palette = bitmap.Palette;
Color entries = palette.Entries;
....
entries[i] = new Color(...);
....
bitmap.Palette = palette; // The crucial statement

См. http://www.charlespetzold.com/pwcs/PaletteChange.html

Ответ 2

Согласно Microsoft Reference Source, свойство Palette класса Image в.net, внутренне использует GDI+ плоские API для обработки палитр. GdipGetImagePalette используется для инициализации объекта ColorPalette в методе get метод GdipSetImagePalette используемый для записи ColorPalette объекта ColorPalette обратно на устройство, - это метод set.

Каждый раз в вашем цикле for строка bmp.Palette.Entries.SetValue(b, i); заставляет изображение вызывать GdipGetImagePalette и данные bmp.Palette инициализированы, и поэтому вы можете видеть, что никаких изменений в bmp.Palette после цикла не было.

Чтобы решить эту проблему, вы должны сделать следующее:

  1. Назначьте новый псевдоним bmp.Palette, присвоив его переменной,
  2. Измените его с помощью нового псевдонима (это предотвратит перезагрузку),
  3. И верните его в bmp.Palette.

Код:

var newAliasForPalette = bmp.Palette; // Palette loaded from graphic device
for (int i = 0; i < 256; i++)
{
    newAliasForPalette.Entries[i] = myColor[i];
}
bmp.Palette = newAliasForPalette; // Palette data wrote back to the graphic device

На мой взгляд, замена определения Palette как свойства с помощью GetPalette() и SetPalette() Microsoft, будет большой помощью в предотвращении путаницы.