I have a function that I'm using to accept user-uploaded images, proportionally scale it to a have a maximum width/height of 4,000px, and also generate 400px and 800px thumbnails. It needs to be capable of handling transparent PNGs and applying a white background.
My current code does all of this, however, it adds undesirable artifacts not typical of JPEGs. They're vertical striations and look like a very washed out barcode when viewed close up (400% Zoomed Screenshot attached). This even occurs on the original image when uploaded at the size it's being scaled to. It seems to be even more prevalent with transparent PNGs, but happens in white regions of JPEGs as well. JPEGs are being saved with Quality 80.
function resize_image($file, $w, $h, $strict = false, $crop = false, $path = null, $thumbnail = false)
{
// Check for Valid Image + Calculate Ratio
list($width, $height) = getimagesize($file);
if (empty($width) || empty($height))
{
echo json_encode(['result' => 'error', 'error' => 'file_format_invalid']);
http_response_code(405);
exit;
}
$r = $width / $height;
if (!$strict)
{
$w = min($w, $width);
$h = min($h, $height);
}
$wTa = min($w, 400);
$hTa = min($h, 400);
$wTb = min($w, 800);
$hTb = min($h, 800);
// Apply Crop Constraint
if ($crop)
{
if ($width > $height)
{
$width = ceil($width - ($width * abs($r - $w / $h)));
$widthTa = ceil($width - ($width * abs($r - $wTa / $hTa)));
$widthTb = ceil($width - ($width * abs($r - $wTb / $hTb)));
}
else
{
$height = ceil($height - ($height * abs($r - $w / $h)));
$heightTa = ceil($height - ($height * abs($r - $wTa / $hTa)));
$heightTb = ceil($height - ($height * abs($r - $wTa / $hTb)));
}
$newWidth = $w;
$newHeight = $h;
}
else
{
if ($w / $h > $r || $r < 1)
{
$newWidth = $h * $r;
$newWidthTa = $hTa * $r;
$newWidthTb = $hTb * $r;
$newHeight = $h;
$newHeightTa = $hTa;
$newHeightTb = $hTb;
}
else
{
$newHeight = $w / $r;
$newHeightTa = $wTa / $r;
$newHeightTb = $wTb / $r;
$newWidth = $w;
$newWidthTa = $wTa;
$newWidthTb = $wTb;
}
}
// Create, Resample + Return Image
$src = imagecreatefromstring(file_get_contents($file));
$dst = imagecreatetruecolor($newWidth, $newHeight);
$fff = imagecolorallocate($dst, 255, 255, 255);
imagefill($dst, 0, 0, $fff);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
if (!is_null($path))
{
imagejpeg($dst, $path, 80);
if ($thumbnail)
{
$dstThumbA = imagecreatetruecolor($newWidthTa, $newHeightTa);
$dstThumbB = imagecreatetruecolor($newWidthTb, $newHeightTb);
$fffThumbA = imagecolorallocate($dstThumbA, 255, 255, 255);
$fffThumbB = imagecolorallocate($dstThumbB, 255, 255, 255);
imagefill($dstThumbA, 0, 0, $fffThumbA);
imagefill($dstThumbB, 0, 0, $fffThumbB);
imagecopyresampled($dstThumbA, $src, 0, 0, 0, 0, $newWidthTa, $newHeightTa, $width, $height);
imagecopyresampled($dstThumbB, $src, 0, 0, 0, 0, $newWidthTb, $newHeightTb, $width, $height);
imagejpeg($dstThumbA, str_replace('.jpg', '-thumb.jpg', $path), 80);
imagejpeg($dstThumbB, str_replace('.jpg', '-thumb#2x.jpg', $path), 80);
}
}
return $dst;
}
I concluded that the issue is specific to the environment (occurs on PHP 7.1.3 under Ubuntu, but not under PHP 7.0.1 on Windows). Reinstalling php7.1 and php7.1-gd had no effect.
Ultimately I decided to bite the bullet and rewrite with ImageMagick, resulting in a much more concise block of code:
$magickSource = new Imagick();
$magickSource->readImageBlob(file_get_contents($file));
$magickSource = $magickSource->flattenImages();
$magickFull = clone $magickSource;
$magickFull->resizeImage(min($originalWidth, $newWidth), min($originalHeight, $newHeight), Imagick::FILTER_LANCZOS, 1, true);
$magickFull->setImageCompression(Imagick::COMPRESSION_JPEG);
$magickFull->setImageCompressionQuality(75);
$magickFull->stripImage();
$magickFull->writeImage($path);
$magickFull->destroy();
if ($thumbnail)
{
$magickThumb = clone $magickSource;
$magickThumb->resizeImage(min($originalWidth, 400), min($originalHeight, 400), Imagick::FILTER_LANCZOS, 1, true);
$magickThumb->setImageCompression(Imagick::COMPRESSION_JPEG);
$magickThumb->setImageCompressionQuality(75);
$magickThumb->stripImage();
$magickThumb->writeImage(str_replace('.jpg', '-thumb.jpg', $path));
$magickThumb->destroy();
}
The calls to setImageCompression(), setImageCompressionQuality, and stripImage() yielded a 53% reduction in combined filesizes. (Source)
Related
Original Image:
Desired output: (I added black border for the sack of understanding)
I want to resize image to 200/200 without cropping. See the desired output.
I have this code
<?php
// function created by www.thewebhelp.com
if (!function_exists("create_square_image")) {
function create_square_image($original_file, $destination_file = NULL, $square_size = 96) {
if (isset($destination_file) and $destination_file != NULL) {
if (!is_writable($destination_file)) {
echo '<p style="color:#FF0000">Oops, the destination path is not writable. Make that file or its parent folder wirtable.</p>';
}
}
// get width and height of original image
$imagedata = getimagesize($original_file);
$original_width = $imagedata[0];
$original_height = $imagedata[1];
if ($original_width > $original_height) {
$new_height = $square_size;
$new_width = $new_height * ($original_width / $original_height);
}
if ($original_height > $original_width) {
$new_width = $square_size;
$new_height = $new_width * ($original_height / $original_width);
}
if ($original_height == $original_width) {
$new_width = $square_size;
$new_height = $square_size;
}
$new_width = round($new_width);
$new_height = round($new_height);
// load the image
if (substr_count(strtolower($original_file), ".jpg") or substr_count(strtolower($original_file), ".jpeg")) {
$original_image = imagecreatefromjpeg($original_file);
}
if (substr_count(strtolower($original_file), ".gif")) {
$original_image = imagecreatefromgif($original_file);
}
if (substr_count(strtolower($original_file), ".png")) {
$original_image = imagecreatefrompng($original_file);
}
$smaller_image = imagecreatetruecolor($new_width, $new_height);
$square_image = imagecreatetruecolor($square_size, $square_size);
imagecopyresampled($smaller_image, $original_image, 0, 0, 0, 0, $new_width, $new_height, $original_width, $original_height);
if ($new_width > $new_height) {
$difference = $new_width - $new_height;
$half_difference = round($difference / 2);
imagecopyresampled($square_image, $smaller_image, 0 - $half_difference + 1, 0, 0, 0, $square_size + $difference, $square_size, $new_width, $new_height);
}
if ($new_height > $new_width) {
$difference = $new_height - $new_width;
$half_difference = round($difference / 2);
imagecopyresampled($square_image, $smaller_image, 0, 0 - $half_difference + 1, 0, 0, $square_size, $square_size + $difference, $new_width, $new_height);
}
if ($new_height == $new_width) {
imagecopyresampled($square_image, $smaller_image, 0, 0, 0, 0, $square_size, $square_size, $new_width, $new_height);
}
// if no destination file was given then display a png
if (!$destination_file) {
imagepng($square_image, NULL, 9);
}
// save the smaller image FILE if destination file given
if (substr_count(strtolower($destination_file), ".jpg")) {
imagejpeg($square_image, $destination_file, 100);
}
if (substr_count(strtolower($destination_file), ".gif")) {
imagegif($square_image, $destination_file);
}
if (substr_count(strtolower($destination_file), ".png")) {
imagepng($square_image, $destination_file, 9);
}
imagedestroy($original_image);
imagedestroy($smaller_image);
imagedestroy($square_image);
}
}
create_square_image("image.jpg", "sample_thumb.jpg", 200);
?>
<h2>Original image</h2>
<h2><img src="image.jpg" />
</h2>
<h2>The created square thumbnail</h2>
<h2><img src="sample_thumb.jpg" />
</h2>
But my code is outputting like this
How about using a white image that matches your dimensions? I.e you get a white image that is your desired size (200x200) and merge it with your other image.
// First image is the white image that has the dimension you want.
$image1 = imagecreatefrompng('COLOR.png');
// Second image is the image you want to change size of
$image2 = imagecreatefrompng('SOURCE.png');
// Merge the two, so that the white image is below the "Dress"
// image you showed us in your question.
imagecopymerge($image1, $image2, 0, 0, 0, 0, 161, 200, 100);
// Output and free from memory
header('Content-Type: image/png');
echo imagepng($image1);
// Destroy images
imagedestroy($image1);
imagedestroy($image2);
Parameters for the function:
bool imagecopymerge ( resource $dst_im , resource $src_im , int $dst_x
, int $dst_y , int $src_x , int $src_y , int $src_w , int $src_h , int
$pct )
Last parameter is percentage(alpha) so if you don't want a white backround then you just set it to 0, and it will be transparent.
EDIT: Check out the docs so that you get the correct position for the second image here.
EDIT 2: The above code will produce the following image(provided the color image is black):
I have found the solution that works for both situation whether image is wide or tall.
$whereToPut = "source.jpg"; // This is 200/200 blank white image
$size = getimagesize($fn);
$ratio = $size[0] / $size[1]; // width/height
$dst_y = 0;
$dst_x = 0;
if ($ratio > 1) {
$width = 200;
$height = 200 / $ratio;
$dst_y = (200 - $height) / 2;
} else {
$width = 200 * $ratio;
$height = 200;
$dst_x = (200 - $width) / 2;
}
$src = imagecreatefromstring(file_get_contents($fn));
$dst = imagecreatetruecolor($width, $height);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $width, $height, $size[0], $size[1]);
$image1 = imagecreatefromjpeg($whereToPut);
imagecopymerge($image1, $dst, $dst_x, $dst_y, 0, 0, imagesx($dst), imagesy($dst), 100);
imagejpeg($image1, $finalImage);
// $dinalImage is your final created image.
I've got the following piece of code:
$biggest = ($width > $height) ? $width : $height;
$newWidth = 0;
$newHeight = 0;
if($biggest > $divSize){
echo "BIGGEST<br />";
$scale = $divSize/$biggest;
$newWidth = floor($width * $scale);
$newHeight = floor($height * $scale);
} else if($biggest < $divSize){
echo "DIVSIZE<br />";
$scale = $biggest/$divSize;
$newWidth = floor($width * $scale);
$newHeight = floor($height * $scale);
}
echo "SCALE: ".$scale."<br />";
echo "BIGGEST: ".$biggest."<br />";
echo "WIDTH: ".$width."<br />";
echo "HEIGHT: ".$height."<br />";
echo "NEWWIDTH: ".$newWidth."<br />";
echo "NEWHEIGHT: ".$newHeight."<br />";
$sourceImage = imagecreatefromstring(file_get_contents($fileName));
$thumb = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresampled($thumb, $sourceImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
imagedestroy($sourceImage);
This piece of code works fine for some images but not for all of them.
I've got a div with the dimension of 64 by 64.
For some images they scale perfectly fine but for some images the height of the outputted image is also 64px what should by for example 32px.
I don't have a clue what's causing this problem.
If you need more information, please ask.
Your function is good but sometimes your image should have a static size (this avoid to break design on some web pages).
In such a case, you can use this function. It resizes an image fit inside a defined width / height, and if the image has not the same proportions as the required thumbnail's, unused free space is set transparent.
function resizePreservingAspectRatio($img, $targetWidth, $targetHeight)
{
$srcWidth = imagesx($img);
$srcHeight = imagesy($img);
// Determine new width / height preserving aspect ratio
$srcRatio = $srcWidth / $srcHeight;
$targetRatio = $targetWidth / $targetHeight;
if (($srcWidth <= $targetWidth) && ($srcHeight <= $targetHeight))
{
$imgTargetWidth = $srcWidth;
$imgTargetHeight = $srcHeight;
}
else if ($targetRatio > $srcRatio)
{
$imgTargetWidth = (int) ($targetHeight * $srcRatio);
$imgTargetHeight = $targetHeight;
}
else
{
$imgTargetWidth = $targetWidth;
$imgTargetHeight = (int) ($targetWidth / $srcRatio);
}
// Creating new image with desired size
$targetImg = imagecreatetruecolor($targetWidth, $targetHeight);
// Add transparency if your reduced image does not fit with the new size
$targetTransparent = imagecolorallocate($targetImg, 255, 0, 255);
imagefill($targetImg, 0, 0, $targetTransparent);
imagecolortransparent($targetImg, $targetTransparent);
// Copies image, centered to the new one (if it does not fit to it)
imagecopyresampled(
$targetImg, $img, ($targetWidth - $imgTargetWidth) / 2, // centered
($targetHeight - $imgTargetHeight) / 2, // centered
0, 0, $imgTargetWidth, $imgTargetHeight, $srcWidth, $srcHeight
);
return $targetImg;
}
Usage example :
$gd = imagecreatefromjpeg("images/image5.jpg");
$resized = resizePreservingAspectRatio($gd, 100, 100);
header("Content-type: image/png");
imagepng($resized);
This image :
Becomes :
Never mind.
I figured it out myself.
I simplefied the code for scaling the thumbnail quite a bit:
$biggest = ($width > $height) ? $width : $height;
$newWidth = 0;
$newHeight = 0;
$scale = ($biggest >= $thumbSize) ? $thumbSize/$biggest : $biggest/$thumbSize;
$newWidth = floor($width * $scale);
$newHeight = floor($height * $scale);
$sourceImage = imagecreatefromstring(file_get_contents($fileName));
$thumb = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresampled($thumb, $sourceImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
imagedestroy($sourceImage);
Maybe someone can use this.
I have successfully resized images using GD library. I resize any image to 350 x 250, the problem is tat some pictures don't look good (stretch) when they are resized as i am resizing them to a fixed size. I have a space of 350 x 250 where resize picture needs to be fit, I don't mind if the pic size is smaller than 350 x 250 as long as it does not stretch. How do i solve this problem?
$save = "$directory/" . $file_name; //This is the new file you saving
$file = "$directory/" . $file_name; //This is the original file
list($width, $height) = getimagesize($file) ;
$modwidth = 350;
if ($width > $height) {
$y = 0;
$x = ($width - $height) / 2;
$smallestSide = $height;
} else {
$x = 0;
$y = ($height - $width) / 2;
$smallestSide = $width;
}
$diff = $width / $modwidth;
$modheight = 250;
$tn = imagecreatetruecolor($modwidth, $modheight) ;
$image = imagecreatefromjpeg($file) ;
imagecopyresampled($tn, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height);
imagejpeg($tn, $save, 100) ;
Try using this function I've written some time ago:
public function resize($img, $width, $height, $stretch = false)
{
$temp = imagecreatetruecolor($width, $height);
imagealphablending($temp, true);
imagesavealpha($temp, true);
$bg = imagecolorallocatealpha($temp, 0, 0, 0, 127); // Background color
imagefill($temp, 0, 0, $bg);
if ($stretch)
{
imagecopyresampled($temp, img, 0, 0, 0, 0, $width, $height, imagesx($img), imagesy($img));
}
else
{
if (imagesx($img) <= $width && imagesy($img) <= $height)
{
$fwidth = imagesx($img);
$fheight = imagesy($img);
}
else
{
$wscale = $width / imagesx($img);
$hscale = $height / imagesy($img);
$scale = min($wscale, $hscale);
$fwidth = $scale * imagesx($img);
$fheight = $scale * imagesy($img);
}
imagecopyresampled($temp,
$img,
($width - $fwidth) / 2, ($height - $fheight) / 2,
0, 0,
$fwidth, $fheight,
imagesx($img), imagesy($img)
);
}
return $temp;
}
if you say not to stretch the image, it will calculate a new size making it fit your new size.
use it as:
...
$image = imagecreatefromjpeg($file);
$resized = resize($image, 350, 250, false); // false = don't stretch
imagejpeg($resized, $save, 100);
...
now store $resized on the disk using imagepng() for example.
I'm wanting to create a very very basic upload, resize, and crop PHP script.
The functionality to this will be identical (last i checked anyway) to the method Twitter uses to upload avatar pictures.
I want the script to take any size image, resize the shortest side to 116px, then crop off the top and bottom (or left and right side if it's landscape) as to get a square 116px by 116px.
I don't want a bloated PHP script with client side resizing or anything, just a simple PHP resize and crop. How is this done?
The GD Library is a good place to start.
http://www.php.net/manual/en/book.image.php
There a simple to use, open source library called PHP Image Magician. It uses GD but simplifies it's usage to 3 lines.
Example of basis usage:
$magicianObj = new imageLib('racecar.jpg');
$magicianObj -> resizeImage(100, 200, 'crop');
$magicianObj -> saveImage('racecar_small.png');
If you want an example to work from my upload, resize and crop class does all of this plus some other cool stuff - you can use it all if needed or just take the bits out that you like:
http://www.mjdigital.co.uk/blog/php-upload-and-resize-image-class/
I don't think it is too bloated! - you can just do something this (not tested):
if((isset($_FILES['file']['error']))&&($_FILES['file']['error']==0)){ // if a file has been posted then upload it
include('INCLUDE_CLASS_FILE_HERE.php');
$myImage = new _image;
// upload image
$myImage->uploadTo = 'uploads/'; // SET UPLOAD FOLDER HERE
$myImage->returnType = 'array'; // RETURN ARRAY OF IMAGE DETAILS
$img = $myImage->upload($_FILES['file']);
if($img) {
$myImage->newWidth = 116;
$myImage->newHeight = 116;
$i = $myImage->resize(); // resizes to 116px keeping aspect ratio
// get new image height
$imgWidth = $i['width'];
// get new image width
$imgHeight = $i['height'];
if($i) {
// work out where to crop it
$cropX = ($imgWidth>116) ? (($imgWidth-116)/2) : 0;
$cropY = ($imgHeight>116) ? (($imgHeight-116)/2) : 0;
$cropped = $myImage->crop(116,116,$cropX,$cropY);
if($cropped) { echo 'It Worked (I think!)'; print_r($cropped);
} else { echo 'Crop failed'; }
} else { echo 'Resize failed'; }
} else { echo 'Upload failed'; }
I made this simple function which is very easy to use, it allows you to resize, crop and center an image to a specific width and height, it can suppert JPGs, PNGs and GIFs. Feel free to copy and paste it to your code:
function resize_imagejpg($file, $w, $h, $finaldst) {
list($width, $height) = getimagesize($file);
$src = imagecreatefromjpeg($file);
$ir = $width/$height;
$fir = $w/$h;
if($ir >= $fir){
$newheight = $h;
$newwidth = $w * ($width / $height);
}
else {
$newheight = $w / ($width/$height);
$newwidth = $w;
}
$xcor = 0 - ($newwidth - $w) / 2;
$ycor = 0 - ($newheight - $h) / 2;
$dst = imagecreatetruecolor($w, $h);
imagecopyresampled($dst, $src, $xcor, $ycor, 0, 0, $newwidth, $newheight,
$width, $height);
imagejpeg($dst, $finaldst);
imagedestroy($dst);
return $file;
}
function resize_imagegif($file, $w, $h, $finaldst) {
list($width, $height) = getimagesize($file);
$src = imagecreatefromgif($file);
$ir = $width/$height;
$fir = $w/$h;
if($ir >= $fir){
$newheight = $h;
$newwidth = $w * ($width / $height);
}
else {
$newheight = $w / ($width/$height);
$newwidth = $w;
}
$xcor = 0 - ($newwidth - $w) / 2;
$ycor = 0 - ($newheight - $h) / 2;
$dst = imagecreatetruecolor($w, $h);
$background = imagecolorallocatealpha($dst, 0, 0, 0, 127);
imagecolortransparent($dst, $background);
imagealphablending($dst, false);
imagesavealpha($dst, true);
imagecopyresampled($dst, $src, $xcor, $ycor, 0, 0, $newwidth, $newheight,
$width, $height);
imagegif($dst, $finaldst);
imagedestroy($dst);
return $file;
}
function resize_imagepng($file, $w, $h, $finaldst) {
list($width, $height) = getimagesize($file);
$src = imagecreatefrompng($file);
$ir = $width/$height;
$fir = $w/$h;
if($ir >= $fir){
$newheight = $h;
$newwidth = $w * ($width / $height);
}
else {
$newheight = $w / ($width/$height);
$newwidth = $w;
}
$xcor = 0 - ($newwidth - $w) / 2;
$ycor = 0 - ($newheight - $h) / 2;
$dst = imagecreatetruecolor($w, $h);
$background = imagecolorallocate($dst, 0, 0, 0);
imagecolortransparent($dst, $background);
imagealphablending($dst, false);
imagesavealpha($dst, true);
imagecopyresampled($dst, $src, $xcor, $ycor, 0, 0, $newwidth,
$newheight,$width, $height);
imagepng($dst, $finaldst);
imagedestroy($dst);
return $file;
}
function ImageResize($file, $w, $h, $finaldst) {
$getsize = getimagesize($file);
$image_type = $getsize[2];
if( $image_type == IMAGETYPE_JPEG) {
resize_imagejpg($file, $w, $h, $finaldst);
} elseif( $image_type == IMAGETYPE_GIF ) {
resize_imagegif($file, $w, $h, $finaldst);
} elseif( $image_type == IMAGETYPE_PNG ) {
resize_imagepng($file, $w, $h, $finaldst);
}
}
All you have to do to use it is call it like so:
ImageResize(image, width, height, destination);
E.g.
ImageResize("uploads/face.png", 100, 150, "images/user332profilepic.png");
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Can anybody suggest the best image resize script in php?
I'm still a newbie regarding image handling or file handling for that matter in PHP.
Would appreciate any input regarding the following
I post an image file using a simple html form and upload it via php.
When i try and alter my code to accomodate larger files (i.e. resize) I get an error.
Have been searching online but cant find anything really simple.
$size = getimagesize($_FILES['image']['tmp_name']);
//compare the size with the maxim size we defined and print error if bigger
if ($size == FALSE)
{
$errors=1;
}else if($size[0] > 300){ //if width greater than 300px
$aspectRatio = 300 / $size[0];
$newWidth = round($aspectRatio * $size[0]);
$newHeight = round($aspectRatio * $size[1]);
$imgHolder = imagecreatetruecolor($newWidth,$newHeight);
}
$newname= ROOTPATH.LOCALDIR."/images/".$image_name; //image_name is generated
$copy = imagecopyresized($imgHolder, $_FILES['image']['tmp_name'], 0, 0, 0, 0, $newWidth, $newHeight, $size[0], $size[1]);
move_uploaded_file($copy, $newname); //where I want to move the file to the location of $newname
The error I get is:
imagecopyresized(): supplied argument
is not a valid Image resource in
Thanks in advance
Thanks for all your input, i've changed it to this
$oldImage = imagecreatefromstring(file_get_contents($_FILES['image']['tmp_name']));
$copy = imagecopyresized($imgHolder, $oldImage, 0, 0, 0, 0, $newWidth, $newHeight, $size[0], $size[1]);
if(!move_uploaded_file($copy, $newname)){
$errors=1;
}
Not getting a PHP log error but its not saving :(
Any ideas?
Thanks again
Result
Following works.
$oldImage = imagecreatefromjpeg($img);
$imageHolder = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresized($imageHolder, $oldImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
imagejpeg($imageHolder, $newname, 100);
Thanks for everyones help
imagecopyresized takes an image resource as its second parameter, not a file name. You'll need to load the file first. If you know the file type, you can use imagecreatefromFILETYPE to load it. For example, if it's a JPEG, use imagecreatefromjpeg and pass that the file name - this will return an image resource.
If you don't know the file type, all is not lost. You can read the file in as a string and use imagecreatefromstring (which detects file types automatically) to load it as follows:
$oldImage = imagecreatefromstring(file_get_contents($_FILES['image']['tmp_name']));
$_FILES['image']['tmp_name'] is path not image resource. You have to use one of imagecreatefrom*() functions to create resource.
Here is my implementation of saving a thumbnail picture:
Resize and save function:
function SaveThumbnail($imagePath, $saveAs, $max_x, $max_y)
{
ini_set("memory_limit","32M");
$im = imagecreatefromjpeg ($imagePath);
$x = imagesx($im);
$y = imagesy($im);
if (($max_x/$max_y) < ($x/$y))
{
$save = imagecreatetruecolor($x/($x/$max_x), $y/($x/$max_x));
}
else
{
$save = imagecreatetruecolor($x/($y/$max_y), $y/($y/$max_y));
}
imagecopyresized($save, $im, 0, 0, 0, 0, imagesx($save), imagesy($save), $x, $y);
imagejpeg($save, $saveAs);
imagedestroy($im);
imagedestroy($save);
}
Usage:
$thumb_dir = "/path/to/thumbnaildir/"
$thumb_name = "thumb.jpg"
$muf = move_uploaded_file($_FILES['imgfile']['tmp_name'], "/tmp/test.jpg")
if($muf)
{
SaveThumbnail("/tmp/test.jpg", $thumb_dir . $thumb_name, 128, 128);
}
I use ImageMagick for stuff like that. Look how much simpler it is!
An example from one of my scripts:
$target= //destination path
move_uploaded_file($_FILES['item']['tmp_name'],$target);
$image = new imagick($target);
$image->setImageColorspace(imagick::COLORSPACE_RGB);
$image->scaleImage(350,0);
$image->writeImage($target);
You could then use getImageGeometry() to obtain the width and height.
For example:
$size=$image->getImageGeometry();
if($size['width'] > 300){ //if width greater than
$image->scaleImage(300,0);
}
Also, using scaleImage(300,0) means that ImageMagick automatically calculates the height based on the aspect ratio.
I was working on sth similar. I tried Ghostscript and ImageMagic. They are good tools but takes a but of time to set up. I ended up using 'sips' on a Snow Leopard server. Not sure if it's built in to Linux server but it's the faster solution I have found if you need sth done quick.
function resizeImage($file){
define ('MAX_WIDTH', 1500);//max image width
define ('MAX_HEIGHT', 1500);//max image height
define ('MAX_FILE_SIZE', 10485760);
//iamge save path
$path = 'storeResize/';
//size of the resize image
$new_width = 128;
$new_height = 128;
//name of the new image
$nameOfFile = 'resize_'.$new_width.'x'.$new_height.'_'.basename($file['name']);
$image_type = $file['type'];
$image_size = $file['size'];
$image_error = $file['error'];
$image_file = $file['tmp_name'];
$image_name = $file['name'];
$image_info = getimagesize($image_file);
//check image type
if ($image_info['mime'] == 'image/jpeg' or $image_info['mime'] == 'image/jpg'){
}
else if ($image_info['mime'] == 'image/png'){
}
else if ($image_info['mime'] == 'image/gif'){
}
else{
//set error invalid file type
}
if ($image_error){
//set error image upload error
}
if ( $image_size > MAX_FILE_SIZE ){
//set error image size invalid
}
switch ($image_info['mime']) {
case 'image/jpg': //This isn't a valid mime type so we should probably remove it
case 'image/jpeg':
$image = imagecreatefromjpeg ($image_file);
break;
case 'image/png':
$image = imagecreatefrompng ($image_file);
break;
case 'image/gif':
$image = imagecreatefromgif ($image_file);
break;
}
if ($new_width == 0 && $new_height == 0) {
$new_width = 100;
$new_height = 100;
}
// ensure size limits can not be abused
$new_width = min ($new_width, MAX_WIDTH);
$new_height = min ($new_height, MAX_HEIGHT);
//get original image h/w
$width = imagesx ($image);
$height = imagesy ($image);
//$align = 'b';
$zoom_crop = 1;
$origin_x = 0;
$origin_y = 0;
//TODO setting Memory
// generate new w/h if not provided
if ($new_width && !$new_height) {
$new_height = floor ($height * ($new_width / $width));
} else if ($new_height && !$new_width) {
$new_width = floor ($width * ($new_height / $height));
}
// scale down and add borders
if ($zoom_crop == 3) {
$final_height = $height * ($new_width / $width);
if ($final_height > $new_height) {
$new_width = $width * ($new_height / $height);
} else {
$new_height = $final_height;
}
}
// create a new true color image
$canvas = imagecreatetruecolor ($new_width, $new_height);
imagealphablending ($canvas, false);
if (strlen ($canvas_color) < 6) {
$canvas_color = 'ffffff';
}
$canvas_color_R = hexdec (substr ($canvas_color, 0, 2));
$canvas_color_G = hexdec (substr ($canvas_color, 2, 2));
$canvas_color_B = hexdec (substr ($canvas_color, 2, 2));
// Create a new transparent color for image
$color = imagecolorallocatealpha ($canvas, $canvas_color_R, $canvas_color_G, $canvas_color_B, 127);
// Completely fill the background of the new image with allocated color.
imagefill ($canvas, 0, 0, $color);
// scale down and add borders
if ($zoom_crop == 2) {
$final_height = $height * ($new_width / $width);
if ($final_height > $new_height) {
$origin_x = $new_width / 2;
$new_width = $width * ($new_height / $height);
$origin_x = round ($origin_x - ($new_width / 2));
} else {
$origin_y = $new_height / 2;
$new_height = $final_height;
$origin_y = round ($origin_y - ($new_height / 2));
}
}
// Restore transparency blending
imagesavealpha ($canvas, true);
if ($zoom_crop > 0) {
$src_x = $src_y = 0;
$src_w = $width;
$src_h = $height;
$cmp_x = $width / $new_width;
$cmp_y = $height / $new_height;
// calculate x or y coordinate and width or height of source
if ($cmp_x > $cmp_y) {
$src_w = round ($width / $cmp_x * $cmp_y);
$src_x = round (($width - ($width / $cmp_x * $cmp_y)) / 2);
} else if ($cmp_y > $cmp_x) {
$src_h = round ($height / $cmp_y * $cmp_x);
$src_y = round (($height - ($height / $cmp_y * $cmp_x)) / 2);
}
// positional cropping!
if ($align) {
if (strpos ($align, 't') !== false) {
$src_y = 0;
}
if (strpos ($align, 'b') !== false) {
$src_y = $height - $src_h;
}
if (strpos ($align, 'l') !== false) {
$src_x = 0;
}
if (strpos ($align, 'r') !== false) {
$src_x = $width - $src_w;
}
}
// positional cropping!
imagecopyresampled ($canvas, $image, $origin_x, $origin_y, $src_x, $src_y, $new_width, $new_height, $src_w, $src_h);
} else {
imagecopyresampled ($canvas, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
}
//Straight from Wordpress core code. Reduces filesize by up to 70% for PNG's
if ( (IMAGETYPE_PNG == $image_info[2] || IMAGETYPE_GIF == $image_info[2]) && function_exists('imageistruecolor') && !imageistruecolor( $image ) && imagecolortransparent( $image ) > 0 ){
imagetruecolortopalette( $canvas, false, imagecolorstotal( $image ) );
}
$quality = 100;
$nameOfFile = 'resize_'.$new_width.'x'.$new_height.'_'.basename($file['name']);
if (preg_match('/^image\/(?:jpg|jpeg)$/i', $image_info['mime'])){
imagejpeg($canvas, $path.$nameOfFile, $quality);
} else if (preg_match('/^image\/png$/i', $image_info['mime'])){
imagepng($canvas, $path.$nameOfFile, floor($quality * 0.09));
} else if (preg_match('/^image\/gif$/i', $image_info['mime'])){
imagegif($canvas, $path.$nameOfFile);
}
}