Crop and Resize image from X and Y Position - php

I'm trying to crop then resize an image on PHP v5.4, I've read these resources
Put PNG over a JPG in PHP
http://php.net/manual/en/function.imagecopy.php
http://php.net/manual/en/function.imagecopyresampled.php
http://php.net/manual/en/function.call-user-func-array.phPP
PHP watermarking
http://php.net/manual/en/function.imagecreatetruecolor.php
My code is based off the answer from Cropping image in PHP (the dimensions between these images vary alot).
I want to resize this image from 1151x768 to 200x82 and crop the background section at x: 0, y: 686
I'd prefer not bloating the question with the entire 600 lines in this question, $output refers to setwidth1200nzpioneerthursday08398 image
<?php
$output = imagecreatefromjpeg("setwidth1200nzpioneerthursday08398.jpg");
$source_crop_image = imagecreatetruecolor(200, 82);
if(!is_resource($source_crop_image)) {
return $source_crop_image;
}
imagealphablending($output, true);
$source_copy_result = imagecopy($output, $source_crop_image, 0, 0, 0, 686, 200, 82);
$source_copy_result = (bool) $source_copy_result;
if(!$source_copy_result) {
return false;
}
$source_image_result = imagejpeg($source_crop_image, "images/mynewimage.jpg");
$source_image_result = (bool) $source_image_result;
?>
My Image setwidth1200nzpioneerthursday08398
Ideally I'm trying to get it crop the RED SECTION, while keeping the scale intact then resizing to 200x82
My Result
My Expected Result (I created this image using GIMP).
I have no idea why my resulting image is a black box ..

You have imagecopy() arguments in wrong order.
The right one is $source_copy_result = imagecopy($source_crop_image, $output, 0, 0, 0, 686, 200, 82);

Related

How to crop image with dimensions (without quality loss) in PHP?

I need to crop the image with PHP by using the dimensions.
And save it into the local with JPEG format.
Dimensions that i receive is,
{"left":82.5,"top":48.875,"width":660,"height":371.25}
I need to crop from Original size of the image.
Ex. image is 1200x800, then the result image dimension from the actual size, not resizing or any. Because the quality should be same.
How could i use these params to crop the image ?
Is it possible ?
Use the built-in imagick class:
$image = realpath("/path/to/your/image.extension");
$cropped = realpath("/path/to/your/output/image.png");
$imObj = new Imagick();
$imObj->cropImage($width, $height, $offset_x, $offset_y);
$imObj->setImageFormat("png"); // this is unnesesary, you can force an image format with the extension of the output filename.
$imObj->writeImage($cropped);
As for lossless output, use an image format with lossless encoding. PNG is perfect for the job, since it was designed for network transfer (hence the "Adam-7" interlacing).
Check this related question about lossless image formats on graphic design stack:
What are lossless image formats?
You can use imageCopyResampled function which was designed pretty much exactly for this.
$image = imagecreatefromjpeg($imageFileURL);
/***
* resize values (imported)
***/
$left = 82;
$top = 49;
$width = 660;
$height = 371;
/***
* Create destination image
***/
$newImage = imagecreatetruecolor($width,$height);
$saveToFile = "destintion filespace of image file.jpg"
if(imagecopyresampled($newImage, $image, //dest/source images
0, 0, // dest coordinates
$left, $top, // source coordinates
$width, $height, // size of area to paste to
$width, $height // size of area to copy from
)){
imagejpeg($newImage,$saveToFile,100); //zero compression saved to file
print "image resized ok!!";
}
The new fileimage will be the size specified with $width,$height and will be offset from the original image by the values given in $left and $top. From your question this looks like what you want. This will not resize or change the compression of the image (until you save the file and then possibly set these details yourself).

How to create and to merge a 2D transparent barcode on top of a JPG image in PHP?

