I have a cool snippet of code that works well, except one thing.
The code will take an icon I want to add to an existing picture. I can position it where I want too! Which is exactly what I need to do.
However, I'm stuck on one thing, concerning the placement.
The code "starting position" (on the main image: navIcons.png) is from the Bottom Right.
I have 2 variables: $move_left = 10; & $move_up = 8;.
So, the means I can position the icon.png 10px left, and 8px up, from the bottom right corner.
I really really want to start the positioning from the Top Left of the image, so I'm really moving the icon 10px right & 8px down, from the top left position of the main image.
Can someone look at my code and see if I'm just missing something that inverts that starting position?
<?php
function attachIcon($imgname)
{
$mark = imagecreatefrompng($imgname);
imagesavealpha($mark, true);
list($icon_width, $icon_height) = getimagesize($imgname);
$img = imagecreatefrompng('images/sprites/navIcons.png');
imagesavealpha($img, true);
$move_left = 10;
$move_up = 9;
list($mainpic_width, $mainpic_height) = getimagesize('images/sprites/navIcons.png');
imagecopy($img, $mark, $mainpic_width-$icon_width-$move_left, $mainpic_height-$icon_height-$move_up, 0, 0, $icon_width, $icon_height);
imagepng($img); // display the image + positioned icon in the browser
//imagepng($img,'newnavIcon.png'); // rewrite the image with icon attached.
}
header('Content-Type: image/png');
attachIcon('icon.png');
?>
For those who are wondering why I'd even bother doing this. In a nutshell, I like to add 16x16 icons to 1 single image, while using css to display that individual icon. This does involve me downloading the image (sprite) and open photoshop, add the new icon (positioning it), and reuploading it to the server. Not a massive ordeal, but just having fun with php.
bool imagecopy ( resource $dst_im , resource $src_im , int $dst_x , int $dst_y , int $src_x , int $src_y , int $src_w , int $src_h )
Copy a part of src_im onto dst_im starting at the x,y coordinates src_x, src_y with a width of src_w and a height of src_h. The portion defined will be copied onto the x,y coordinates, dst_x and dst_y. (PHP.net
$move_right = 10;
$move_down = 8;
imagecopy($img, $mark, $move_right, $move_down, 0, 0, $icon_width, $icon_height);
turns out, I'm not being more simple than I should be.
It's already to the positioning I need, I just need to NOT complicate the int $dst_x/$dst_y.
I put simple integers there, and it works.
Related
I need help (My english is not good, please try to understand what i'm trying to find). Currently i'm working in a project based on image transformation, where i'm using imagick to transform image. I'm successfully transformed my image. What i am doing in my project is taking a photo(photo1), placing it to another photo (photo2 {the grey are is transparent}) which create the following effect photo3. Then replaceing it again with photo2 (to create the mask effect which showing the hand), and the result is (photo4). But the problem is, photo1 area in photo4 gets darker. {Please compare photo3 and photo4}. Can anyone help me how to keep the original color of photo1 in photo4. Here is my code:
$image1 = new imagick( public_path("img/testImage2.jpg") );
$image2 = new imagick( public_path("storage/Templates/romantisch copy.png"));
$image3 = new imagick( public_path("storage/Templates/romantisch copy.png") );
//for preserving transparency
$image2->mergeImageLayers(\Imagick::LAYERMETHOD_FLATTEN);
$image3->mergeImageLayers(\Imagick::LAYERMETHOD_FLATTEN);
//resizing photo1
$image1->resizeImage(468, 729, Imagick::FILTER_LANCZOS, 1);
/* Fill background area with transparent */
$image1->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_TRANSPARENT);
// $image2->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_TRANSPARENT);
$image1->setImageArtifact('compose:args', "1,0,-0.5,0.5");
$image1->setImageMatte(true);
$controlPoints = array(
0, 0, //initial point (top left)
0, 0, //targeted point (top left)
0, $image1->getImageHeight(), //initial point (bottom left)
0, $image1->getImageHeight(), //targeted point (bottom left)
$image1->getImageWidth(), 0, //initial point (top right)
$image1->getImageWidth(), 0, //targeted point (top right)
$image1->getImageWidth(), $image1->getImageHeight(), //initial point (bottom right)
$image1->getImageWidth(), $image1->getImageHeight() //targeted point (bottom right)
);
// /* Perform the distortion */
$image1->distortImage(Imagick::DISTORTION_PERSPECTIVE, $controlPoints, true);
$image2->compositeImage($image1, Imagick::COMPOSITE_OVER, 720, 368);
$image2->compositeImage($image3, Imagick::COMPOSITE_OVER, 0, 0);
/* Ouput the image */
header("Content-Type: image/png");
$image2->writeImage ("test_0.png");
echo $image2;
Found my solution. Changing my colorspace solved the problem. still don't know why.
$image2->transformImageColorspace(\Imagick::COLORSPACE_XYZ);
$image3->transformImageColorspace(\Imagick::COLORSPACE_XYZ);
I am trying to merge two images in PHP, overlapping each other in the middle like in here : http://i.stack.imgur.com/ejdDQ.jpg
However, I am having no luck.
On the ImageMagick page, they are using this method to do it in the command line:
http://www.imagemagick.org/Usage/photos/#overlap
But since I cannot use exec on my server, I have to do it somehow with the help of the imagick extension installed on the server (http://us1.php.net/manual/en/book.imagick.php).
Is there any way to make this work?
Using the source files from the link and the code below generates the image:
//Load the images
$left = new Imagick(realpath('../images/im/holocaust_tn.gif'));
$right = new Imagick(realpath('../images/im/spiral_stairs_tn.gif'));
$gradient = new Imagick(realpath('../images/im/overlap_mask.png'));
//The right bit will be offset by a certain amount - avoid recalculating.
$offsetX = $gradient->getImageWidth() - $right->getImageWidth();
//When doing the fading of the images, ImageMagick uses "White == show image".
//The gradient is setup with black on the left, white on the right. So the for
//the left image we need to reverse the gradient to make it white on the left.
$negativeGradient = clone $gradient;
$negativeGradient->negateimage(false);
//Fade out the left part
$left->compositeimage(
$negativeGradient,
Imagick::COMPOSITE_COPYOPACITY,
0, 0
);
//Fade out the right part - offset the gradient
//to make it align in the final image
$right->compositeimage(
$gradient,
Imagick::COMPOSITE_COPYOPACITY,
-$offsetX, 0
);
//Create a new canvas to render everything in to.
$canvas = new Imagick();
$canvas->newImage($gradient->getImageWidth(), $gradient->getImageHeight(), new ImagickPixel('black'));
//Blend left half into final image
$canvas->compositeimage(
$left,
Imagick::COMPOSITE_BLEND,
0, 0
);
//Blend Right half into final image
$canvas->compositeimage(
$right,
Imagick::COMPOSITE_BLEND,
$offsetX, 0
);
//Output the final image
$canvas->setImageFormat('png');
header("Content-Type: image/png");
echo $canvas->getImageBlob();
// And Robert is your father's brother.
My code so far (it creates an overlay to a youtube thumbnail):
<?php
header("Content-type:image/png");
$background=imagecreatefromjpeg("http://img.youtube.com/vi/".$_GET['v']."/default.jpg");
$insert=imagecreatefrompng("play.png");
imagecolortransparent($insert,imagecolorat($insert,0,0));
$insert_x=imagesx($insert);
$insert_y=imagesy($insert);
imagecopymerge($background,$insert,5,57,0,0,$insert_x,$insert_y,100);
imagepng($background,NULL);
The output image is 120x90px, but i need it to have 90x90px.
Anyone knows how this is possible?
Thanks in advance!
http://www.johnconde.net/blog/cropping-an-image-with-php-and-the-gd-library/
<?php
header("Content-type:image/png");
$background = imagecreatefromjpeg("http://img.youtube.com/vi/".$_GET['v']."/default.jpg");
$insert = imagecreatefrompng("play.png");
imagecolortransparent($insert,imagecolorat($insert,0,0));
list($current_width, $current_height) = getimagesize($background);
$left = 0;
$top = 0;
$crop_width = 90;
$crop_height = 90;
$canvas = imagecreatetruecolor($crop_width, $crop_height);
$current_image = $background;
imagecopy($canvas, $current_image, 0, 0, $left, $top, $current_width, $current_height);
imagecopymerge($canvas,$insert,5,57,0,0,$current_width,$current_height,100);
imagepng($canvas);
?>
try that it should work if not comment as to otherwise.
This is taken from a function I wrote to create square thumbnails. You may find the commentary I wrote for myself helpful. Depending on your needs (i.e if you can't afford to make assumptions about the type and dimensions of incoming images) you may need to add additional checks. To avoid smashed or stretched thumbnails we take a central part of the image which is most likely to contain something distinguishable as source co-ordinates.
The basic idea is: Since imagecopyresampled or imagecopyresized also allow you to specify destination and source coordinates, you can copy only part of your original image to a new canvas and save that (or directly output to browser). To avoid smashed or stretched dimensions we take a central part of the original image which is most likely to contain distinguishable content.
//assuming you have already merged your $background image with your overlay at this point
//original dimensions
$original_width = imagesx($background);
$original_height = imagesy($background);
//new dimensions
$new_width = 90;
$new_height = 90;
//the center of the rectangular image
$center = $original_width/2, $original_height/2
//the coordinates from where to start on the original image
//assuming you want to crop the center part
$src_x = floor(($original_width/2) - ($new_width/2));
$src_y = floor(($original_height/2) - ($new_height/2));
//create a new canvas with the new desired width, height
$temp = imagecreatetruecolor(90,90);
//copy the large image to this new canvas
imagecopyresampled($temp,$background,0,0,$src_x,$src_y,$new_width,$new_height,$original_width,$original_height);
//from right to left: source image, destination image, dest x, dest y,
//source x, source y, new width, new height, original width, original height
//save the canvas as an image
imagepng($temp);
This could be improved to handle larger images by first taking a central part relative to it's size and then scaling it down to the new canvas.
I want to insert an image in my created PDF file. However, it won't position well at all.
If I do this:
$fpdf->Image($row_products['prod_imagelarge'], 10);
The images will appear however, they're too big.
If I do this:
$fpdf->Image($row_products['prod_imagelarge'],30, 40, 40, 40);
Not all images will appear. Only 1 image per page will appear but with
the right size.
Actually, I am inserting an image inside a while loop.
What I would want to display in the pdf file is: (in order)
-product name (works fine)
-product image (the problem is here!)
-product description (works fine)
Similar to Naveed, but a little more complete with the rest of your row data. The trick is to capture the X and Y position before placing the image and then manually set the abscissa ("position") to the proper place, given the new image.
$image_height = 40;
$image_width = 40;
while ($row_products = mysql_fetch_array($products)) {
$fpdf->Cell(0, 0, $row_products['prod_name'], 0, 2);
$fpdf->Cell(0, 0, $row_products['prod_description'], 0, 2);
// get current X and Y
$start_x = $fpdf->GetX();
$start_y = $fpdf->GetY();
// place image and move cursor to proper place. "+ 5" added for buffer
$fpdf->Image($row_products['prod_imagelarge'], $fpdf->GetX(), $fpdf->GetY() + 5,
$image_height, $image_width)
$fpdf->SetXY($start_x, $start_y + $image_height + 5);
}
If one page contains many images then may be your images are placed on each others. You should change position for each image on one page. Try something like this.
for( $i=10; $i<=200; $i=$i+10 ) {
$fpdf->Image($row_products['prod_imagelarge'],30, $i, 40, 40);
}
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.
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.
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);
}
?>