 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Ali Guest
|
Posted: Sun Jul 20, 2003 11:25 am Post subject: Reduce Pallete of BMP |
|
|
Hi.
How can I reduce the pallete page of bmp file,
for instance I want to reduce 16bit pallete page of bmp file to 16-color pallet page.
With Best Regards
|
|
| Back to top |
|
 |
Earl F. Glynn Guest
|
Posted: Sun Jul 20, 2003 5:20 pm Post subject: Re: Reduce Pallete of BMP |
|
|
"Joris" <PleaseReplyTo (AT) TheGroupInstead (DOT) be> wrote
| Quote: | "Ali" <gono2bed (AT) yahoo (DOT) con> wrote in message
news:3f1a7c38$1 (AT) newsgroups (DOT) borland.com...
How can I reduce the pallete page of bmp file,
for instance I want to reduce 16bit pallete page of bmp file to 16-color
pallet page.
|
If you have a true 16-bit image, you don't have any palettes. With
15-/16-bit "high" color or 24-/32-bit "true" color each pixel contains
complete color information. With 8-bit color, each pixel is an
index into a palette. You need the color palette with pf8bit images,
but not pf24bit images.
Find some of these details here for various PixelFormats:
http://homepages.borland.com/efg2lab/ImageProcessing/Scanline.htm
| Quote: | You mean 16bit direct color image to 4bit 16 color palette image?
Two techniques are relevant: quantizing and dithering.
|
And neither Windows nor Delphi help you much with these tasks.
Working with palettes in Windows adds quite a bit of complexity to your
code, especially if you're concerned with displaying paletted images on
display devices with only 256 colors. I avoid working with palettes
whenever possible and try to only work in high color true color display
modes.
You might start with the "Color Reduction, Color Quantization" links on this
page:
http://homepages.borland.com/efg2lab/Library/Delphi/Graphics/Color.htm
--
efg -- Earl F. Glynn, Overland Park, KS USA
efg's Computer Lab: http://www.efg2.com/Lab
Mirror: http://homepages.borland.com/efg2lab/Default.htm
|
|
| Back to top |
|
 |
