views:

49

answers:

2

I am working on improving one of my Facebook apps by allowing the user to upload an image and apply a styled border, or frame to it (i.e. clouds, stars, sky etc). The user chould also be able to save the image, with the border after it has been applied. This explains a little better what I need:

http://zbrowntechnology.info/ImgDisp/imgdisp.php

If you have any other questions or need more details, please let me know.. I'll edit this post.

A: 

Client-side solution by using css3:

checkout the css3 property border-image (dosen't meet the requirement of saving the img with the border)

Server-side solution by merging 2 different images:

<?php


$imgFile = 'img.jpg';
$brdFile = 'brd.jpg';
$img = addBorder($imgFile,$brdFile);
outputImage($img);

function addBorder($imgFile,$brdFile)
{
    $img=imagecreatefromjpeg($imgFile);
    $brd=imagecreatefromjpeg($brdFile);

    $imgSize = getimagesize($imgFile);
    $brdSize = getimagesize($brdFile);


    //NOTE: the border img MUST be bigger then the src img
    $dst_x = ceil(($brdSize[0] - $imgSize[0])/2);
    $dst_y = ceil(($brdSize[1] - $imgSize[1])/2);


    imagecopymerge  ( $brd, $img, $dst_x,  $dst_y,  0, 0, $imgSize[0], $imgSize[1] ,100  );

    return $brd;
}   

function outputImage($img)
{
    header('Content-type: image/png');  
    imagepng($img);
}

?>
Cesar
I think the OP is looking for a PHP script that will combine the border with the original into one image so users can save the entire image as one file.
willell
maybe yes or maybe no... there are advantages and disadvantages in both the solutions. By using the css, you can resolve the problem in 1 line and you don't need to change anything on the server side, however some old browser may not support the css3. by using the GD for sure it's cross-browser but you need to elaborate every image and you increase the elaboration on the server-side
Cesar
+2  A: 

Use imagecopy(). The example on that page is done using the transparency option with imagecopymerge() but I don't think you need that.

Using imagecopy() you'll specify the X/Y coordinates to use for positioning:

imagecopy( $borderimage, $topimage, 20, 20, 0, 0, $width, $height);

Where $width and $height will be the entire width and height of the top image. You'll want to replace 20 and 20 with the measurement for how much of the border image will be showing around the borders. You will probably have to resize the top image to the exact dimensions you want, or else it might overlap the border a little too far to the right or bottom. (see imagecopyresampled())

Edit:

Here's a rough way to do the whole process (assuming chosenborder.png is the border they chose, and uploadedimage.png is the image they uploaded. If it's a different image type you'll use the corresponding function).

$borderx = 20; // The width of our border
$border = imagecreatefrompng("chosenborder.png");
$topimage = imagecreatefrompng("uploadedimage.png");
$bordersize = getimagesize($border);
$topimagesize = getimagesize($topimage);

/* The new dimensions of topimage. $borderx*2 means we account for
   the border on both left and right, top and bottom. */
$newx = $bordersize[0] - ($borderx*2);
$newy = $bordersize[1] - ($borderx*2);
imagecopyresampled( $topimage_scaled, $topimage, 0, 0, 0, 0,
              $newx, $newy, $topimagesize[0], $topimagesize[1]);

/* Merge the images */
imagecopy( $border, $topimage_scaled, $borderx, $borderx,
              0, 0, $width, $height);
/* Output the image */
imagepng($border, "newimage.png");
/* Free up the memory occupied by the image resources */
imagedestroy($border);
imagedestroy($topimage);

After the user uploads their image, find chosenborder.png and uploadedimage.png, run the above script, then display newimage.png to the user and you're good to go. Just make sure you call imagedestroy() on the temporary image resources or they'll eat up memory.

If you don't want to keep the generated image on your server, you can omit the second argument to imagepng() which will make it send the image information directly as an image to the browser, in which case you'll want to write the correct image HTTP headers.

willell