Hi.
I got a problem.
I want to make a screenshot of my opengl game. the game runs in 24bit mode. so i get my pixel data in 24bit. now i want to save the image to an 8bit pcx file. how do i convert this 24bit image to 8bit? is there a way that automatically creates an adjusted palette and converts the pixel data for that palette?
Posted on 2002-04-04 06:15:27 by darester
I don't know for sure if it would work, but you could create a DIB from it, and then call GetDIBits specifying some 8-bit format.
However if your goal is to make screenshot, wouldn't it be much easier to output in a format that supports 24-bit? Creating bitmaps is quite simple..

Thomas
Posted on 2002-04-04 06:45:46 by Thomas
well AFAIK this process is called 'debabelizing' or 'debabelization' , maybe run a search on it...
But what I do know is that 24-bit 3d-rendered scenes look like crap in 8-bit color, and doing an accurate conversion is really a tough job
Posted on 2002-04-04 13:05:10 by AntiPasta
A quick and dirty way would be to scan the original picture and build your 256 color palette containing the most used colors from the original picture. Afterwards, replace each pixel with its closest match in the palette.

It would look better with dithering, but since you're saving it as a PCX, dithering would bloat the hell out of it.
Posted on 2002-04-05 13:25:22 by iblis

A quick and dirty way would be to scan the original picture and build your 256 color palette containing the most used colors from the original picture. Afterwards, replace each pixel with its closest match in the palette.

It would look better with dithering, but since you're saving it as a PCX, dithering would bloat the hell out of it.
I wrote such a routine (24bit -> 8bit including Floyd Steinberg dithering) many years ago.. it's 68000 assembly, dunno if the original poster is interested? Shoudln't be too hard to convert. Pliz tell me if I've to extrapolate it from my Amiga. :)
Posted on 2002-04-05 15:50:06 by Maverick
Hi,

This 24bit to 16bit convert procedure. May be help you.

Have nice days, :)




; void DIBconvert_24_to_16(
; void *dest, [ESP+ 4]
; ulong dest_pitch, [ESP+ 8]
; void *src, [ESP+12]
; ulong src_pitch, [ESP+16]
; ulong width, [ESP+20]
; ulong height); [ESP+24]

_DIBconvert_24_to_16:
push ebp
push edi
push esi
push edx
push ecx
push ebx
push eax

mov esi,[esp+12+28]
mov edi,[esp+4+28]

mov ebp,[esp+20+28]
lea eax,[ebp+ebp]
lea ebx,[ebp+eax]
sub [esp+8+28],eax
sub [esp+16+28],ebx

mov edx,[esp+24+28]
DIBconvert2416@y:
mov ebp,[esp+20+28]
push ebp
push edx
shr ebp,1
jz DIBconvert2416@x2
DIBconvert2416@x:
mov eax,[esi+3] ;u
add esi,6 ;v

mov ebx,eax ;u
mov ecx,eax ;v
shr ebx,3 ;u
and ecx,0000f800h ;v
shr eax,9 ;u
and ebx,0000001fh ;v
shr ecx,6 ;u
and eax,00007c00h ;v
or ebx,ecx ;u
add edi,4 ;v
or ebx,eax ;u

mov ecx,[esi-6] ;v
mov edx,ebx ;u
mov eax,ecx ;v

shl edx,16 ;u
mov ebx,ecx ;v
shr ebx,3 ;u
and ecx,0000f800h ;v
shr eax,9 ;u
and ebx,0000001fh ;v
shr ecx,6 ;u
and eax,00007c00h ;v
or eax,ecx ;u
or edx,ebx ;v
or edx,eax ;u
dec ebp ;v
mov [edi-4],edx ;u
jne DIBconvert2416@x ;v
DIBconvert2416@x2:
pop edx
pop ebp
and ebp,1
jz DIBconvert2416@x3
mov eax,[esi]
add esi,3

mov ebx,eax
mov ecx,eax
shr ebx,3
and ecx,0000f800h
shr eax,9
and ebx,0000001fh
shr ecx,6
and eax,00007c00h
or ebx,ecx
or ebx,eax
mov [edi+0],bl
mov [edi+1],bh
add edi,2
DIBconvert2416@x3:

