Dealing with image bits and XOR/AND maps

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Dealing with image bits and XOR/AND maps

Post by superdezign »

I'm not sure how many people here are experienced in this, but I'll give it a shot. I've got my class that gets all of the information for *.ico files which is the headers, the icon entries, the bitmap info (headers and palettes), and then the XOR and AND maps. From there, I would think I'm doing this correctly, but I'm not.

I'm working with an 8x8 1-bit icon to start off with (2-color palette) and can't seem to get it to display correctly. Here's my generation code:

Code: Select all

$image				= imagecreatetruecolor($width, $height);

// Create bitmaps
for($i = 0; $i < $length / 2; $i++, $bitslength += 
{
	$xorbits	.= str_pad(decbin(ord($maps[$i])), 8, '0', STR_PAD_LEFT);
}
for(; $i < $length; $i++)
{
	$andbits	.= str_pad(decbin(ord($maps[$i])), 8, '0', STR_PAD_LEFT);
}

// Set pixel colors
for($y = $height - 1, $offset = 0; $y >= 0 && $offset < $bitslength; $y--)
{
	for($x = 0; $x < $width && $offset < $bitslength; $x++, $offset++)
	{
		if($andbits[$offset] == 0)
		{
			imagesetpixel($image, $x, $y, imagecolorexact(255, 255, 255));
		}
	}
}

header('Content-type: image/png');
imagepng($image);
This should give me a basic B&W of the icon, but it ends up just looking like a cluttered mess. Every resource I've found online thus far validates everything I've done up to this point, but once it comes to the display of the data, they generalize and summarize. It's so frustrating. :cry:

If anyone has any experience in XOR/AND maps or bit manipulation, please offer some advice.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Are you sure the iteration is running properly?
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Post by Luke »

I wish I did... that stuff is all like magic to me. If you know of good resources to pick this type of stuff up, please let me know. :)
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

Can't help you directly, sorry. However, I can say that whenever I'm faced with a particularly complex algorithm it helps me to have some debug function that visualizes the internal state of the algorithm, so I can figure out where things are going wrong.
User avatar
stereofrog
Forum Contributor
Posts: 386
Joined: Mon Dec 04, 2006 6:10 am

Post by stereofrog »

Binary arithmetic operators (& << and others) are useful when dealing with bitmap data.
I don't know how exactly ICO files are built up, but maybe this small illustration helps you further.

Code: Select all

$map=""
."\x18" //00011000
."\x18" //00011000
."\x18" //00011000
."\xff" //11111111
."\xff" //11111111
."\x18" //00011000
."\x18" //00011000
."\x18" //00011000
;


$w = 8;
$h = 8;

$image = imagecreatetruecolor($w, $h); 
$c = imagecolorexact($image, 255, 0, 255);

for($y = 0; $y < $h; $y++)
	for($x = 0; $x < $w; $x++)
		if(ord($map[$y]) & (1 << $x))
			imagesetpixel($image, $x, $y, $c);

header('Content-type: image/png');
imagepng($image);
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post by superdezign »

That's an interesting suggestion, but the bitwise operators could easily be replaced by the simple if statement that I am using.

I've been reading through more and more material, and read somewhere about "padding scanlines." It was a term I'd heard years back before I even knew what I was doing with C++, and was stumped by the concept. Now, it makes a bit more sense. Basically, the binary data is set up in scanlines (lines of pixels) that ALWAYS equal a number of DWORD (the Microsoft C++ definition of long unsigned integer) units, which is 4 bytes each. Any unused portions of the DWORD units are padded with zeros. I didn't know that.

So, my error was in the first part of the code where I create the XOR map and the AND map. After putting the padding into consideration, I've altered the loop to ignore the padding, and I could get all icon images to work EXCEPT for 1-bit icons. The 1-bit icons don't seem to have any padding at all, which is invalid because they *should* have 31 bits of padding. The error was caused simply by the fact that the number '1' was being used in the equation that determined the length of it's data in the file, and skewed the results drastically. I fixed this with a conditional for 1-bit graphics to ignore the conversion back into bytes because they were too small, and then I had to alter the offset by 8 (though I've yet to figure out why that happens :?:)

Now, the only thing I'm having trouble with is alpha transparency in 32-bit files. There's bound to be some sort of equation. I tried "255 - $alphaValue," but that only partially works. If anyone knows of an equation to do this, I'd love to be notified. :D

Until then, I'll keep searching. I'm so excited that it's almost done. ^_^
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post by superdezign »

I did it!

I read more into the GD library functions that allocate colors and it turns out that the alpha values much be between 0 and 127. However, after echoing out all of the alpha values in the images, they ranged from 0 to 255. So, I divided the alpha value by 255 and get a ratio and then multiplied 127 by that ratio. It gave me the complete opposite, so I inverted it by subtracting it from 127 and viola!

This is going to be a chore to write a tutorial for... these people better click on ads. :P
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

superdezign wrote:I did it!

I read more into the GD library functions that allocate colors and it turns out that the alpha values much be between 0 and 127. However, after echoing out all of the alpha values in the images, they ranged from 0 to 255. So, I divided the alpha value by 255 and get a ratio and then multiplied 127 by that ratio. It gave me the complete opposite, so I inverted it by subtracting it from 127 and viola!

This is going to be a chore to write a tutorial for... these people better click on ads. :P
Dont' advertise on here then, most everyone uses ad blocking software...I've polled the community before and paid close attention to other topics similar in nature. :P
User avatar
stereofrog
Forum Contributor
Posts: 386
Joined: Mon Dec 04, 2006 6:10 am

Post by stereofrog »

superdezign wrote:That's an interesting suggestion, but the bitwise operators could easily be replaced by the simple if statement that I am using.
Glad to hear it was helpful. ;)
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post by superdezign »

stereofrog wrote:
superdezign wrote:That's an interesting suggestion, but the bitwise operators could easily be replaced by the simple if statement that I am using.
Glad to hear it was helpful. ;)
Hehe. I remember using bitwise operators in C++ for file manipulation.. Not fun. Needless to say, I've never gotten this far before. I'm so proud of myself. ^_^
Post Reply