Could you please see the below code and let me know how to write the $png on top of the $jpg image? The code shows the bacode image in the browser, but it does not save it and merge it with $jpg image. thanks for taking time and help.
$jpg= imagejpeg($image, '/applications/AMPPS/www/files/final-image-2.jpg');
require_once(dirname(__FILE__).'/tcpdf/tcpdf_barcodes_2d.php');
// set the barcode content and type
$barcodeobj = new TCPDF2DBarcode('Hello-this-is-a-test', 'DATAMATRIX');
// output the barcode as PNG image
$barcodeobj->getBarcodePNG(6, 6, array(0,0,0));
// the code stops to work from here
$png= imagepng($barcodeobj, '/applications/AMPPS/www/certificates/barcode.jpg');
imagecopymerge($png, $jpg, 0, 0, 0, 0, 50, 50, 100);
imagedestroy($image);
imagedestroy($png);

Merging two PNG images with the smaller image behind with GD

I am attempting to merge two png images by placing a smaller png behind an image with a "hole" in the center with transparency.
The "Front" image is $src in this example
The "Back" image is $dest in the example
So far, i've gotten it to work in reverse (by putting the $dest image / smaller image in front) using the following code:
imagecopymerge($src, $dest, 300, 150, 0, 0, 150, 150, 100);
However, i'm not sure how to do it with the smaller image "Behind" the bigger image so that it fits perfectly in the hole.
Do I need to recreate the image ($dest) as a larger image (500 x 500) to "paste" the $src image over top of with 0 offset? This stuff is confusing :S
Figured it out.
First I merged the smaller image onto a blank image below that matched the larger image.
Then, I merged the image with the hole onto the new image created above. See as follows:
// Get size of larger image
$sz = getimagesize("larger.jpg");
// Create resources
$backing = imagecreatetruecolor($sz[0],$sz[1]);
$img1 = imagecreatefrompng("larger.jpg");
$img2 = imagecreatefrompng("smaller.jpg");
// Merge backing
imagecopymerge($backing, $img2, 300, 150, 0, 0, 150, 150, 100);
// Merge main
imagecopymerge($backing,$img1, 0, 0, 0, 0, $sz[0], $sz[1], 100);
// Save new image
imagepng($backing,$save);
// Destroy resources
imagedestroy($backing);
imagedestroy($img1);
imagedestroy($img2);
Hope this helps someone!

php imagick, how to make an area transparent

I want to make an area transparent within an Imagick object with a specific width, height and a top position.
For example I need a transparent area with 30px x 30px from the 15th px to the top but I can't find a way to do it.
$canvas1 = new Imagick();
$canvas1->newImage(30,60,'black','png');
Please help.
This may be a slightly simpler way of doing it. I recycled #AndreKR's setup code to get started:
$im = new Imagick();
$im->newImage(100,100, 'red');
$im->setImageAlphaChannel(Imagick::ALPHACHANNEL_ACTIVATE); // make sure it has an alpha channel
$box=$im->getImageRegion(30,30,15,15);
$box->setImageAlphaChannel(Imagick::ALPHACHANNEL_TRANSPARENT);
$im->compositeImage($box,Imagick::COMPOSITE_REPLACE,15,15);
While you can flood fill with transparency ink (not transparent ink) like this:
$im->floodFillPaintImage('#FF000000', 10, '#FFFFFF', 0, 0, false);
in this post, Anthony, apparently some important figure in the ImageMagick universe, says that you cannot draw with transparency.
So it seems you have to create a punch image and then use it to punch the transparent areas out in your actual image. To create the punch here I draw the rectangle opaque on a transparent brackground and then invert the whole image:
$punch = new Imagick();
$punch->newImage(100,100, 'transparent');
$drawing = new ImagickDraw();
$drawing->setFillColor(new ImagickPixel('black'));
$drawing->rectangle(15, 15, 45, 45);
$punch->drawImage($drawing);
$punch->negateImage(true, Imagick::CHANNEL_ALPHA);
Here's the actual image before the punching:
$im = new Imagick();
$im->newImage(100,100, 'red');
$im->setImageAlphaChannel(Imagick::ALPHACHANNEL_ACTIVATE); // make sure it has
// an alpha channel
Now we can copy over the alpha channel from our punch image. For a reason unknown to me the obvious way does not work:
// Copy over the alpha channel from one image to the other
// this does NOT work, the $channel parameter seems to be useless:
// $im->compositeImage($punch, Imagick::COMPOSITE_SRC, 0, 0, Imagick::CHANNEL_ALPHA);
However, these both work:
// Copy over the alpha channel from one image to the other
// $im->compositeImage($punch, Imagick::COMPOSITE_COPYOPACITY, 0, 0);
// $im->compositeImage($punch, Imagick::COMPOSITE_DSTIN, 0, 0);
(The light blue is the background of the Windows photo viewer, indicating transparent areas.)
You can set the opacity as follows
$image->setImageOpacity(0.0);
If you set it to 0.0 the image what you have crated will become transparent
for more information you can Set opacity in Imagick
if you want it for a particular area part then you need to change the approach by using GD library functions by doing some what like this
$img = imagecreatefrompng($imgPath); // load the image
list($width,$height) = getimagesize($imgPath); // get its size
$c = imagecolortransparent($img,imagecolorallocate($img,255,1,254)); // create transparent color, (255,1,254) is a color that won't likely occur in your image
$border = 10;
imagefilledrectangle($img, $border, $border, $width-$border, $height-$border, $c); // draw transparent box
imagepng($img,'after.png'); // save
I Could see a similar requirement which is posted in another forum here
Try
$canvas1->setImageOpacity(0);

