Невозможно установить палитру в растровое изображение
Я писал 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 и сохранил их в палитре []. оттуда я использовал это, чтобы установить записи в палитре растрового изображения. Как установить цвета?
Ответы
Ответ 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
после цикла не было.
Чтобы решить эту проблему, вы должны сделать следующее:
- Назначьте новый псевдоним
bmp.Palette
, присвоив его переменной, - Измените его с помощью нового псевдонима (это предотвратит перезагрузку),
- И верните его в
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, будет большой помощью в предотвращении путаницы.