Ничто не поможет вам с GDI. Похоже, что индексированные изображения — слишком отсталая технология, чтобы Microsoft могла о ней заботиться. Все, что вы можете сделать, это читать и записывать индексированные файлы изображений.
Обычно квантизация цветов в изображении выполняется в два этапа:
1) Найдите наилучшую палитру для изображения (квантизация цвета)
2) Сопоставьте исходные солоры с найденной палитрой (картографирование цвета).
Насколько я понимаю, у вас уже есть палитра в базе данных, а это значит, что самое сложное за вас уже сделано. Все, что вам нужно сделать, это сопоставить 24-битные цвета с предоставленными цветами палитры. Если у вас нет исходной палитры, вам придется вычислить ее самостоятельно, используя алгоритм квантования: наиболее известны Octree или Median Cut. Median Cut дает лучшие результаты, но медленнее и сложнее в реализации и точной настройке.
Самый простой алгоритм для сопоставления цветов в вашем случае — вычислить расстояние от вашего исходного цвета до всех цветов палитры и выбрать ближайший.
float ColorDistanceSquared(Color c1, Color c2)
{
float deltaR = c2.R - c1.R;
float deltaG = c2.G - c1.G;
float deltaB = c2.B - c1.B;
return deltaR*deltaR + deltaG*deltaG + deltaB*deltaB;
}
Вы также можете обдумать каналы, чтобы синий имел меньший вес, не переборщите с этим, иначе это даст ужасные результаты, в частности, 30/59/11 вообще не будет работать:
float ColorDistanceSquared(Color c1, Color c2)
{
float deltaR = (c2.R - c1.R) * 3;
float deltaG = (c2.G - c1.G) * 3;
float deltaB = (c2.B - c1.B) * 2;
return deltaR*deltaR + deltaG*deltaG + deltaB*deltaB;
}
Вызовите эту штуку для всех исходных цветов и цветов палитры и найдите Мин. Если вы кешируете свои результаты по мере продвижения по карте, это будет очень быстро.
Кроме того, исходный цвет редко будет соответствовать цвету палитры достаточно, чтобы не создавать полосы и однотонные области и не терять детали на вашем изображении. Чтобы избежать этого, вы можете использовать дизеринг. Самый простой алгоритм, дающий наилучшие результаты, — диффузионное сглаживание ошибок.
После того, как вы сопоставили свои цвета, вам придется вручную заблокировать растровое изображение и записать туда индексы, поскольку .Net не позволит вам писать в индексированное изображение.
person
Coincoin
schedule
09.11.2009