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.
Related
I'm trying to do the following layout in an PDF file generated by FPDF in PHP.
--------------------------------------------------
| | Text1 |
| IMAGE | Text2 |
| | Text3 |
--------------------------------------------------
But I couldn't figure out how to do it by now.
This is the code I'm using
public function floatingImage($imgPath, $height) {
list($w, $h) = getimagesize($imgPath);
$ratio = $w / $h;
$imgWidth = $height * $ratio;
$this->Image($imgPath, $this->GetX(), $this->GetY(), 140, 100);
$this->x += $imgWidth;
}
/* Logbuch is our extension from FPDI, but there's nothing changed
* only a custom header, footer and the floatingImage and loadMapImage function are part of it
*/
$pdf = new logbuch();
// Frontpage
$pdf->AddPage();
$mapImage = $pdf->loadMapImage();
$pdf->setJPEGQuality(75);
$x = 15; $y = 21; $w = 100;
$pdf->floatingImage($mapImage, 100, 100);
$pdf->SetFillColor(154,222,229);
$pdf->Cell(0,0,"Test",0,0,'R',true);
$pdf->Ln();
$pdf->Cell(100,0,"Test",0,0,'R',true);
$pdf->Ln();
$pdf->Cell(100,0,"Test",0,0,'R',true);
This is the result I'm generating by now
If I change the width of the last two cells to 100 it will look like this:
This is nearly what I want, the cells just must align to the right side. How can I do this?
I found the answer myself
You can set an X value to the pdf with determines the position on the X axis.
$pdf->Cell(0,0,"Test",0,0,'R',true);
$pdf->Ln();
$pdf->SetX(100); //The next cell will be set 100 units to the right
$pdf->Cell(100,0,"Test",0,0,'R',true);
$pdf->Ln();
Importend to mention is that after every wrote Cell X will be asigned a new value from the Cell() function. So you need to SetX() before creating a new Cell!
I have 2 dimensions, (width & height) and I need to take another image, and resize it until both width and height are greater than the 2 dimensions. If the image is already larger than the 2 dimensions, I still need to resize it to be slightly larger than the given dimensions.
I also need to keep the image aspect ratio the same.
I've been trying the following:
$masksize = getimagesize($maskpath);
// Reverse the sizes as it's landscape and we're always checking portrait
$maskwidth = $masksize[1];
$maskheight = $masksize[0];
$currentsize = getimagesize($target_path);
$currentwidth = $currentsize[0];
$currentheight = $currentsize[1];
$thumwidth = 0;
$thumbheight = 0;
do {
$thumbwidth += 10;
$thumbheight = $currentheight*($thumbheight+10/$thumbwidth);
}while (($thumbwidth < $maskwidth) && ($thumbheight < $maskheight));
However it's not working, it only loops once and the width stays at 10.
So say for instance I have an image at 1000 x 2000, and the dimensions I have are 500 x 1000, I need the image to be resized to 510 x 1010 (i.e always bigger than the given dimensions, but only by a max of 10)
i have a image manipulation class, i want to create images that always fill the entire new width and height so there are no borders/solid color background, i just cant understand how i can make it always fill the height and width (mantaining the aspect ratio of the uploaded image) if the image width AND height are smaller than the new image size..
just like the zoomcrop (zc=1) from phpthumb class (i looked the code from it but i couldnt mimic the behavior)
public function resizeCrop($newwidth, $newheight) {
...
$x = $this->getX();
$y = $this->getY();
...
else if ($x < $newwidth && $y < $newheight)
{
// logic ??
}
}
You need to make sure that the smaller (relative to the aspect ratio of the original image and that of container) side is zoomed to maximum. Have a look at this code:
public function resizeCrop($newwidth, $newheight) {
...
$x = $this->getX();
$y = $this->getY();
// old images width will fit
if(($x / $y) < ($newwidth/$newheight)){
$scale = $newwidth/$x;
$newX = 0;
$newY = - ($scale * $y - $newheight) / 2;
// else old image's height will fit
}else{
$scale = $newheight/$y;
$newX = - ($scale * $x - $newwidth) / 2;
$newY = 0;
}
// new image
$dest = imagecreatetruecolor($newwidth, $newheight);
// now use imagecopyresampled
imagecopyresampled($dest, $src, $newX, $newY, 0, 0, $scale * $x, $scale * $y, $x, $y);
return $dest;
}
Update: Corrected the function. It is now working perfectly, I have tested it on my dev machine.
To maintain aspect ratio, you need to choose: either make the image too big and then crop the original, or you make it fit just right and then fill in the parts that don't reach the edges with a solid color.
The former, you can compare the percentage change for width and height respectively, then use the larger percentage as a multiplier against both dimensions. For a 1 x 1 unit image that you want to fit into a 2w x 3h unit area and maintain aspect ratio: you can use a 3x multiplier, get a 3 x 3 unit image, and crop .5 units left/right.
The latter, you use the smaller percentage as a multiplier. For a 1 x 1 unit image that you want to fit into a 2w x 3h unit area and maintain aspect ratio: you can use a 2x multiplier, get a 2 x 2 unit image, and add .5 units of solid color top/bottom.
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.
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.