Related
How to crop an image without losing its quality?
When I try to crop an image via admin panel, it works with no problems. But when I use the function "add_image_size" or "add_filter", thumbnails loss their quality.
These are the codes I tried.
set_post_thumbnail_size( 212, 159, array( 'center', 'center') );
add_image_size( 'qwqeq', 212, 159, array( 'center', 'center' ) );
add_filter('jpeg_quality', function($arg) { return 100; } );
How can I do this without using any plugin?
Here is a function to scale/crop an image using the php gd library. You can tinker with it to get it to do what you need.
function scaleMyImage($filePath, $newPath, $newSize, $crop = NULL){
$img = imagecreatefromstring(file_get_contents($filePath));
$dst_x = 0;
$dst_y = 0;
$width = imagesx($img);
$height = imagesy($img);
$newWidth = $newSize;
$newHeight = $newSize;
$aspectRatio = $width/$height;
if($width < $height){ //Portrait.
if($crop){
$newWidth = floor($width * ($newSize / $width));
$newHeight = floor($height * ($newSize / $width));
$dst_y = (floor(($newHeight - $newSize)/2)) * -1;
}else{
$newWidth = floor($width * ($newSize / $height));
$newHeight = $newSize;
$dst_x = floor(($newSize - $newWidth)/2);
}
} elseif($width > $height) { //Landscape
if($crop){
$newWidth = floor($width * ($newSize / $height));
$newHeight = floor($height * ($newSize / $height));
$dst_x = (floor(($newWidth - $newSize)/2)) * -1;
}else{
$newWidth = $newSize;
$newHeight = floor($height * ($newSize / $width));
$dst_y = floor(($newSize - $newHeight)/2);
}
}
$finalImage = imagecreatetruecolor($newSize, $newSize);
imagecopyresampled($finalImage, $img, $dst_x, $dst_y, 0, 0, $newWidth, $newHeight, $width, $height);
header('Content-Type: image/jpeg'); //<--Comment out if you want to save to file. Otherwise it will output to your browser.
imagejpeg($finalImage, $newPath, 60); //3rd param is quality. 60 does good job. You can play around.
imagedestroy($img);
imagedestroy($finalImage);
}
$filePath = 'path/to/image.jpg';
$newPath = NULL; //Set to NULL to output to browser. Otherwise set a new filepath to save.
$newSize = 400;
$crop = 1; //Set to NULL if you don't want to crop.
To use:
scaleMyImage($filePath, $newPath, $newSize, 1);
Ok so I'm trying to resize an image using php. I do not have access to install plugins on the server I use at this time.
$originalimage is the actual original image that I'm going to resize.
$width is another parameter to define $original_width. The same can be said for $height and $original_height.
$original_width = imagesx($originalimage);
$original_height = imagesy($originalimage);
$max_width = $thumbwidth;
$max_height = $thumbheight;
$width = $original_width;
$height = $original_height;
Using the pre-setup above I start to work on this one here. This works but no way to set a max height. For example I pass a max width as $thumbwidth and max height as $thumbheight and this will work as desired till I then try to go ahead and use an image that's higher than it is wide. (Portrait image.) It does not completely fail however it does fail to enforce a max height, rendering an image that can potentially be very high.
if ($width > $height) {
$newwidth = $thumbwidth;
$divisor = $width / $thumbwidth;
$newheight = floor( $height / $divisor);
} else {
$newheight = $thumbheight;
$divisor = $height / $thumbheight;
$newwidth = floor( $width / $divisor );
}
$image = imagecreatetruecolor( $newwidth, $newheight );
imagecopyresampled( $image, $originalimage, 0, 0, 0, 0, $newwidth, $newheight, $original_width, $original_height );
After trying to understand this and failing after a few hours I came up with the code below which I had gotten from php.net. As you can see there was a reason I set two sets of variables equal to each other in the pre-setup part of the code. Mostly because I can not comprehend calling $max_width as $thumbwidth in the second code segment.
This below works as well until you pass in a parameter though that is larger than the width or height of $originalimage.
# taller
if ($height > $max_height) {
$width = ($max_height / $height) * $width;
$height = $max_height;
}
# wider
if ($width > $max_width) {
$height = ($max_width / $width) * $height;
$width = $max_width;
}
$image = imagecreatetruecolor( $width, $height );
imagecopyresampled( $image, $originalimage, 0, 0, 0, 0, $width, $height, $original_width, $original_height );
I'm sorry I can't find a way to do this on my own. As for this being a duplicate question, Most similar questions end up with "[Insert plugin name here] is better use that instead." I am asking specifically for an answer that does not use other plugins or javascript. (Besides GD which is pre-installed on my server.)
Before I end this question I will say that I am using imagejpeg($image); so the use of HTML or CSS is completely forbidden.
Here's a class I whipped up for a program I worked on. maybe it will help you?
<?php
class ImageHelper
{
/**
* #static
* #param $source string Path for source image
* #param $destination string Path for destination image to be placed
* #param $targetWidth int Width of the new image (in pixels)
* #param $targetHeight int Height of the new image (in pixels)
* #param $strict bool
*/
public static function createImage($source, $destination, $targetWidth, $targetHeight, $strict = false){
$dir = dirname($destination);
if(!is_dir($dir)){
mkdir($dir, 0770, true);
}
$fileContents = file_get_contents($source);
$image = imagecreatefromstring($fileContents);
$thumbnail = ImageHelper::resizeImage($image, $targetWidth, $targetHeight, $strict);
imagejpeg($thumbnail, $destination, 100);
imagedestroy($thumbnail);
imagedestroy($image);
}
/**
* Resize an image to the specified dimensions
* #param string $original Path to the original image
* #param int $targetWidth Width of the new image (in pixels)
* #param int $targetHeight Height of the new image (in pixels)
* #param bool $strict True to crop the picture to the specified dimensions, false for best fit
* #return bool|resource Returns the new image resource or false if the image was not resized.
*/
public static function resizeImage($original, $targetWidth, $targetHeight, $strict = false)
{
$originalWidth = imagesx($original);
$originalHeight = imagesy($original);
$widthRatio = $targetWidth / $originalWidth;
$heightRatio = $targetHeight / $originalHeight;
if(($widthRatio > 1 || $heightRatio > 1) && !$strict){
// don't scale up an image if either targets are greater than the original sizes and we aren't using a strict parameter
$dstHeight = $originalHeight;
$dstWidth = $originalWidth;
$srcHeight = $originalHeight;
$srcWidth = $originalWidth;
$srcX = 0;
$srcY = 0;
}elseif ($widthRatio > $heightRatio) {
// width is the constraining factor
if ($strict) {
$dstHeight = $targetHeight;
$dstWidth = $targetWidth;
$srcHeight = $originalHeight;
$srcWidth = $heightRatio * $targetWidth;
$srcX = floor(($originalWidth - $srcWidth) / 2);
$srcY = 0;
} else {
$dstHeight = ($originalHeight * $targetWidth) / $originalWidth;
$dstWidth = $targetWidth;
$srcHeight = $originalHeight;
$srcWidth = $originalWidth;
$srcX = 0;
$srcY = 0;
}
} else {
// height is the constraining factor
if ($strict) {
$dstHeight = $targetHeight;
$dstWidth = $targetWidth;
$srcHeight = $widthRatio * $targetHeight;
$srcWidth = $originalWidth;
$srcY = floor(($originalHeight - $srcHeight) / 2);
$srcX = 0;
} else {
$dstHeight = $targetHeight;
$dstWidth = ($originalWidth * $targetHeight) / $originalHeight;
$srcHeight = $originalHeight;
$srcWidth = $originalWidth;
$srcX = 0;
$srcY = 0;
}
}
$new = imagecreatetruecolor($dstWidth, $dstHeight);
if ($new === false) {
return false;
}
imagecopyresampled($new, $original, 0, 0, $srcX, $srcY, $dstWidth, $dstHeight, $srcWidth, $srcHeight);
return $new;
}
}
You can try this function as shown below.
<?php
function makeThumbnail($sourcefile,$max_width, $max_height, $endfile, $type){
// Takes the sourcefile (path/to/image.jpg) and makes a thumbnail from it
// and places it at endfile (path/to/thumb.jpg).
// Load image and get image size.
//
switch($type){
case'image/png':
$img = imagecreatefrompng($sourcefile);
break;
case'image/jpeg':
$img = imagecreatefromjpeg($sourcefile);
break;
case'image/gif':
$img = imagecreatefromgif($sourcefile);
break;
default :
return 'Un supported format';
}
$width = imagesx( $img );
$height = imagesy( $img );
if ($width > $height) {
if($width < $max_width)
$newwidth = $width;
else
$newwidth = $max_width;
$divisor = $width / $newwidth;
$newheight = floor( $height / $divisor);
}
else {
if($height < $max_height)
$newheight = $height;
else
$newheight = $max_height;
$divisor = $height / $newheight;
$newwidth = floor( $width / $divisor );
}
// Create a new temporary image.
$tmpimg = imagecreatetruecolor( $newwidth, $newheight );
imagealphablending($tmpimg, false);
imagesavealpha($tmpimg, true);
// Copy and resize old image into new image.
imagecopyresampled( $tmpimg, $img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
// Save thumbnail into a file.
//compressing the file
switch($type){
case'image/png':
imagepng($tmpimg, $endfile, 0);
break;
case'image/jpeg':
imagejpeg($tmpimg, $endfile, 100);
break;
case'image/gif':
imagegif($tmpimg, $endfile, 0);
break;
}
// release the memory
imagedestroy($tmpimg);
imagedestroy($img);
}
?>
The function has five parameters.
> $sourcefile - Specicifies the temporary location of your image file
> $max_width - Specifies the possible maximum width
> $max_height - Specifies the possible maximum width
> $endfile - Specifies the directory to save the image
> $type - Specifies the image file type
Download demo code here
I've had a very similar problem building the thumbs for a gallery page. I tried Daniel Nyamasyo solution above but just could not get past the "$img = imagecreatefromjpeg($sourcefile);" line without getting "Warning: imagecreatefromjpeg failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request" no matter what $sourcefile I fed it.
I came up with this dirty method.
<?php
// Some variables
$thumb_width = 162; // The maximum values you want
$thumb_height = 122;
$thumb_pointer = 'thumbs'; // Put your output folder here which must exist
$img = imagecreatefromjpeg( $image_name);
$width = imagesx( $img );
$height = imagesy( $img );
if ($width>=$height)
{
// Now calculate thumbnail size
$new_width = $thumb_width;
$new_height = floor( $height * ($thumb_width / $width));
// The 'dirty' bit I found was needed for square or near square images
while ($new_height > $thumb_height)
{
$new_width = floor($new_width * 0.99);
$new_height = floor($new_height * 0.99);
}
}
else
{
$new_height = $thumb_height;
$new_width = floor($width * ($thumb_height / $height));
}
// Create a new temporary image
$tmp_img = imagecreatetruecolor( $new_width, $new_height );
// Copy and resize old image into new image
imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );
// Save the thumbnail into a file
imagejpeg( $tmp_img, $thumb_pointer.'/'.$image_name);
?>
I use imagick for thumbnail crop, but sometimes cropped thumbnails are missing top part of the images (hair, eyes).
I was thinking to resize the image then crop it. Also, I need to keep the image size ratio.
Below is the php script I use for crop:
$im = new imagick( "img/20130815233205-8.jpg" );
$im->cropThumbnailImage( 80, 80 );
$im->writeImage( "thumb/th_80x80_test.jpg" );
echo '<img src="thumb/th_80x80_test.jpg">';
Thanks..
This task is not easy as the "important" part may not always be at the same place. Still, using something like this
$im = new imagick("c:\\temp\\523764_169105429888246_1540489537_n.jpg");
$imageprops = $im->getImageGeometry();
$width = $imageprops['width'];
$height = $imageprops['height'];
if($width > $height){
$newHeight = 80;
$newWidth = (80 / $height) * $width;
}else{
$newWidth = 80;
$newHeight = (80 / $width) * $height;
}
$im->resizeImage($newWidth,$newHeight, imagick::FILTER_LANCZOS, 0.9, true);
$im->cropImage (80,80,0,0);
$im->writeImage( "D:\\xampp\\htdocs\\th_80x80_test.jpg" );
echo '<img src="th_80x80_test.jpg">';
(tested)
should work. The cropImage parameters (0 and 0) determine the upper left corner of the cropping area. So playing with these gives you differnt results of what stays in the image.
Based on Martin's answer I made a more general function that resizes and crops Imagick image to fit given width and height (i.e. behaves exactly as CSS background-size: cover declaration):
/**
* Resizes and crops $image to fit provided $width and $height.
*
* #param \Imagick $image
* Image to change.
* #param int $width
* New desired width.
* #param int $height
* New desired height.
*/
function image_cover(Imagick $image, $width, $height) {
$ratio = $width / $height;
// Original image dimensions.
$old_width = $image->getImageWidth();
$old_height = $image->getImageHeight();
$old_ratio = $old_width / $old_height;
// Determine new image dimensions to scale to.
// Also determine cropping coordinates.
if ($ratio > $old_ratio) {
$new_width = $width;
$new_height = $width / $old_width * $old_height;
$crop_x = 0;
$crop_y = intval(($new_height - $height) / 2);
}
else {
$new_width = $height / $old_height * $old_width;
$new_height = $height;
$crop_x = intval(($new_width - $width) / 2);
$crop_y = 0;
}
// Scale image to fit minimal of provided dimensions.
$image->resizeImage($new_width, $new_height, imagick::FILTER_LANCZOS, 0.9, true);
// Now crop image to exactly fit provided dimensions.
$image->cropImage($new_width, $new_height, $crop_x, $crop_y);
}
Hope this may help somebody.
My code. Please vote
// Imagick
$image = new Imagick($img);
// method 1 - resize to max width
if($type==1){
$image->resizeImage($newWidth,0,Imagick::FILTER_LANCZOS,1);
// method 2 - resize to max height
}else if($type==2){
$image->resizeImage(0,$newHeight,Imagick::FILTER_LANCZOS,1);
// method 1 - resize to max width or height
}else if($type==3){
if($image->getImageHeight() <= $image->getImageWidth()){
$image->resizeImage($newWidth,0,Imagick::FILTER_LANCZOS,1);
}else{
$image->resizeImage(0,$newHeight,Imagick::FILTER_LANCZOS,1);
}
// method 4 - resize and crop to center
}else if($type==4){
if($image->getImageHeight() <= $image->getImageWidth()){
$image->resizeImage(0,$newheight,Imagick::FILTER_LANCZOS,1);
}else{
$image->resizeImage($newwidth,0,Imagick::FILTER_LANCZOS,1);
}
$cropWidth = $image->getImageWidth();
$cropHeight = $image->getImageHeight();
$image->cropimage(
$newwidth,
$newheight,
($cropWidth - $newwidth) / 2,
($cropHeight - $newheight) / 2
);
}
$image->setImageFormat("jpeg");
$image->setImageCompression(Imagick::COMPRESSION_JPEG);
$image->writeImages($newImg, true);
$image->clear();
$image->destroy();
I have a function created which processes images in different ways based on the parameters. I have comments in the function to explain a bit.
Everything works with exception to when I take a jpg image and save it as a png. I just checked, even if I use imagepng() but save it with the extension .jpg, the image displays while properly resized, but with a .jpg extension. However, if I upload the same .jpg image, use imagepng() and save it with a .png extension, I get an image of the expected width and height after the resize, in a png format, with a .png extension. While the whole image is 100% transparent I have a 1px by 1px black pixel in the top left corner.
I would appreciate it if anyone can look at this and see if they see something I am missing. I believe the 1px X 1px is coming from the point I use for the imagefill(), but I don't understand why; it should be filling all transparent as with the rest of the image.
Here is my function:
if(!function_exists("upload")){
//$image = $image file name
//$width = intended width of resized image, if 0 it will proportion to height, overrides proportion
//$height = intended width of resized image, if 0 it will proportion to width, overrides proportion
//$proportion = 2,1,0;
//------ 2 = Preserve proportions while adding a border to fill width and height
//------ 1 = retain proportion to fit within both given width and height
//------ 0 = disregard proportions and resize to the exact width and height
function upload($image, $width, $height, $proportion){
// IS GD HERE?
$gdv = get_gd_info();
if (!$gdv){
return FALSE;
}
// GET AN IMAGE THING
$ext = trim(strtolower(end(explode('.', $image))));
list($imageX, $imageY, $type) = getimagesize($image); //gets information about new server image
// GET THE LESSER OF THE RATIO OF THUMBNAIL H OR W DIMENSIONS
$ratio_w = ($width / $imageX);
$ratio_h = ($height / $imageY);
$ratio = ($ratio_w < $ratio_h) ? $ratio_w : $ratio_h;
if($width == 0){
if($imageY > $height){
$newHeight = $height;
$newWidth = ($height/$imageY) * $imageX;
}else{
$newHeight = $imageY;
$newWidth = $imageX;
}
$width = $newWidth;
$height = $newHeight;
// COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
$fromMidX = 0;
$fromMidY = 0;
}elseif($height == 0){
if ($imageX > $width){
$newWidth = $width;
$newHeight = ($width/$imageX) * $imageY;
}else{
$newHeight = $imageY;
$newWidth = $imageX;
}
$width = $newWidth;
$height = $newHeight;
// COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
$fromMidX = 0;
$fromMidY = 0;
}elseif($proportion == 2){
// COMPUTE THUMBNAIL IMAGE DIMENSIONS
$newWidth = $imageX * $ratio;
$newHeight = $imageY * $ratio;
// COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
$fromMidX = ($width - $newWidth) / 2.0;
$fromMidY = ($height - $newHeight) / 2.0;
}elseif($proportion == 1){
if ($imageX > $width){
$newHeight = ($width/$imageX) * $imageY;
$newWidth = $width;
}
if ($imageY > $height){
$newHeight = $height;
$newWidth = ($height/$imageY) * $imageX;
}
$fromMidY = 0;
$fromMidX = 0;
}elseif($proportion == 0){
$newWidth = $width;
$newHeight = $height;
$fromMidY = 0;
$fromMidX = 0;
}
switch(strtoupper($ext))
{
case 'JPG' :
case 'JPEG' :
$source = imagecreatefromjpeg($image);
break;
case 'PNG' :
$source = imagecreatefrompng($image);
break;
default : die("UNKNOWN IMAGE TYPE: $image");
}
// WHICH FUNCTIONS CAN RESIZE / RESAMPLE THE IMAGE?
if ($gdv >= 2)
{
// IF GD IS AT LEVEL 2 OR ABOVE
$target = imagecreatetruecolor($width, $height);
$color = imagecolorallocatealpha($target, 0, 0, 0, 127);
imagefill($target, 0, 0, $color);
imagesavealpha($target, TRUE);
imagecopyresampled ($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);
}
else
{
// IF GD IS AT A LOWER REVISION LEVEL
$target = imagecreate($width, $height);
imagesavealpha($target, TRUE);
$empty = imagecolorallocatealpha($thumb,0x00,0x00,0x00,127);
imagefill($target, 0, 0, $empty);
imagecopyresized($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);
}
// SHARPEN THE PIC
$sharpenMatrix = array
( array( -1.2, -1, -1.2 )
, array( -1, 20, -1 )
, array( -1.2, -1, -1.2 )
)
;
$divisor = array_sum(array_map('array_sum', $sharpenMatrix));
$offset = 0;
imageconvolution($target, $sharpenMatrix, $divisor, $offset);
if(imagepng($target, $image,9)){
imagedestroy($target);
}else{
}
return $image;
}
}
EDIT 1: I guess I should have noted that I am uploading a .jpg image (Ex: 100px X 200px) and converting them to .png (Ex: 400px X 200px) but am retaining the proportions of the image to fit perfectly in the center of the destination .png. So I would have a 400px X 200px .png with my image in the center and 100px on the left and right which should be transparent. This way it fits nicely in a slider without a solid color as a fill. So an example of my call to my function would be upload($image, 400, 200, 2).
I figured out what the issue was. The portion of code which decides whether I should use imagecreatefromjpeg or imagecreatefrompng was incorrectly going off of the extension of the passed image and NOT by its mime type. I switched it to this:
switch($type)
{
case '2' :
$source = imagecreatefromjpeg($image);
break;
case '3' :
$source = imagecreatefrompng($image);
break;
default : die("UNKNOWN IMAGE TYPE: $image");
}
where $type is coming from the line I had in there
list($imageX, $imageY, $type) = getimagesize($image);
So all together the function is:
if(!function_exists("upload")){
//$image = $image file name
//$width = intended width of resized image, if 0 it will proportion to height, overrides proportion
//$height = intended width of resized image, if 0 it will proportion to width, overrides proportion
//$proportion = 2,1,0;
//------ 2 = Preserve proportions while adding a border to fill width and height
//------ 1 = retain proportion to fit within both given width and height
//------ 0 = disregard proportions and resize to the exact width and height
function upload($image, $width, $height, $proportion){
// IS GD HERE?
$gdv = get_gd_info();
if (!$gdv){
return FALSE;
}
// GET AN IMAGE THING
$ext = trim(strtolower(end(explode('.', $image))));
list($imageX, $imageY, $type) = getimagesize($image); //gets information about new server image
// GET THE LESSER OF THE RATIO OF THUMBNAIL H OR W DIMENSIONS
$ratio_w = ($width / $imageX);
$ratio_h = ($height / $imageY);
$ratio = ($ratio_w < $ratio_h) ? $ratio_w : $ratio_h;
if($width == 0){
if($imageY > $height){
$newHeight = $height;
$newWidth = ($height/$imageY) * $imageX;
}else{
$newHeight = $imageY;
$newWidth = $imageX;
}
$width = $newWidth;
$height = $newHeight;
// COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
$fromMidX = 0;
$fromMidY = 0;
}elseif($height == 0){
if ($imageX > $width){
$newWidth = $width;
$newHeight = ($width/$imageX) * $imageY;
}else{
$newHeight = $imageY;
$newWidth = $imageX;
}
$width = $newWidth;
$height = $newHeight;
// COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
$fromMidX = 0;
$fromMidY = 0;
}elseif($proportion == 2){
// COMPUTE THUMBNAIL IMAGE DIMENSIONS
$newWidth = $imageX * $ratio;
$newHeight = $imageY * $ratio;
// COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
$fromMidX = ($width - $newWidth) / 2.0;
$fromMidY = ($height - $newHeight) / 2.0;
}elseif($proportion == 1){
if ($imageX > $width){
$newHeight = ($width/$imageX) * $imageY;
$newWidth = $width;
}
if ($imageY > $height){
$newHeight = $height;
$newWidth = ($height/$imageY) * $imageX;
}
$fromMidY = 0;
$fromMidX = 0;
}elseif($proportion == 0){
$newWidth = $width;
$newHeight = $height;
$fromMidY = 0;
$fromMidX = 0;
}
switch($type)
{
case '2' :
$source = imagecreatefromjpeg($image);
break;
case '3' :
$source = imagecreatefrompng($image);
break;
default : die("UNKNOWN IMAGE TYPE: $image");
}
// WHICH FUNCTIONS CAN RESIZE / RESAMPLE THE IMAGE?
if ($gdv >= 2)
{
// IF GD IS AT LEVEL 2 OR ABOVE
$target = imagecreatetruecolor($width, $height);
$color = imagecolorallocatealpha($target, 0, 0, 0, 127);
imagefill($target, 0, 0, $color);
imagesavealpha($target, TRUE);
imagecopyresampled ($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);
}
else
{
// IF GD IS AT A LOWER REVISION LEVEL
$target = imagecreate($width, $height);
imagesavealpha($target, TRUE);
$empty = imagecolorallocatealpha($thumb,0x00,0x00,0x00,127);
imagefill($target, 0, 0, $empty);
imagecopyresized($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);
}
// SHARPEN THE PIC
$sharpenMatrix = array
( array( -1.2, -1, -1.2 )
, array( -1, 20, -1 )
, array( -1.2, -1, -1.2 )
)
;
$divisor = array_sum(array_map('array_sum', $sharpenMatrix));
$offset = 0;
imageconvolution($target, $sharpenMatrix, $divisor, $offset);
if(imagepng($target, $image,9)){
imagedestroy($target);
}
return $image;
}
}
And an example call would be: upload("path/to/image/on/server.png", 400, 200, 2)
Where the image path can be either in a jpg or png mime type. But the extension MUST be .png. I suppose I can make it smarter where you can have any extension, but with the current code which uses this function it makes more sense for me to leave it as is. I would like to eventually add the option to turn on or off the transparency and instead use a solid color such as black if it is needed. Feel free to use and modify this.
There are nice hex2rgb/rgb2hex functions which I plan on using for this here
The code below crops the image well, which is what i want, but for larger images, it wotn work as well. Is there any way of 'zooming out of the image'
Idealy i would be able to have each image roughly the same size before cropping so that i would get good results each time
Code is
<?php
$image = $_GET['src']; // the image to crop
$dest_image = 'images/cropped_whatever.jpg'; // make sure the directory is writeable
$img = imagecreatetruecolor('200','150');
$org_img = imagecreatefromjpeg($image);
$ims = getimagesize($image);
imagecopy($img,$org_img, 0, 0, 20, 20, 200, 150);
imagejpeg($img,$dest_image,90);
imagedestroy($img);
echo '<img src="'.$dest_image.'" ><p>';
If you are trying to generate thumbnails, you must first resize the image using imagecopyresampled();. You must resize the image so that the size of the smaller side of the image is equal to the corresponding side of the thumb.
For example, if your source image is 1280x800px and your thumb is 200x150px, you must resize your image to 240x150px and then crop it to 200x150px. This is so that the aspect ratio of the image won't change.
Here's a general formula for creating thumbnails:
$image = imagecreatefromjpeg($_GET['src']);
$filename = 'images/cropped_whatever.jpg';
$thumb_width = 200;
$thumb_height = 150;
$width = imagesx($image);
$height = imagesy($image);
$original_aspect = $width / $height;
$thumb_aspect = $thumb_width / $thumb_height;
if ( $original_aspect >= $thumb_aspect )
{
// If image is wider than thumbnail (in aspect ratio sense)
$new_height = $thumb_height;
$new_width = $width / ($height / $thumb_height);
}
else
{
// If the thumbnail is wider than the image
$new_width = $thumb_width;
$new_height = $height / ($width / $thumb_width);
}
$thumb = imagecreatetruecolor( $thumb_width, $thumb_height );
// Resize and crop
imagecopyresampled($thumb,
$image,
0 - ($new_width - $thumb_width) / 2, // Center the image horizontally
0 - ($new_height - $thumb_height) / 2, // Center the image vertically
0, 0,
$new_width, $new_height,
$width, $height);
imagejpeg($thumb, $filename, 80);
Haven't tested this but it should work.
EDIT
Now tested and working.
imagecopyresampled() will take a rectangular area from $src_image of width $src_w and height $src_h at position ($src_x, $src_y) and place it in a rectangular area of $dst_image of width $dst_w and height $dst_h at position ($dst_x, $dst_y).
If the source and destination coordinates and width and heights differ, appropriate stretching or shrinking of the image fragment will be performed. The coordinates refer to the upper left corner.
This function can be used to copy regions within the same image. But if the regions overlap, the results will be unpredictable.
- Edit -
If $src_w and $src_h are smaller than $dst_w and $dst_h respectively, thumb image will be zoomed in. Otherwise it will be zoomed out.
<?php
$dst_x = 0; // X-coordinate of destination point
$dst_y = 0; // Y-coordinate of destination point
$src_x = 100; // Crop Start X position in original image
$src_y = 100; // Crop Srart Y position in original image
$dst_w = 160; // Thumb width
$dst_h = 120; // Thumb height
$src_w = 260; // Crop end X position in original image
$src_h = 220; // 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('images/source.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');
?>
php 5.5 has an imagecrop function http://php.net/manual/en/function.imagecrop.php
$image = imagecreatefromjpeg($_GET['src']);
Needs to be replaced with this:
$image = imagecreatefromjpeg('images/thumbnails/myimage.jpg');
Because imagecreatefromjpeg() is expecting a string.
This worked for me.
ref:
http://php.net/manual/en/function.imagecreatefromjpeg.php
HTML Code:-
enter code here
<!DOCTYPE html>
<html>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" name="image" id="fileToUpload">
<input type="submit" value="Upload Image" name="submit">
</form>
</body>
</html>
upload.php
enter code here
<?php
$image = $_FILES;
$NewImageName = rand(4,10000)."-". $image['image']['name'];
$destination = realpath('../images/testing').'/';
move_uploaded_file($image['image']['tmp_name'], $destination.$NewImageName);
$image = imagecreatefromjpeg($destination.$NewImageName);
$filename = $destination.$NewImageName;
$thumb_width = 200;
$thumb_height = 150;
$width = imagesx($image);
$height = imagesy($image);
$original_aspect = $width / $height;
$thumb_aspect = $thumb_width / $thumb_height;
if ( $original_aspect >= $thumb_aspect )
{
// If image is wider than thumbnail (in aspect ratio sense)
$new_height = $thumb_height;
$new_width = $width / ($height / $thumb_height);
}
else
{
// If the thumbnail is wider than the image
$new_width = $thumb_width;
$new_height = $height / ($width / $thumb_width);
}
$thumb = imagecreatetruecolor( $thumb_width, $thumb_height );
// Resize and crop
imagecopyresampled($thumb,
$image,
0 - ($new_width - $thumb_width) / 2, // Center the image horizontally
0 - ($new_height - $thumb_height) / 2, // Center the image vertically
0, 0,
$new_width, $new_height,
$width, $height);
imagejpeg($thumb, $filename, 80);
echo "cropped"; die;
?>
Improved Crop image functionality in PHP on the fly.
http://www.example.com/cropimage.php?filename=a.jpg&newxsize=100&newysize=200&constrain=1
Code in cropimage.php
$basefilename = #basename(urldecode($_REQUEST['filename']));
$path = 'images/';
$outPath = 'crop_images/';
$saveOutput = false; // true/false ("true" if you want to save images in out put folder)
$defaultImage = 'no_img.png'; // change it with your default image
$basefilename = $basefilename;
$w = $_REQUEST['newxsize'];
$h = $_REQUEST['newysize'];
if ($basefilename == "") {
$img = $path . $defaultImage;
$percent = 100;
} else {
$img = $path . $basefilename;
$len = strlen($img);
$ext = substr($img, $len - 3, $len);
$img2 = substr($img, 0, $len - 3) . strtoupper($ext);
if (!file_exists($img)) $img = $img2;
if (file_exists($img)) {
$percent = #$_GET['percent'];
$constrain = #$_GET['constrain'];
$w = $w;
$h = $h;
} else if (file_exists($path . $basefilename)) {
$img = $path . $basefilename;
$percent = $_GET['percent'];
$constrain = $_GET['constrain'];
$w = $w;
$h = $h;
} else {
$img = $path . 'no_img.png'; // change with your default image
$percent = #$_GET['percent'];
$constrain = #$_GET['constrain'];
$w = $w;
$h = $h;
}
}
// get image size of img
$x = #getimagesize($img);
// image width
$sw = $x[0];
// image height
$sh = $x[1];
if ($percent > 0) {
// calculate resized height and width if percent is defined
$percent = $percent * 0.01;
$w = $sw * $percent;
$h = $sh * $percent;
} else {
if (isset ($w) AND !isset ($h)) {
// autocompute height if only width is set
$h = (100 / ($sw / $w)) * .01;
$h = #round($sh * $h);
} elseif (isset ($h) AND !isset ($w)) {
// autocompute width if only height is set
$w = (100 / ($sh / $h)) * .01;
$w = #round($sw * $w);
} elseif (isset ($h) AND isset ($w) AND isset ($constrain)) {
// get the smaller resulting image dimension if both height
// and width are set and $constrain is also set
$hx = (100 / ($sw / $w)) * .01;
$hx = #round($sh * $hx);
$wx = (100 / ($sh / $h)) * .01;
$wx = #round($sw * $wx);
if ($hx < $h) {
$h = (100 / ($sw / $w)) * .01;
$h = #round($sh * $h);
} else {
$w = (100 / ($sh / $h)) * .01;
$w = #round($sw * $w);
}
}
}
$im = #ImageCreateFromJPEG($img) or // Read JPEG Image
$im = #ImageCreateFromPNG($img) or // or PNG Image
$im = #ImageCreateFromGIF($img) or // or GIF Image
$im = false; // If image is not JPEG, PNG, or GIF
if (!$im) {
// We get errors from PHP's ImageCreate functions...
// So let's echo back the contents of the actual image.
readfile($img);
} else {
// Create the resized image destination
$thumb = #ImageCreateTrueColor($w, $h);
// Copy from image source, resize it, and paste to image destination
#ImageCopyResampled($thumb, $im, 0, 0, 0, 0, $w, $h, $sw, $sh);
//Other format imagepng()
if ($saveOutput) { //Save image
$save = $outPath . $basefilename;
#ImageJPEG($thumb, $save);
} else { // Output resized image
header("Content-type: image/jpeg");
#ImageJPEG($thumb);
}
}
You can use imagecrop function in (PHP 5 >= 5.5.0, PHP 7)
Example:
<?php
$im = imagecreatefrompng('example.png');
$size = min(imagesx($im), imagesy($im));
$im2 = imagecrop($im, ['x' => 0, 'y' => 0, 'width' => $size, 'height' => $size]);
if ($im2 !== FALSE) {
imagepng($im2, 'example-cropped.png');
imagedestroy($im2);
}
imagedestroy($im);
?>
$image = imagecreatefromjpeg($_GET['src']);
$filename = 'images/cropped_whatever.jpg'
Must be replaced with:
$image = imagecreatefromjpeg($_GET['src']);
Then it will work!