Transforming transparent `gif` to grayscale while saving transparency

First, I resize the image while saving transparency:
/*
all the classic routine etcetera:
$canvas = imagecreatefrom[png|gif|jpeg]();
$resize = imagecreatetruecolor();
*/
if($blending){
$transparentIndex = imagecolortransparent($canvas);
if($transparentIndex >= 0){
#GIF
imagepalettecopy($canvas, $resize);
imagefill($resize, 0, 0, $transparentIndex);
imagecolortransparent($resize, $transparentIndex);
imagetruecolortopalette($resize, true, 256);
}else{
#PNG
imagealphablending($resize, false);
imagesavealpha($resize, true);
$transparent = imagecolorallocatealpha($resize, 255, 255, 255, 127);
imagefill($resize, 0, 0, $transparent);
}
}
imagecopyresampled($resize, $canvas, 0, 0, 0, 0, $nx, $ny, $x, $y);
// image[png|gif|jpeg]... (image gets saved)
Then, I want to apply grayscale filter to that previously saved image (within a new function):
/*
classic routine again:
$canvas = imagecreatefrom[png|gif|jpeg]()
*/
if($blending){
imagealphablending($canvas, false);
imagesavealpha($canvas, true);
}
imagefilter($canvas, IMG_FILTER_GRAYSCALE);
/*
This fully filters PNG's to Grayscale while saving transparency,
but for GIF, black background is added to my grayscaled picture,
plus, the picture isn't fully grayscale (more like gets high-contrasted with acidic colors).
*/
// image[png|gif|jpeg]
What would be the fix, to preserve transparency when applying IMG_FILTER_GRAYSCALE to gif?
What would be the fix, in order to transform gif to grayscale while saving the transparency? (Question revised due to answer provided by #Pierre)
Thanks in advance!
imagefilter used with the gray scale filter does take care of the alpha channel.
However, gif does not support alpha. So you won't be able to store it using the GIF format.
It is also important to note that the background color (one single color or color index being used as background) has nothing to do with the alpha (level of transparency of a given color or pixel). That means you are responsible to set the background color to the desired single color.
Update
It is not directly possible as the color used as transparent will be modified. That could be considered as a bug as the transparent color may or should be ignored by the filter. But that's another topic.
A workaround could be:
$logo = imagecreatefromgif('php.gif');
$newimg = imagecreatetruecolor(imagesx($logo), imagesy($logo));
/* copy ignore the transparent color
* so that we can use black (0,0,0) as transparent, which is what
* the image is filled with when created.
*/
$transparent = imagecolorallocate($newimg, 0,0,0);
imagecolortransparent($newimg, $transparent);
imagecopy($newimg, $logo, 0,0, 0, 0,imagesx($logo), imagesx($logo));
imagefilter($newimg, IMG_FILTER_GRAYSCALE);
imagegif($newimg, 'a.gif');
this code simply fetch the value of the existing transparent color, convert it to gray and set it back to the color index. This code will only work for palette image like gif but that's the idea.

Categories