...

View Full Version : PHP Image Manipulating?



bluephoenix
02-26-2003, 01:47 AM
Okay, here's a doozy of a question for y'all...

I'm working on the company website, and since we're a financial institution we have a listing of all the ATMs our members can use without surcharge. The previous webdesigner just threw the information up and it looked like crap. The first thing I did was to organize the information in an XML file, similar to this:



<atm_data>
<area name="Syracuse">
<atm location="Syracuse Mobil" address="123 Main Street" />
<atm location="Public Safety Building" address="511 State Street />
</area>
</atm_data>


I've then created PHP scripts to parse the data and create a nicely formatted table for the results. I've even set up a mechanism where the area names are read and displayed as a drop box, allowing the viewer to see the locations of ATMs for a specific area.

I'm pelase (and so is my supervisor!), but I want to put it "over the top" by displaying a map of the area with the ATM locations starred. But that's where I'm stuck.

I could generate twenty or so maps (one for each area), and each map would have the ATM locations already highlighted. But, if we had an ATM to the network or loose one, then I have to go back, edit the XML data file accordingly, and then modify the map image. Now granted that only having to modify two items as opposed to all 4 or 5 doesn't seem that bad, but I'd like the maps to update themselves, too.

I've checked into SVG but our current server doesn't send them out with the correct MIME-type. And I can't control that because it's hosted by an outside company (I'm working on getting our own server and hosting it inhouse; I think it'll be cheaper and more secure, but that's still at least a year away by the time I clear through proposals and budget setbacks).

So how can I dynamicly generate, modify, or overlay an image over an existing image before serving it to the viewer using PHP?

To see my work so far, http://www.acmgfcu.org/temp/findatm.php It doesn't format the results "all pretty and stuff," I just ran out of time and I'll get to that tomorrow afternoon. But the scripts are functioning properly, and that's the important thing!

Thanks in advance,

-Tim

Íkii
02-26-2003, 11:39 AM
First things first, what version of GD does your build support?

Second note: dynamically generating an image at every page view is resource hungry and unneccessary when your image only needs changing when you add/delete an ATM. I'd suggest something whereby your admin interface creates and saves the image.

3rd: If you are running GD2+, I've a lil class that handles overlaying easily...
$a->merge('overlay.png',123,234,75,'FF0000')
image - xpos - ypos - opacity - transparent colour
though I wasn't really thinking of releasing it for commercial use, I could be persuaded. Would also be possible just to pull out the function merge and configure it for GD1.6.4 - 2, if needed.

You could also - if you decide to only construct through an admin interface, imagemap the graphic and alt-text or dhtml reference the hotspots.

Anyway, answer the above questions first if you could.

-------------------
subnote:
temp/php/page.php - you might want to assure you have write permissions to the xml file AND maybe combine all your fputs() into one call by constructing a string and then just appending that the once.

Darknight
02-27-2003, 08:54 PM
I'm glad you started this thread. I have been trying to do the same kinda thing.

I was able to get this to work!
make sure 1.jpg and 2.jpg are in the same folder.

there is an example in the "imageCopyMerge" user comments.
<?php
//$sourcefile = Filename of the picture into that $insertfile will be inserted.
//$insertfile = Filename of the picture that is to be inserted into $sourcefile.
//$targetfile = Filename of the modified picture.
//$transition = Intensity of the transition (in percent)
//$pos = Position where $insertfile will be inserted in $sourcefile
// 0 = middle
// 1 = top left
// 2 = top right
// 3 = bottom right
// 4 = bottom left
// 5 = top middle
// 6 = middle right
// 7 = bottom middle
// 8 = middle left
//
//
function mergePix($sourcefile,$insertfile, $targetfile, $pos=0,$transition=50)
{

//Get the resource id┤s of the pictures
$insertfile_id = imageCreateFromJPEG($insertfile);
$sourcefile_id = imageCreateFromJPEG($sourcefile);
//Get the sizes of both pix
$sourcefile_width=imageSX($sourcefile_id);
$sourcefile_height=imageSY($sourcefile_id);
$insertfile_width=imageSX($insertfile_id);
$insertfile_height=imageSY($insertfile_id);
//middle
if( $pos == 0 )
{
$dest_x = ( $sourcefile_width / 2 ) - ( $insertfile_width / 2 );
$dest_y = ( $sourcefile_height / 2 ) - ( $insertfile_height / 2 );
}
//top left
if( $pos == 1 )
{
$dest_x = 0;
$dest_y = 0;
}
//top right
if( $pos == 2 )
{
$dest_x = $sourcefile_width - $insertfile_width;
$dest_y = 0;
}
//bottom right
if( $pos == 3 )
{
$dest_x = $sourcefile_width - $insertfile_width;
$dest_y = $sourcefile_height - $insertfile_height;
}
//bottom left
if( $pos == 4 )
{
$dest_x = 0;
$dest_y = $sourcefile_height - $insertfile_height;
}
//top middle
if( $pos == 5 )
{
$dest_x = ( ( $sourcefile_width - $insertfile_width ) / 2 );
$dest_y = 0;
}
//middle right
if( $pos == 6 )
{
$dest_x = $sourcefile_width - $insertfile_width;
$dest_y = ( $sourcefile_height / 2 ) - ( $insertfile_height / 2 );
}

//bottom middle
if( $pos == 7 )
{
$dest_x = ( ( $sourcefile_width - $insertfile_width ) / 2 );
$dest_y = $sourcefile_height - $insertfile_height;
}
//middle left
if( $pos == 8 )
{
$dest_x = 0;
$dest_y = ( $sourcefile_height / 2 ) - ( $insertfile_height / 2 );
}

//The main thing : merge the two pix
imageCopyMerge($sourcefile_id, $insertfile_id,$dest_x,$dest_y,0,0,$insertfile_width,$insertfile_height,$transition);
//Create a jpeg out of the modified picture
imagejpeg ($sourcefile_id,"$targetfile");

}


mergePix("1.jpg","2.jpg","3.jpg", 0,50);
?>

<img src="3.jpg" border="0" alt="alt text">

Íkii
02-28-2003, 12:54 PM
I approached the overlay/merge from a different direction as I wanted to define one colour as transparent.

Basically, I just iterated through the merge image a pixel at a time, tested whether the colour was what I set as transparent and, if not, I merged the pixel to a relative point on the background image


function merge($merge_img="", $x_left=0, $y_top=0, $merge_opacity=70, $trans_colour="FF0000")
{
$this->mi = ($merge_img == "") ? $this->b : $merge_img;
$this->xx = ($x_left < 0) ? $this->q+$x_left : $x_left;
$this->yy = ($y_top < 0) ? $this->r+$y_top : $y_top;
$this->mo = $merge_opacity;
$this->tc = $trans_colour;
$this->tr = $this->hex2rgb(substr($this->tc,0,2));
$this->tg = $this->hex2rgb(substr($this->tc,2,2));
$this->tb = $this->hex2rgb(substr($this->tc,4,2));
$this->md = getimagesize($this->mi);
$this->mw = $this->md[0];
$this->mh = $this->md[1];
$this->mm = ($this->md[2] < 4) ? ($this->md[2] < 3) ? ($this->md[2] < 2) ? imagecreatefromgif($this->mi) :
imagecreatefromjpeg($this->mi) :
imagecreatefrompng($this->mi) : Null;
for($this->ypo = 0; $this->ypo < $this->mh; $this->ypo++)
{
for($this->xpo = 0; $this->xpo < $this->mw; $this->xpo++)
{
$this->indx_ref = imagecolorat($this->mm, $this->xpo, $this->ypo);
$this->indx_rgb = imagecolorsforindex($this->mm, $this->indx_ref);
if($this->indx_rgb['red'] !== $this->tr && $this->indx_rgb['green'] !== $this->tg && $this->indx_rgb['blue'] !== $this->tb)
{
imagecopymerge($this->t, $this->mm, $this->xx+$this->xpo, $this->yy+$this->ypo, $this->xpo, $this->ypo, 1, 1, $this->mo);
}
}
}
imagedestroy($this->mm);
}

$this->t would be the background image.
If any open-source [non commercial] scripters want to test the entire class, just give me shout.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum