PDA

View Full Version : How to draw 1bpp images



NicolasF
June 26th, 2009, 05:43 AM
Hi, I want to draw monochrome images (1bpp) but I'm having problems with the algorithm, Does anyone have an example so that I can use?

Thanks!

mbbrutman
June 26th, 2009, 05:56 AM
It's pretty simple. 0 means no color, 1 means color. You pack eight pixels to a byte.

The bigger question is, what file format are you reading? If it is compressed in any way you need to decompress first. That determines the first step in the algorithm.


Mike

NicolasF
June 26th, 2009, 07:01 AM
Hi, the image has been decompressed. I'm having problems with unpacking the bits from the byte.

mbbrutman
June 26th, 2009, 07:51 AM
What language are you using? Can you post the code?

NicolasF
June 26th, 2009, 11:02 AM
I'm using C.this is the code I have so far


for(uiRows = 0; uiRows < uiHeight; uiRows++)
{
for(uiColumns = 0; uiColumns < uiWidth; uiColumns++)
{
if(ucFlag){
ucAux = pImage->ucpPicture[uiCursor];
// ucAux = ucAux << 4 | ucAux >> 4;
ucFlag = 0;
}

if(ucPixel1 < 8){
if(ucAux & ucMask)
ucColor = 0xFF;
else
ucColor = 0x00;
ucPixel1++;
ucAux = ucAux >> 1;
}
else{
uiCursor++;
ucPixel1 = 0;
ucFlag = 1;
}

ucfpWhere[((uiRows+y)<<8)+ ((uiRows+y)<<6)+uiColumns+x] = ucColor;
}
}

cosam
June 26th, 2009, 11:19 AM
In which order are the bits packed into each byte? Could it be that you simply have every byte "reversed"?

mbbrutman
June 26th, 2009, 11:32 AM
I would add some comments and either add some printfs to debug, or learn to use a debugger. The debugger can be a tremendous time saver.

kiyotewolf
July 11th, 2009, 03:48 AM
Okie tay.

Well, the best way is to do something relative to this.

Generate a lookup table of possible color combinations.

Grayscale: 0,1,2,3,4

Assign them color values.

Colorz(0).red=&h00
Colorz(0).grn=&h00
Colorz(0).blu=&h00
Colorz(1).red=&h07
Colorz(1).grn=&h07
Colorz(1).blu=&h07

That's generic and needs to be tuned. You simply make a gradient from black into gray to white at various stages. As few as possible.

Write code to dither correctly based on the binary compiment of the pixel address in x and y.

Pseudocode in PLC type notation.
(Looks like an old flowchart if you look at the symbols.)
() Begin program
[] Load image
[] Generate lookup table with target colors
{} (loop function)
<> Is color within range of one of target colors (use SQR root of ..)
y[] Draw pixel
<> is final pixel color on or off in dither pattern?
y[] Draw monochrome pixel
n[] Leave pixel off
n[] cycle through colors until most approximate match is found
endof{} loop

So you see, if you make a target set of colors, a very wide gradient in as few choices as possible, then you can set the target pixels to be either on or off, but it must test against the pattern in the gradient for the designated color.

You have dots like this for off
~~
~~
(blank)

You have dots for on
XX
XX

You have dots for 25% on
X~
~~

You have dots for 50% on
X~
~X

You have dots for 75% on
XX
~X

So, if you give it target colors to match to, simply grayscale RGB colors, they will match down to the target colors, which are monochrome only bit patterns, then for each pixel you draw, (one pixel at a time), make sure it fits in either the ON or the OFF pattern of the pseudo pixel of monochrome-ness, and you will end up with a dithered, 1bpps, (not perfect mind you but it works), image of awesomeness.



Kiyote!

BTW, I work in either PLC flowchart psuedocode or fully working examples of either QBasic or FreeBasic, nothing in between. I hate half-alive stillborn examples of code you can't even run. I post either something metaphysical, or the real deal.

Mike Chambers
July 13th, 2009, 05:39 AM
looks like this has already been answered, but i'm bored so i'll answer it again... as mike brutman said, 8 pixels are packed into a byte... normally the pixel order left to right will be from the MSB to the LSB.

here's how you'd determine the 8 pixels from each byte: (in BASIC, sorry but it's simple to read anyway)


IF (thebyte AND 128) THEN x1 = 1 ELSE x1 = 0
IF (thebyte AND 64) THEN x2 = 1 ELSE x2 = 0
IF (thebyte AND 32) THEN x3 = 1 ELSE x3 = 0
IF (thebyte AND 16) THEN x4 = 1 ELSE x4 = 0
IF (thebyte AND 8) THEN x5 = 1 ELSE x5 = 0
IF (thebyte AND 4) THEN x6 = 1 ELSE x6 = 0
IF (thebyte AND 2) THEN x7 = 1 ELSE x7 = 0
IF (thebyte AND 1) THEN x8 = 1 ELSE x8 = 0