add esi,[esp+16+28]
add edi,[esp+ 8+28]

dec edx
jne DIBconvert2416@y

pop eax
pop ebx
pop ecx
pop edx
pop esi
pop edi
pop ebp

ret

Posted on 2002-04-05 17:34:52 by CYDONIA
Its also called "quantization" on the net. There is a quantiz.c proggy that demonstrates that as i recall.

We played with this concept many times at HE because in 8 bit all alpha blending and FX are much faster and easyer to do but doh... we couldnt find a way to make it work for many many images that are quite diffrent.

I can be done pretty well for a simgle image IMHO i have seen pictures with 32 colors (after quantization from 24 bits) and even less that look quite good but you have to find the best colors to suit your image and finding/choosing them is no easy task...

Basically the samllest distance from original colors and the samller overall error also are the conditions...
Posted on 2002-04-06 01:00:12 by BogdanOntanu
I miss the days of pixel artists that would create magical art in 32 colors or less! 24bit color is cheating and rarely fully utilized, imo. With everything moving so fast, all those colors aren't processed by the brain.
Posted on 2002-04-06 01:28:29 by bitRAKE
Hi,

This another convert proc (8 to 24 )

have nice days,



; void DIBconvert_8_to_24(
; void *dest, [ESP+ 4]
; ulong dest_pitch, [ESP+ 8]
; void *src, [ESP+12]
; ulong src_pitch, [ESP+16]
; ulong width, [ESP+20]
; ulong height, [ESP+24]
; ulong *palette); [ESP+28]

_DIBconvert_8_to_24:
push ebp
push edi
push esi
push edx
push ecx
push ebx
push eax

mov esi,[esp+12+28]
mov edi,[esp+4+28]

mov eax,[esp+20+28]
mov ebx,eax
lea ebx,[ebx+eax*2]
mov edx,[esp+28+28]
mov ecx,[esp+24+28]

sub [esp+16+28],eax
sub [esp+8+28],ebx

DIBconvert824@y:
mov ebp,[esp+20+28]
xor eax,eax
DIBconvert824@x:
mov al,[esi]
inc esi
mov ebx,[eax*4+edx]
mov [edi],ebx
add edi,3
dec ebp
jne DIBconvert824@x

add esi,[esp+16+28]
add edi,[esp+8+28]

dec ecx
jne DIBconvert824@y

pop eax
pop ebx
pop ecx
pop edx
pop esi
pop edi
pop ebp

ret
Posted on 2002-04-07 19:38:52 by CYDONIA
The two most successful ways of converting 24->8 bit are probably the octree method, and the neural net method.
If you think of r, g and b as 3 dimensions, and each colour as a position in this 3d space, then the octree method should make sense.
You insert each colour into the octree, and it will adaptively subdivide, then you tweak the tree so that you get ~256 cells, and for each cell you take the average of all colours in that cell. And there you have your reasonably well-optimized palette.

The neural net method is rather fuzzy. You basically train a neural net to accept 256 colours, and you feed them all colours in the image repeatedly. Eventually the nodes in the net will converge to the 256 best-matching colours, and you have your palette.

Octree is fast and always works, neural net is very slow, and it is hard to prove that it will always get the proper palette.. But in practice it generally does, and it does a slightly better job than octree. But with both methods, you get remarkable results if you convert eg a picture to 256 colour. It will still look very good in general. And there is no dithering involved, so no noisy images. You may get banding though, so you may actually want to insert some noise for some images (so back to dithering :)).
Posted on 2004-06-11 17:32:31 by Scali
any reason why it needs to be PCX?
Posted on 2004-06-11 18:02:29 by klumsy
hm, got any examples of apps that use neural nets for color reduction?
Posted on 2004-06-11 18:18:59 by f0dder
http://members.ozemail.com.au/~dekker/NEUQUANT.HTML

I don't know of any actual software using the algo, as it is pretty slow, and barely better than octree (which is very fast).
Octree is quite common and can be found in Paint Shop Pro for example.
Posted on 2004-06-11 18:32:14 by Scali