Joris Guest
|
Posted: Sun Jul 20, 2003 10:23 pm Post subject: Re: Reduce Pallete of BMP |
|
|
"Ali" <gono2bed (AT) yahoo (DOT) con> wrote
| Quote: | How can I reduce the pallete page of bmp file,
for instance I want to reduce 16bit pallete page of bmp file to 16-color
pallet page. |
You mean 16bit direct color image to 4bit 16 color palette image?
Two techniques are relevant: quantizing and dithering. Quantizing is the art
of selecting an appropriate palette. Dithering is the art of reducing a
direct color image to a specific palette such that it looks as good as
possible to the human eye. Both techniques are extensive, and there's no
limit to the amount of effort you can spend to increase performance and
output quality. I'll try to give a general description of one way to do it.
* Quantizing *
As always (see other posts of mine), I think you should go from CIE L*a*b*
color values, since these reflect human eye color perception, as opposed to
CRT voltages reflected in a color space like RGB. But that's just my
opinion. So as to not confuse my point, I'll go from RGB in this post.
Step 1: Histogram building
Imagine a cube. That's essentially what RGB is, a cube. When you're talking
about 24bit RGB, each dimension (X, Y, Z in common mathematics, or in this
case R, G, and B) is divided up into 256 parts. That's way to much for the
quantizing algorithm I'm going to explain. First thing you need is to divide
each dimension in say 32 or 64 parts instead, and for each partial cube
(there are 32*32*32 or 64*64*64 partial cubes, so it's a rather huge array),
you need to know how many image pixels occupy a color in that particular
partial cube. So set up the array, scan through the image, and increment the
correct partial cube's pixel count for each pixel. I'll call the resulting
array the 'histogram' from this point on.
Step 2: Quantization initialization
Now set up a list, containing partial cube descriptions. To start with, the
list should have one single entry. This one single entry should describe the
complete RGB cube. I'll call a description of a partial cube in this list an
'entry', from this point on.
Step 3: Quantization loop
For each dimension of each entry in the list, you need an average value. For
instance, the starter single entry, in the R dimension, results in this
average
(0*(number of pixels with R=0 in this entry)+1*(number of pixels with R=1 in
this entry)+...)/(all pixels in this entry)
Next, you need some value that indicates how 'badly' this average describes
the complete dimension of the entry. One way to calculate this figure is
(number of pixels with R=0 in this entry)*Sqr(average-0)+(number of pixels
with R=1 in this entry)*Sqr(average-1)+...
I'll call this value the 'variation' from this point on.
Now determine wich dimension of which entry has the highest 'variation'.
This entry needs to be split up. Remove the entry, and add two new entries,
effectively splitting the entry in the given dimension. The average is the
point at which to split.
Put like this, it may sound confusing, so let's add an example. This may be
the first situation before the very first pass:
One entry, encompassing the complete RGB cube.
*Single entry*
R range: 0-255
R average: 124
R variation: 3000
G range: 0-255
G average: 30
G variation: 100
B range: 0-255
B average: 80
B variation: 4555
B variation is biggest. Meaning, after the very first pass through this
loop, things may look like this
*First entry*
R range: 0-255
R average: ...
R variation: ...
G range: 0-255
G average: ...
G variation: ...
B range: 0-80
B average: ...
B variation: ...
*Second entry*
R range: 0-255
R average: ...
R variation: ...
G range: 0-255
G average: ...
G variation: ...
B range: 81-255
B average: ...
B variation: ...
Every pass therefore results in an entry count increment of 1. Repeat the
quantization loop until you've got exactly as many entries as you want
colors in the final resulting palette.
Step 4: Final palette composition
The final resulting palette is composed of one color per list entry. Use
average values for color channel values. It's that simple. What you did,
from a higher level point of view, is simply slicing up the RGB space, such
that each slicing action was the action most needed, resulting in as many
slices as entries in the final desired palette, and subsequently selecting a
good color value for each slice.
* Dithering *
Next logical action is to transform your direct color image into a palette
color image. You could simply calculate the nearest palette entry for each
pixel, of course. But that is not ideal. A better way is to add the error
caused by round to the nearest palette entry to neighbouring pixels before
in turn rounding these to the nearest palette entry. As such, you can
compensate the error in one pixel with an opposite error in a neighbouring
pixel. The human eye does not see pixels, but sees pixel neighbourhoods.
This technique is called 'dithering'.
There are many different implementations of this dithering technique. I
personally use the Hilbert curve, a space-filling curve, to control the
order in which individual pixels get rounded and exclude artifacts. But the
Peano (from the top of my head) curve is much more common, and there are
other techniques that are much easier to use than space-filling curves. The
bottom line is always trying to minimize errors in pixel neighbourhoods by
trying to oppose individual pixel errors.
Joris
|
|
| Back to top |
|
 |
Joris Guest
|
Posted: Mon Jul 21, 2003 3:12 am Post subject: Re: Reduce Pallete of BMP |
|
|
"Earl F. Glynn" <efg2 (AT) efg2 (DOT) com> wrote
| Quote: | "Joris" <PleaseReplyTo (AT) TheGroupInstead (DOT) be> wrote in message
news:3f1a9789 (AT) newsgroups (DOT) borland.com...
Two techniques are relevant: quantizing and dithering.
And neither Windows nor Delphi help you much with these tasks.
|
Neither Windows nor Delphi is an imaging library, so I'm thinking it's
actually quite logical that they don't include such advanced imaging
techniques. Not that you said otherwise, of course.
I should have included a link to your site in my response. But then again, I
should include a link to your site in every response I ever post. It's
always an excellent starting point for whatever question anyone has.
In my earlier response, I failed to mention the use of the 'histogram'. It
is of course used in the calculation of average and 'variation' in steps 2
and 3. One other thing I should have mentioned is that the 'list of partial
box descriptions', build for the purpose of quantization, can be used to
quickly determine a 'near' palette entry in the dithering process. One can
just select the palette entry determined by the 'partial box' that includes
a direct color value. This is not always the nearest palette entry, but it
does very often at least come close, and the method is very fast. (Selecting
the truely nearest color, from a palette of eg 256 colors, comparably fast,
is possible, but is quite a headache.)
Joris
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|