Не могу установить палитру в растровом изображении - PullRequest
22 голосов
/ 12 апреля 2011

Я пишу декодер 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 и сохранил их в палитре []. оттуда я использовал это, чтобы установить записи в палитре растрового изображения. Как мне установить цвета?

Ответы [ 2 ]

31 голосов
/ 16 мая 2011

Меня это тоже смутило.Кажется, bitmap.Palette возвращает клон палитры растрового изображения.После того, как вы изменили свою копию, вам нужно сбросить палитру растрового изображения, используя 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

3 голосов
/ 30 июня 2018

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

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

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

  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 поможет избежать путаницы.

...