So I have a user image and a user specified point of interest based off of that image.
I have retrieved that point of interest from a XML file and put them into variables so I have 2 points.
x= 246
y= 73
My question: How can I crop a 45 by 53 thumbnail image with the above coordinates being the center-point of the thumbnail? I don't want the image to scale at all, just crop.
With GD it should work this way:
// Open source image
$srcImg = imagecreatefromjpeg ( $filename );
// Create new image for the cropped version
$destImg = imagecreate ( 45, 53 );
// Calculate the upper left of the image-part we want to crop
$startX = x - 45 / 2;
$startY = y - 53 / 2;
// Copy image part into the new image
imagecopy ( $destImg, $srcImg , 0, 0, $startX, $startY, 45, 53 );
// Write the new image with quality 90
imagejpeg($destImg, 'newfile.jpg', 90);
You might want to check for rounded coordinates as your image might blur if you don't. You should check if your cropped image coordinates are well within your original image if the user lets say chooses a corner as poi.
Related
I am reading an 8.5 x 11" PDF and creating a jpg thumbnail.
I want to crop all but approx the bottom 10% of the image. (basically only want the footer in the final)
$pdf_file = $file;
$save_to = 'bottom.jpg';
$img = new imagick();
$img->setResolution(300,300);
$img->readImage("{$pdf_file}[0]");
$img->scaleImage(800,0);
$img->setImageFormat('jpg');
$img = $img->flattenImages();
$img->cropImage(0,0,0,350);
$img->writeImages($save_to, false);
echo '<img src="bottom.jpg">';
The output of the above code produces a jpg showing the footer, however the image is 800px W X 685px H with white space on top of the footer.
I just want the footer at 800px W X approx 200px H.
I'm not sure why you're passing in zero 3 times to the crop function. The parameters are meant to be:
width - The width of the crop
height - The height of the crop
x - The X coordinate of the cropped region's top left corner
y - The Y coordinate of the cropped region's top left corner
So this should do what you want:
$img->cropImage(
$image->getImageWidth(),
350,
0,
$image->getImageHeight() - 350
);
I am writing a script that takes an arrow image and rotates it by a set number of degrees. Using the code below, when the angle is a multiple of 90 the image rotates and displays as expected.
The source image looks like this (74 x 74):
Images after rotating by 90:
Images after rotating by any other number (not a multiple of 90) eg 45:
As can be seen in the image, the tip of the arrow has been cropped out of the image. Could anyone please tell me why this is happening? Again, multiples of 90 are fine, it's just any other number where the unusual cropping occurs.
$props = ['w' => 74, 'h' => 74];
$angle = 360 - $_GET['angle'];
$final_img = imagecreatetruecolor($props['w'], $props['h']);
imagesavealpha($final_img, true);
$transColor = imagecolorallocatealpha($final_img, 0, 0, 0, 127);
imagefill($final_img, 0, 0, $transColor);
$rotate = imagecreatefrompng('arrow.png');
$src = imagerotate($rotate, $angle, $transColor); //rotated my image
$src_x = ImageSX($src); //find out new x width
$src_y = ImageSY($src); //find out new y height
$src_widthx = $src_x/2 - $props['w']/2; // divide each by 2 and then subtract desired end width from wider rotated width
$src_heighty = $src_y/2 - $props['h']/2; // and again for height
imagecopy($final_img, $src, 0, 0, $src_widthx, $src_heighty, $props['w'], $props['h']);
header('Content-Type: image/png');
imagepng($final_img);
When you rotate a square of nXm pixels by lets say 45 degrees you will get the diagonals(which are bigger than n or m and equal sqrt(n^2+m^2)) of the image be the new rotated image width and height.
The function crops the rotated image using the original dimensions of the image, namely n and m.
A way to fix the problem would be by crating a bigger blank image with the appropriate size, sqrt(width_original_image^2+height_original_image^2), and than copy the original image to the new image using imagecopy. After that you can use imagerotate on the new image
I installed and used the ImageMagick PHP library and the rotations show uncropped, no matter the degree of rotation.
I wish to make part (or in fact, several parts) of an image transparent using IMagick, such that I can use it as a mask over a different image. I can't figure out any way of doing this in an simple fashion.
So say my starting image is represented as below, where X is any color:
XXXXXXXXXXXXX
XXXXXXXXXXXXX
XXXXXXXXXXXXX
XXXXXXXXXXXXX
XXXXXXXXXXXXX
Then I want to be able to make certain rectangular regions transparent (so it ends up a bit like a punch-card):
XXXXXXXXXXXXX
X XXXXXXXXXX
X XXXX XXXX
XXXXXXX XXXX
XXXXXXXXXXXXX
Does anyone know of a good way of doing this? Thanks.
Figured it out.
//Open your image and get its dimensions
$image = new Imagick('image.png');
$height = $image->getImageHeight();
$width = $image->getImageWidth();
//Create a new transparent image of the same size
$mask = new Imagick();
$mask->newImage($width, $height, new ImagickPixel('none'));
$mask->setImageFormat('png');
//Draw onto the new image the areas you want to be transparent in the original
$draw = new ImagickDraw();
$draw->setFillColor('black');
$draw->rectangle( 10,10,100,100 );
$mask->drawImage( $draw );
//Composite the images using Imagick::COMPOSITE_DSTOUT
$image->compositeImage($mask, Imagick::COMPOSITE_DSTOUT, 0, 0, Imagick::CHANNEL_ALPHA);
imagecopyresized ( resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h )
This is what I want to do: I have an image that's 600x1000px in size, and I want to create a thumb that's 100x100px after resizing that image to 300x500px, the x coordinate for the top left point of the thumb square should be at 100(src x) and 120(src y).
According to what I understand from the manual, the command should be
$dst_image = imagecreatetruecolor(100,100);
$src_image = imagecreatefromjpeg('/home/sandbox/imagetoresize.jpg');
imagecopyresized ($dst_image, $src_image, 0, 0, 100, 120, **300 , 500 , 600 , 1000** )
It is cropping the image just fine, but it isn't resizing it correctly. I never got it to match what I see in my image editor (the GIMP). What am I doing wrong? I confirmed that all the numbers are correct, but it's always shifted up or down no matter what I do.
Here's a link to a function I wrote using PHP GD to resize any sized image to any arbitrary size. It has an explaination, and options to use crop-to-fit or letterboxing to fit the destination aspect ratio.
http://www.spotlesswebdesign.com/blog.php?id=1
update
it should look more like this.
$dst_image = imagecreatetruecolor(100,100);
$src_image = imagecreatefromjpeg('/home/sandbox/imagetoresize.jpg');
imagecopyresized ($dst_image, $src_image, 0, 0, 100, 120, 100, 100, 400, 400);
takes a 400x400 square from the source, and copies it into a 100x100 square in the destination. the top-left of the source square is 100 x and 120 y. x and y represent number of pixels from the top left corner.
Yes, that fixed it nicely.
For Googlers: What I basically needed to do is to have the source width and source height link to the actual width and height of the area that I will crop in the source image. Which means that the code needed to be:
imagecopyresized ($dst_image, $src_image, 0, 0, 200, 240, 100, 100, 200, 200);
So the variables actually mean the following:
$src_x = the x co-ordinate of the top left point of the square in the original. Since the original is twice the size of the resized version from which the thumb is to be extracted, this will be 200 ((original_width / resized_width) * x).
$src_y = the same thing, but with the y co-ordinate.
$dst_w = the width of the generated thumbnail - 100.
$dst_h = the height of the generated thumbnail - 100.
$src_w = the width of the area that I will crop from the original ((original_width / resized_width) * $dst_w)
$src_h = the height of the area that I will crop from the original ((original_width / resized_width) * $dst_h)
dqhendricks: Thanks a lot for your help, I really appreciate it. I was scratching my head over this for hours.
OK i thought i understood this function but i have a complete mental block on this one.
I wanted to create cropped thumbnails of size 75x75 from photos that are 800x536.
the imagecopyresampled function has 10 possible parameters. i first tried this:
// Starting point of crop
$tlx = floor(($width / 2) - ($new_width / 2)); //finds halfway point of big image and subtracts half of thumb.
$tly = floor(($height / 2) - ($new_height / 2)); //gets centre of image to be cropped.
imagecopyresampled($tmp_img,$img,0,0,$tlx,$tly,$new_width,$new_height,$orig_width,$orig_height);
this finds either side of the halfway mark on the large image and crops it out. or so i thought. but it actuall crops a bit of the picture and leaves the right hand side and bottom in black (presumably from the imagecreatetruecolor earlier.
so i found a way to do what i want but i want you to explain how it is working.
i now have:
//Create thumbnails.
$new_width = 75; //pixels.
$new_height = 75;
if($width > $height) $biggest_side = $width;
else $biggest_side = $height;
//The crop size will be half that of the largest side
$crop_percent = .5;
$crop_width = $biggest_side*$crop_percent;
$crop_height = $biggest_side*$crop_percent;
$c1 = array("x"=>($width-$crop_width)/2, "y"=>($height-$crop_height)/2);
//Create new image with new dimensions to hold thumb
$tmp_img = imagecreatetruecolor($new_width,$new_height);
//Copy and resample original image into new image.
imagecopyresampled($tmp_img,$img,0,0,$c1['x'],$c1['y'],$new_width,$new_height,$crop_width,$crop_height);
it's doing it perfectly, shrinking the image and then cropping out the middle, but my maths isn't very sharp and also i think it's definitely that i don't fully understand the imagecopyresampled function.
can someone walk me through it? parameter by parameter. especially the last two. originally i entered the width and height of the original image, but this enters 400 and 400 (half of the longest side). sorry for the rant. hope my mind understands this soon :)
Alex
It's fairly simple, documented here
The parameters:
1) $dst_image, a valid GD handle representing the image you want to copy INTO
2) $src_image, a valid GD Handle represending the image you're copying FROM
3) $dst_x - X offset in the destination image you want to place the resampled image into
4) $dst_y - Y offset, ditto
5) $src_x - X offset in the source image you want to start copying from
6) $src_y - Y offset, ditto
7) $dst_x - X width of the newly resampled image in $dst_image
8) $dst_y - Y width, ditto
9) $src_x - X width of the area to copy out of the $src_image
10) $src_y - Y width, ditto
So...
You've got a $src_image that's 800x536, and a $dst_image that's 75x75
$width = 800 $new_width = 75
+-----------------------+ +----+
| | | |
| | | | $new_height = 75
| | $height = 536 +----+
| |
| |
+-----------------------+
Sounds like you want to take the middle chunk of the source image and make a thumbnail from that, right? This middle chunk should represent half the height & width of the original image, so you want:
$start_X = floor($width / 4); // 200
$width_Y = floor($height / 4); // 134
200 400 200
+-----------------------+
| | | | 134
|-----+----------+------|
| | This part| | 268
|-----+----------+------|
| | | | 134
+-----------------------+
$end_x = $start_X + (2 * $start_x) // 3 * $start_x = 600
$end_y = $start_Y + (2 * $start_y) // 3 * $start_y = 402
imagecopyresampled($src, $dst, 0, 0, $startX, $start_y, 75, 75, $end_x, $end_y);
a b c d e f g h
a,b - start pasting the new image into the top-left of the destination image
c,d - start sucking pixels out of the original image at 200,134
e,f - make the resized image 75x75 (fill up the thumbnail)
g,h - stop copying pixels at 600x402 in the original image
Now, this is assuming that you want the thumbnail to be completely filled up. If you want the source image to be shrunk proportionally (so it has the same ration of height/width as the original, then you'll have to do some math to adjust the a,b and e,f parameters.