Page 1 of 1

imagefill and imagefilltoborder not working for me

Posted: Fri Nov 16, 2007 12:20 pm
by bozlax
feyd | Please use

Code: Select all

,

Code: Select all

and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]


So, here's the deal: I'm trying to fill an irregular shape with a color on the fly using php and gd.  Pretty simple, no?

The starting image looks like this: [url=http://bozlax.is-a-geek.net/apache2-default/laketest.jpg]laketest.jpg[/url]

First stab at code is thusly:

Code: Select all

#!/usr/bin/php

<?php
        $im = imagecreatefromjpeg("laketest.jpg");
        $blue = imagecolorallocate($im, 0, 0, 255);
        imagefill($im, 168, 140, $blue);
        imagejpeg($im, "laketest2.jpg");
        imagedestroy($im);
?>
The result of that looks like this: laketest2.jpg

Second stab at code:

Code: Select all

#!/usr/bin/php

<?php
        $im = imagecreatefromjpeg("laketest.jpg");
        // $border = imagecolorat($im, 258, 198); // should be black line
        $border = imagecolorallocate($im, 0, 0, 0); // force to black
        $blue = imagecolorallocate($im, 0, 0, 255);
        imagefilltoborder($im, 168, 140, $border, $blue);
        imagejpeg($im, "laketest3.jpg");
        imagedestroy($im);
?>
The result looks like this: laketest3.jpg

(It didn't matter whether I forced the border to black or picked the color from the image.)

Any suggestions? I know the border is solid because when I open the original in a program like Gimp and do a fill it works just fine.

TIA


feyd | Please use

Code: Select all

,

Code: Select all

and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]

Image links dead

Posted: Sat Nov 17, 2007 2:26 pm
by bozlax
Sorry, guys, I just realized that one of my kids took the images down last night. They're live, again.

Posted: Sat Nov 17, 2007 4:09 pm
by onion2k
There's actually two separate problems here, but they're both related to the fact you're using a JPEG file. When you save an image as a JPEG it destroys the exact colour information of the image and replaces it with an approximation that compresses very well uses a couple of compression algorithms (LWZ and some transformations if you're interested). What this means in practise is that what was a big white blob in your original image is now a big white blob in the centre with nearly white areas around the outside of it.

The reason the imagefill() isn't working is because of the way imagefill() works. It replaces a single color in an area where there's a block of pixels that color .. eg if you pick the pixel at 168,140 GD replaces it, then it checks the pixel to the left and replaces it if it's the same, then checks the one to the left of that, and above it, and below it ... until it's run out of identical pixels in that area. Because you've used a JPEG file the pixels just inside the black border are only nearly white so they're not replaced.

The second problem is with imagefilltoborder(). Again, because you're using a JPEG file the black border isn't really black anymore .. it's lots of different colors all very similar to black. That means there's no solid border all of one color, so the blue fill color bleeds out to the edge of the image.

The solution is very simple - don't use a JPEG. Save your laketest image as a PNG or a GIF then open it using imagecreatefrompng() or imagecreatefromgif(). imagecreatefromgif() is only available on fairly recent PHP GD2 versions though.

If this is an operation that your website is going to be doing very frequently I'd recommend converting the image to a native GD format ... write a separate script to open it using imagecreatefrompng() then save it using imagegd2(), then in your live script open it using imagecreatefromgd2(). The GD2 format makes somewhat bigger files but they're a lot quicker to open in PHP.

Thanks

Posted: Sun Nov 18, 2007 10:11 am
by bozlax
Nice one, onion. Saving the original image as PNG solved the problem.

Now, is there any way to cleanly go from JPEG to PNG, i.e. to "correct" the JPEG image? The live image is much more complex than the example presented (as you might imagine), and I'd rather not re-do the whole thing if possible.

Never mind

Posted: Sun Nov 18, 2007 10:25 am
by bozlax
Even my Sunday-morning-addled brain was able to figure out to open the original JPEG in Gimp, flood-fill the supposedly white areas with white and re-save the image as PNG.

Thanks again, onion.