I have the follow PHP code:
$w = 300; // Width of new image
$h = 300; // Height of new image
$oh = 540; // Original file height
$ow = 720; // Original file width
$x = 196;
$y = 50;
$image = imagecreatefromjpeg('fileToCrop.jpg');
$cropped_image = imagecreatetruecolor($w, $h);
imagecopyresampled($cropped_image, $image, 0, 0, $x, $y, $ow, $oh, $w, $h);
imagejpeg($cropped_image, 'fileToCrop.jpg', 100);
And want to crop the image, but my images are distorting / higher than original, eg:
Original:
Cropped ("N" for "Not" are showing):
I can't see what is wrong with my code, and what are happening to images goes bigger..
You inverted the last 4 parameters of imagecopyresampled
bool imagecopyresampled ( 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 )
Change it for
imagecopyresampled($cropped_image, $image, 0, 0, $x, $y, $w, $h, $ow, $oh);
But in fact, are you sure you're not looking for a straight copy of the cropped region?
imagecopy($cropped_image, $image, 0, 0, $x, $y, $ow, $oh);
because you omitted the quality on imagejpeg() it defaults to 75%
http://php.net/manual/en/function.imagejpeg.php
can you try adding 95 on 3rd parameter?
imagejpeg($cropped_image, 'fileToCrop.jpg', 95);
P.S.
If you can use a 3rdparty php script I'll suggest you just use timthumb
http://www.binarymoon.co.uk/projects/timthumb/
if you need a change of cropping location,
http://www.binarymoon.co.uk/2010/08/timthumb-part-4-moving-crop-location/
Related
I have transparent image that I want to overlay over the entire image to give it the boarder effect. In this code it crops an existing image. It merges the two but the final over the top is not showing the alpha. How can I fix this?
<?
$dst_x = 0; // X-coordinate of destination point.
$dst_y = 0; // Y --coordinate of destination point.
$src_x = 163; // Crop Start X position in original image
$src_y = 0; // Crop Srart Y position in original image
$dst_w = 469; // Thumb width
$dst_h = 296; // Thumb height
$src_w = 469; // $src_x + $dst_w Crop end X position in original image
$src_h = 296; // $src_y + $dst_h Crop end Y position in original image
// Creating an image with true colors having thumb dimensions.( to merge with the original image )
$dst_image = imagecreatetruecolor($dst_w,$dst_h);
// Get original image
$src_image = imagecreatefromjpeg("http://www.ucatholic.com/wp-content/uploads/2012/10/Sallixtus-631x295.jpg");
// Cropping
imagecopyresampled($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
// Saving
imagejpeg($dst_image, "images/crop.jpg");
$src = imagecreatefrompng('http://www.EdVizenor.com/images/saintCover.png');
/// THIS LINE NOT WORKING - - // Copy and merge
imagecopymerge($dst_image, $src, 0, 0, 0, 0, 469, 296, 100);
header('Content-Type: image/png');
imagegif($dst_image);
?>
Dont use imagecopymerge, use imagecopy, then it will works normally and your watermark will be shown with alpha.
imagecopy($dst_image, $src, 0, 0, 0, 0, 469, 296);
If used the imagecopy instead of imagecopymerge you will lose control over alpha channel.
I think you could use Jaguar , if you want a real fast overlay action using the Gd extension.
see my answer Here if you want to see how
if you want a brushed border you can use Jaguar like this:
use Jaguar\Canvas,
Jaguar\Drawable\Border;
$canvas = new Canvas('your image');
$brush = new Canvas('style image');
$border = new Border(20);
$border->draw($canvas,$brush);
$canvas->save('path to save')->show();
<?php
//11.811024
$image = imagecreatefromjpeg('test.jpg');
$rotate = imagerotate($image, 90, 0);
list($width, $height) = getimagesize('test.jpg');
// Content type
header('Content-Type: image/jpeg');
$image_p = imagecreatetruecolor($width * 11.811024, $height * 11.811024);
imagecopyresampled($image_p, $rotate, 0, 0, 0, 0, $width * 11.811024, $height * 11.811024, $width, $height);
imagejpeg($rotate);
It's not outputting any image, but when I comment out imagecreatetruecolor it does... Why? How can I fix this?
I think this could be the reason:
bool imagecopyresampled ( 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 )
Thats the function , the 1. Parameter is the destination in your case the emty picture $image_p
but you do imagejpeg($rotate);
take imagejpeg($image_p); to get the right output.
Also try to rotate it after you resampled it :)
Imagerotate rotates the image using the given angle in degrees.
The center of rotation is the center of the image, and the rotated image may have different dimensions than the original image.
How do I change the center of rotation to coordinate x_new and y_new and avoid automatic resizing?
Example: Rotation around red dot.
First idea that comes to mind is to move the image so that its new center is at x_new, y_new rotate it and move back.
assumptions:
0 < x_new < w
0 < y_new < h
Pseudocode:
new_canter_x = MAX(x_new, w - x_new)
new_center_y = MAX(y_new, h - y_new)
create new image (plain or transparent background):
width = new_canter_x * 2
height = new_center_y * 2
copy your old image to new one to coords:
new_center_x - x_new
new_center_y - y_new
imagerotate the new image.
now you just have to cut the part that you are interested in out of it.
The right way to do it is rotate and then crop with right params of transformation.
Another way is move, rotate then move again (simpler math but more code).
$x and $y are coordinates of the red dot.
private function rotateImage($image, $x, $y, $angle)
{
$widthOrig = imagesx($image);
$heightOrig = imagesy($image);
$rotatedImage = $this->createLayer($widthOrig * 2, $heightOrig * 2);
imagecopyresampled($rotatedImage, $image, $widthOrig - $x, $heightOrig - $y, 0, 0, $widthOrig, $heightOrig, $widthOrig, $heightOrig);
$rotatedImage = imagerotate($rotatedImage, $angle, imageColorAllocateAlpha($rotatedImage, 0, 0, 0, 127));
$width = imagesx($rotatedImage);
$height = imagesy($rotatedImage);
$image = $this->createLayer();
imagecopyresampled($image, $rotatedImage, 0, 0, $width / 2 - $x, $height / 2 - $y, $widthOrig, $heightOrig, $widthOrig, $heightOrig);
return $image;
}
private function createLayer($width = 1080, $height = 1080)
{
$image = imagecreatetruecolor($width, $height);
$color = imagecolorallocatealpha($image, 0, 0, 0, 127);
imagefill($image, 0, 0, $color);
return $image;
}
everything in my code is working great for creating a thumbnail image of an uploaded picture.
now all i need to do is crop the $thumb from the center of the image into a square shape (50x50)
heres my function so far
$ext = end(explode('.', $_FILES['profile_photo']['name']));
if ($ext == 'jpg' || $ext == 'jpeg' || $ext == 'png' || $ext == 'gif')
{
$tmp = $_FILES['profile_photo']['tmp_name'];
if ($ext=='jpg' || $ext=='jpeg')
$src = imagecreatefromjpeg($tmp);
else if ($ext=='png')
$src = imagecreatefrompng($tmp);
else
$src = imagecreatefromgif($tmp);
list($width,$height) = getimagesize($tmp);
$thumb_width = 50;
$thumb_height = ($height/$width) * $thumb_width;
$thumb_tmp = imagecreatetruecolor($thumb_width, $thumb_height);
$full_width = 200;
$full_height = ($height/$width) * $full_width;
$full_tmp = imagecreatetruecolor($full_width, $full_height);
imagecopyresampled($thumb_tmp, $src, 0, 0, 0, 0, $thumb_width, $thumb_height, $width, $height);
imagecopyresampled($full_tmp, $src, 0, 0, 0, 0, $full_width, $full_height, $width, $height);
imagejpeg($thumb_tmp, 'images/profile/'.$user['id'].'_'.time().'_thumb.'.$ext, 100);
imagejpeg($full_tmp, 'images/profile/'.$user['id'].'_'.time().'_full.'.$ext, 100);
imagedestroy($src);
imagedestroy($thumb_tmp);
imagedestroy($full_tmp);
// delete old image from server if it is not none.png
}
any help would be greatly appreciated! i know that it has something to do with imagecopyresampled but i can't figure out the math for the cropping from the center of the image. i want this to be my own function so please dont recommend me using other peoples classes.
Right after $full_tmp = imagecreatetruecolor($full_width, $full_height);, add...
if ($thumb_width > $thumb_height) {
$thumb_offset = array('x' => ($thumb_width/2 - 25), 'y' => 0);
} else {
$thumb_offset = array('x' => 0, 'y' => ($thumb_height/2 - 25));
}
$square_tmp = imagecreatetruecolor($thumb_width, $thumb_height);
imagecopyresampled($square_tmp, $src, 0, 0, $thumb_offset['x'], $thumb_offset['y'], 50, 50, $width, $height);
Then save and destroy the temp like the other two images.
Take a look at the parameters that should be passed to imagecopyresampled, as per the PHP manual:
imagecopyresampled ( 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 )
From the third parameter on, you basically define how a rectangle on the source image maps to a rectangle on the destination image.
So the first thing you have to do is calculate the rectanle (x, y, width and height) which defines the visible area of your original image. These will be the 5th, 6th, 9th and 10th parameters to the function, respectively.
For the destination rectangle, use 0,0 for x,y, and $thumb_width,$thumb_height for w,h, just as you are currently doing.
Here is my current code:
$image = 'img.jpg';
$source = imagecreatefromjpeg($image);
list($origWidth, $origHeight) = getimagesize($image);
$imgH = 75;
$imgW = $origWidth / $origHeight * $imgH;
$thumb = imagecreatetruecolor($imgW, $imgH);
imagecopyresampled($thumb, $source, 0, 0, 0, 0, $imgW, $imgH, $origWidth, $origHeight);
This allows me to output an image with a fixed height of 75 pixels. What I would like to do is have a constant image size of 99x75 pixels. Portrait images that don't fit into this will be cropped from the center (so the center of the original remains the center of the thumbnail - if that makes sense).
How can I do this?
Well, it's pure math. You want to achieve a 99x75 size, and you want to only cut from the width. So first, you resize to fit the height. That's what you did, but did it to fit a height of 75. Switch it to 99. Then you, check for the width to be <= 75. If it's not then you do this:
if( $imgW > 75 )
{
$diff = $imgw - 75; // this is what's extra
$srcX = ceil( $diff / 2 ); // this is where your img starts from
$imgW = 75;
}
imagecopyresampled($thumb, $source, 0, 0, $srcX, 0, $imgW, $imgH, $origWidth, $origHeight); // notice that src X changed accordingly.
So, if the width after the first "resize" is 100 and you wanted 75, you compute the diff = 25, split it by 2 and ceil it => 13, then you tell the GD function to start copying the image from 13, instead of 0, and still keep 75 height. This means it will copy from width 13 to witdh 88 => the center.
Hope this is what you wanted.
Regards,
Gabriel
define( 'THUMB_WIDTH', 99 );
define( 'THUMB_HEIGHT', 75 );
$image = imagecreatefromjpeg('img.jpg');
$thumb = imagecreatetruecolor(THUMB_WIDTH, THUMB_HEIGHT);
list($image_width, $image_height) = getimagesize($image);
$x0 = ( $image_width - THUMB_WIDTH ) / 2;
$y0 = ( $image_height - THUMB_HEIGHT ) / 2;
imagecopy(
$thumb, // resource $dst_im
$image, // resource $src_im
0, // int $dst_x
0, // int $dst_y
$x0, // int $src_x
$y0, // int $src_y
THUMB_WIDTH, // int $src_w
THUMB_HEIGHT // int $src_h
);
This code uses imagecopy function to copy 99x75px region from the source image. Source width - 99 / 2 returns the x coordinate from which to start copying, Source height - 75 / 2 returns the y coordinate. If you are interested in generating fixed size thumbnails from arbitrary size images, have a look at this article.
(untested)
define('THUMB_WIDTH', 99);
define('THUMB_HEIGHT', 75);
$image = 'img.jpg';
$source = imagecreatefromjpeg($image);
$thumb = imagecreatetruecolor(THUMB_WIDTH, THUMB_HEIGHT);
$cutX = imagesx($source) > THUMB_WIDTH;
$cutY = imagesy($source) > THUMB_HEIGHT;
$source_x = $cutX ? imagesx($source) / 2 - (THUMB_WIDTH/2) : 0;
$source_y = $cutY ? imagesx($source) / 2 - (THUMB_HEIGHT/2) : 0;
$source_width = $cutX ? THUMB_WIDTH : imagesx($source);
$source_height = $cutY ? THUMB_HEIGHT : imagesy($source);
imagecopyresampled($thumb, $source, 0, 0, $source_x, $source_y, $source_width, $source_height, THUMB_WIDTH, THUMB_HEIGHT);