Crop all but bottom 10% of image with Imagick - php

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
);

Related

PHP imagerotate is cropping image

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.

resizing image based on rules in php

I know how to resize an image keeping its ratio based on these formulas :
Width Formula :
Orig H / Orig W * New W = New H
Height Forula :
Orig W / Orig H * New H = New W
But i have set a maximum width before the image is resized and a maximum height value too.
So how do i work it with two maximum values ??
Say the max height was 600 and the max height was 100 ??
The answer is probably staring me in the face..
This is what i have just now using just the height.
$image_size = new Image(DIR_IMAGE.'data/signatures/'.$file);
$w_size = $image_size->info['width'];
$h_size = $image_size->info['height'];
$w_new_size = round($w_size/$h_size*100);
$h_new_size = 100;
I guess what i'm trying to say is i don't want the image to go above the set width or set height but it has to keep its ratio.
Some show me the light ??
Let php.net show you the light:
http://www.php.net/manual/en/function.imagecopyresampled.php
Example #2 is doing what you ask for, isn't it?

PHP: Image Resize and Crop to Portrait

I need to the re size and crop image to center. The end result image needs to be 250W x 330H.
I need to re size the image uploaded to 330 height but leave the correct ratio with the width. Then check to see if width is 250 or over, after the re size. If it is not, then I need to re size the image from the original to 250 width but leave the correct ratio with the height.
So if it did re size to 330 height and the width was 250 or over, then I need to crop the image to the center on width to 250. But if it re sized to 250 width, with height being 330 or over, then I need to crop image to the center on height to 330.
I was trying to create it myself but I'm so confused by the crop to center part.
With the use of Wideimage library (http://wideimage.sourceforge.net/):
$thumb = WideImage::load('uploaded_image.png')->resize(250, 330);
if ($thumb->getWidth() > 250 || $thumb->getHeight() > 330) {
$thumb = $thumb->crop('center', 'center', 250, 330);
}
$thumb->saveToFile('cropped_image.png');
I wrote a library to can do just that: Php Image Magician
<?php
require_once('../php_image_magician.php');
$magicianObj = new imageLib('racecar.jpg');
$magicianObj -> resizeImage(250, 330, 'crop');
$magicianObj -> saveImage('racecar_cropped.jpg', 100);
?>
here is a function ive just completed to force an exact pixel size - I cant guarantee it 100% but ive tested it with many options and got perfect results so far, it gives the closest result imo. First it resizes the SMALLEST difference between the source image and specified sizes by calculating ratios. Then trims off excess pixels. I have compensated for odd numbers, negative values, etc. I have had good results so far. Please let me know if ive missed something or if it breaks somehow:
PHP:
// set source/export paths and pixel sizes for final sizes
$src="path/to/source.jpg";
$exp="path/to/output.jpg";
$crop_w=300;
$crop_h=200;
$size = getimagesize("$src");
//check image sizes
if( ($size[0] < $crop_w) || ($size[1] < $crop_h) ){
echo 'Image not big enough to crop';
exit();
}
//get differential ratios of image vs crop sizes -
//smaller ratio must be resized
$ratio_w = $size[0]/$crop_w;
$ratio_h = $size[1]/$crop_h;
//square or landscape - shave sides
if($ratio_w >= $ratio_h){
//resize width / shave top&bottom
exec("convert $src -resize x".$crop_h." $exp ");
$size = getimagesize("$exp");
$diff=abs($crop_w-$size[1]);
//dividing 1 by 2 will leave a zero on round down - just force resize
if($diff < 2){
// skip shave - diff too small
exec('convert $exp -resize '.$crop_h.'X! $exp ');
}
else{
//divide difference by 2 for shave amount
$shave = round($diff/2,0,PHP_ROUND_HALF_DOWN); //halve & round difference down to avoid cropping smaller
exec('convert '.$exp.' -shave '.$shave.'x0 '.$exp.' '); //shave sides
//odd $diff leave a rounded down pixel - force height resize
if($diff%2 !==0){//if $diff was not divisible by two then 1 pixel is left from round down
exec('convert '.$exp.' -resize '.$crop_w.'x! '.$exp.' ');
}
}
}
//portrait - shave height
else{
//resize width / shave top&bottom
exec("convert $src -resize ".$crop_w."x $exp ");
$size = getimagesize("$exp");
$diff=abs($crop_h-$size[1]);
//dividing 1 by 2 will leave a zero on round down - just force resize
if($diff < 2){
exec('convert $exp -resize x'.$crop_h.'! $exp ');
}
else{
//divide difference by 2 for shave amount
$shave = round($diff/2,0,PHP_ROUND_HALF_DOWN); //halve & round difference down to avoid cropping smaller
exec('convert '.$exp.' -shave 0x'.$shave.' '.$exp.' '); //shave sides
//odd $diff leave a rounded down pixel - force height resize
if($diff%2 !==0){//if $diff was not divisible by two then 1 pixel is left from round down
exec('convert '.$exp.' -resize x'.$crop_h.'! '.$exp.' ');
}
}
}
Feel free to use / make comments. Php 5.4<, Imagemagick 6.8.8.1, Windows xampp.

PHP image resize depending on height

Hey all i am trying to figure out how to resize an image that has a higher height than width. The normal width and height of the area where the image needs to be displayed is:
width = 1000px
height = 700px
What type of math would i need in order to resize that to the proper width/height above without screwing it?
The test image size is:
width = 1451
height = 2200
I was thinking of doing this:
(700/org.height)
But that does not come up with the correct number of 462.
In photoshop, changing the height to 700 yields a width value of 462.
so you want to scale your image so that it fits as large as possible within a 1000x700 square without stretching it? You could do something like this:
$availH = 700;
$availW = 1000;
$imageH = 2200;
$imageW = 1451;
// you know you want to limit the height to 700
$newH = $availH;
// figure out what the ratio was that you adjusted (will equal aprox 0.3181)
$ratio = $availH / $imageH;
// now that you have the $ratio you can apply that to the width (will equal 462)
$newW = round(imageW * $ratio);
Now you have $newW and $newH which are the new sizes for your image properly scaled. You could of course condense this down but I've written it out so each step is more clear.
Formula to keep aspect ratio when resizing is
original height / original width x new width = new height
Source: http://andrew.hedges.name/experiments/aspect_ratio/
But you want to switch it around to the following I think:
original width / original height x new height = new width

PHP create thumbnail around user specified point

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.

Categories