Fast resize picture tool/script - php

I have a lot of images (500,000 +) in a folder on the server organized by date. I made a PHP script to copy and crop each JPG file on a subfolder (thumb), but it's very slow since PHP doesn't support multithreading.
I want advice on how to proceed. Is Python a good option for this? Is there a good tool, or how can I improve my resize function?
You can also take a look to my PHP Code

You can do it in PHP without any problem, simulating threads instead of using them directly. Actually, PHP doesn't have native threads (you can eventuallĀ„ use libraries but that's not very useful in your case).
In your code, instead of calling :
static::Crop($file,$destination,$tn_w = 300,$tn_h =200,$quality = 100,$wmsource = false);
Why not doing :
$array = array($file, $destination, $tn_w = 300, $tn_h = 200, $quality = 100, $wmsource = 0);
$command = "/usr/bin/php crop.php";
foreach ($array as $arg)
{
$command .= ' ' . escapeshellarg($arg);
}
exec("$command &"); // note the & which release your execution
usleep(100000);
And you put your cropping function inside crop.php, and then call it like :
list($exec, $file, $destination, $tn_w, $tn_h, $quality, $wmsource) = $argv;
static::Crop($file,$destination,$tn_w = 300,$tn_h =200,$quality = 100,$wmsource = false);
This will do the job.
You can also simulate mutexes using a file if you want to avoid usleep and control how many crops are running at once, that's really up to you. You definitely can do such work in PHP.

But php cgi support multithreading. Why not using exec()? Or you can use a shell script and for the conversion php cgi?

by Use This class
<?php
class thumbnail_images {
// get
var $PathImgOld;
var $PathImgNew;
var $NewWidth;
var $NewHeight;
// tmp
var $mime;
function imagejpeg_new ($NewImg,$path_img) {
if ($this->mime == 'image/jpeg' or $this->mime == 'image/pjpeg') imagejpeg($NewImg,$path_img);
elseif ($this->mime == 'image/gif') imagegif($NewImg, $path_img);
elseif ($this->mime == 'image/png') imagepng($NewImg, $path_img);
else return(false);
return(true);
}
function imagecreatefromjpeg_new($path_img) {
if ($this->mime == 'image/jpeg' or $this->mime == 'image/pjpeg') $OldImg = imagecreatefromjpeg($path_img);
elseif ($this->mime == 'image/gif') $OldImg = imagecreatefromgif($path_img);
elseif ($this->mime == 'image/png') $OldImg = imagecreatefrompng($path_img);
else return(false);
return($OldImg);
}
function create_thumbnail_images() {
$PathImgOld = $this->PathImgOld;
$PathImgNew = $this->PathImgNew;
$NewWidth = $this->NewWidth;
$NewHeight = $this->NewHeight;
$Oldsize = #getimagesize($PathImgOld);
$this->mime = $Oldsize['mime'];
$OldWidth = $Oldsize[0];
$OldHeight = $Oldsize[1];
if ($NewHeight == '' and $NewWidth != '') {
$NewHeight = ceil(($OldHeight * $NewWidth) / $OldWidth);
}
elseif ($NewWidth == '' and $NewHeight != '') {
$NewWidth = ceil(($OldWidth * $NewHeight) / $OldHeight);
}
elseif ($NewHeight == '' and $NewWidth == '') {
return(false);
}
$OldHeight_castr = ceil(($OldWidth * $NewHeight) / $NewWidth);
$castr_bottom = ($OldHeight - $OldHeight_castr) / 2;
$OldWidth_castr = ceil(($OldHeight * $NewWidth) / $NewHeight);
$castr_right = ($OldWidth - $OldWidth_castr) / 2;
if ($castr_bottom>0) {
$OldWidth_castr = $OldWidth;
$castr_right = 0;
}
elseif ($castr_right>0) {
$OldHeight_castr = $OldHeight;
$castr_bottom = 0;
}
else {
$OldWidth_castr = $OldWidth;
$OldHeight_castr = $OldHeight;
$castr_right = 0;
$castr_bottom = 0;
}
$OldImg = $this->imagecreatefromjpeg_new($PathImgOld);
if ($OldImg) {
$NewImg_castr = imagecreatetruecolor($OldWidth_castr, $OldHeight_castr);
if ($NewImg_castr) {
imagecopyresampled($NewImg_castr, $OldImg, 0, 0, $castr_right, $castr_bottom, $OldWidth_castr, $OldHeight_castr, $OldWidth_castr, $OldHeight_castr);
$NewImg = imagecreatetruecolor($NewWidth, $NewHeight);
if ($NewImg) {
imagecopyresampled($NewImg, $NewImg_castr, 0, 0, 0, 0, $NewWidth, $NewHeight, $OldWidth_castr, $OldHeight_castr);
imagedestroy($NewImg_castr);
imagedestroy($OldImg);
if (!$this->imagejpeg_new($NewImg, $PathImgNew)) return (false);
imagedestroy($NewImg);
}
}
}
else {
return(false);
}
return(true);
}
}
?>
Now use it
$width = $_REQUEST['img_width'];
$height = $_REQUEST['img_height'];
// example
$obj_img = new thumbnail_images();
$obj_img->PathImgOld = 'Old_image.jpg'; // Image for resize
$obj_img->PathImgNew = 'my_image_new_formSubURLkki.jpg'; // New Image Path
$obj_img->NewWidth = $width;
$obj_img->NewHeight = $height;
if (!$obj_img->create_thumbnail_images()) echo "error";
else {
echo 'Image Maked andsave in directory';
}

Related

Error Resize image in Shared hosting (Cpanel)

I have a problem about resize image at hosting.
When i use function to resize image in Localhost, it's good.
But when i upload them to Cpanel. It's only work with small size picture. With bigger size(maybe 300kb), it doesn't work and doesn't
show any errors. How to fix it?
Please help me!
Command :
resize_image('max',"upload/tindang/".$Hinh,"upload/tindang/".$Hinh,600,600);
This is my function :
function resize_image_crop($image,$width,$height) {
$w = #imagesx($image); //current width
$h = #imagesy($image); //current height
if ((!$w) || (!$h)) { $GLOBALS['errors'][] = 'Image couldn\'t be resized because it wasn\'t a valid image.'; return false; }
if (($w == $width) && ($h == $height)) { return $image; } //no resizing needed
//try max width first...
$ratio = $width / $w;
$new_w = $width;
$new_h = $h * $ratio;
//if that created an image smaller than what we wanted, try the other way
if ($new_h < $height) {
$ratio = $height / $h;
$new_h = $height;
$new_w = $w * $ratio;
}
$image2 = imagecreatetruecolor ($new_w, $new_h);
imagecopyresampled($image2,$image, 0, 0, 0, 0, $new_w, $new_h, $w, $h);
//check to see if cropping needs to happen
if (($new_h != $height) || ($new_w != $width)) {
$image3 = imagecreatetruecolor ($width, $height);
if ($new_h > $height) { //crop vertically
$extra = $new_h - $height;
$x = 0; //source x
$y = round($extra / 2); //source y
imagecopyresampled($image3,$image2, 0, 0, $x, $y, $width, $height, $width, $height);
} else {
$extra = $new_w - $width;
$x = round($extra / 2); //source x
$y = 0; //source y
imagecopyresampled($image3,$image2, 0, 0, $x, $y, $width, $height, $width, $height);
}
imagedestroy($image2);
return $image3;
} else {
return $image2;
}
}
function resize_image_max($image,$max_width,$max_height) {
$w = imagesx($image); //current width
$h = imagesy($image); //current height
if ((!$w) || (!$h)) { $GLOBALS['errors'][] = 'Image couldn\'t be resized because it wasn\'t a valid image.'; return false; }
// if (($w <= $max_width) && ($h <= $max_height)) { return $image; } //no resizing needed
//try max width first...
$ratio = $max_width / $w;
$new_w = $max_width;
$new_h = $h * $ratio;
//if that didn't work
if ($new_h > $max_height) {
$ratio = $max_height / $h;
$new_h = $max_height;
$new_w = $w * $ratio;
}
$new_image = imagecreatetruecolor ($new_w, $new_h);
imagecopyresampled($new_image,$image, 0, 0, 0, 0, $new_w, $new_h, $w, $h);
return $new_image;
}
function resize_image_force($image,$width,$height) {
$w = #imagesx($image); //current width
$h = #imagesy($image); //current height
if ((!$w) || (!$h)) { $GLOBALS['errors'][] = 'Image couldn\'t be resized because it wasn\'t a valid image.'; return false; }
if (($w == $width) && ($h == $height)) { return $image; } //no resizing needed
$image2 = imagecreatetruecolor ($width, $height);
imagecopyresampled($image2,$image, 0, 0, 0, 0, $width, $height, $w, $h);
return $image2;
}
function resize_image($method,$image_loc,$new_loc,$width,$height) {
if (!is_array(#$GLOBALS['errors'])) { $GLOBALS['errors'] = array(); }
if (!in_array($method,array('force','max','crop'))) { $GLOBALS['errors'][] = 'Invalid method selected.'; }
if (!$image_loc) { $GLOBALS['errors'][] = 'No source image location specified.'; }
else {
if ((substr(strtolower($image_loc),0,7) == 'http://') || (substr(strtolower($image_loc),0,7) == 'https://')) { /*don't check to see if file exists since it's not local*/ }
elseif (!file_exists($image_loc)) { $GLOBALS['errors'][] = 'Image source file does not exist.'; }
$extension = strtolower(substr($image_loc,strrpos($image_loc,'.')));
if (!in_array($extension,array('.jpg','.jpeg','.png','.gif','.bmp'))) { $GLOBALS['errors'][] = 'Invalid source file extension!'; }
}
if (!$new_loc) { $GLOBALS['errors'][] = 'No destination image location specified.'; }
else {
$new_extension = strtolower(substr($new_loc,strrpos($new_loc,'.')));
if (!in_array($new_extension,array('.jpg','.jpeg','.png','.gif','.bmp'))) { $GLOBALS['errors'][] = 'Invalid destination file extension!'; }
}
$width = abs(intval($width));
if (!$width) { $GLOBALS['errors'][] = 'No width specified!'; }
$height = abs(intval($height));
if (!$height) { $GLOBALS['errors'][] = 'No height specified!'; }
if (count($GLOBALS['errors']) > 0) { echo_errors(); return false; }
if (in_array($extension,array('.jpg','.jpeg'))) { $image = #imagecreatefromjpeg($image_loc); }
elseif ($extension == '.png') { $image = #imagecreatefrompng($image_loc); }
elseif ($extension == '.gif') { $image = #imagecreatefromgif($image_loc); }
elseif ($extension == '.bmp') { $image = #imagecreatefromwbmp($image_loc); }
if (!$image) { $GLOBALS['errors'][] = 'Image could not be generated!'; }
else {
$current_width = imagesx($image);
$current_height = imagesy($image);
if ((!$current_width) || (!$current_height)) { $GLOBALS['errors'][] = 'Generated image has invalid dimensions!'; }
}
if (count($GLOBALS['errors']) > 0) { #imagedestroy($image); echo_errors(); return false; }
if ($method == 'force') { $new_image = resize_image_force($image,$width,$height); }
elseif ($method == 'max') { $new_image = resize_image_max($image,$width,$height); }
elseif ($method == 'crop') { $new_image = resize_image_crop($image,$width,$height); }
if ((!$new_image) && (count($GLOBALS['errors'] == 0))) { $GLOBALS['errors'][] = 'New image could not be generated!'; }
if (count($GLOBALS['errors']) > 0) { #imagedestroy($image); echo_errors(); return false; }
$save_error = false;
if (in_array($extension,array('.jpg','.jpeg'))) { imagejpeg($new_image,$new_loc) or ($save_error = true); }
elseif ($extension == '.png') { imagepng($new_image,$new_loc) or ($save_error = true); }
elseif ($extension == '.gif') { imagegif($new_image,$new_loc) or ($save_error = true); }
elseif ($extension == '.bmp') { imagewbmp($new_image,$new_loc) or ($save_error = true); }
if ($save_error) { $GLOBALS['errors'][] = 'New image could not be saved!'; }
if (count($GLOBALS['errors']) > 0) { #imagedestroy($image); #imagedestroy($new_image); echo_errors(); return false; }
imagedestroy($image);
imagedestroy($new_image);
return true;
}

Php resize width fix

I have this function in PHP.
<?php
function zmensi_obrazok($max_dimension, $image_max_width, $image_max_height, $dir, $obrazok, $obrazok_tmp, $obrazok_size, $filename){
$postvars = array(
"image" => $obrazok,
"image_tmp" => $obrazok_tmp,
"image_size" => $obrazok_size,
"image_max_width" => $image_max_width,
"image_max_height" => $image_max_height
);
// Array of valid extensions.
$valid_exts = array("jpg","jpeg","gif","png");
// Select the extension from the file.
$ext = end(explode(".",strtolower($obrazok)));
// Check not larger than 175kb.
if($postvars["image_size"] <= 256000){
// Check is valid extension.
if(in_array($ext,$valid_exts)){
if($ext == "jpg" || $ext == "jpeg"){
$image = imagecreatefromjpeg($postvars["image_tmp"]);
}
else if($ext == "gif"){
$image = imagecreatefromgif($postvars["image_tmp"]);
}
else if($ext == "png"){
$image = imagecreatefrompng($postvars["image_tmp"]);
}
list($width,$height) = getimagesize($postvars["image_tmp"]);
if($postvars["image_max_width"] > $postvars["image_max_height"]){
if($postvars["image_max_width"] > $max_dimension){
$newwidth = $max_dimension;
}
else
{
$newwidth = $postvars["image_max_width"];
}
}
else
{
if($postvars["image_max_height"] > $max_dimension)
{
$newheight = $max_dimension;
}
else
{
$newheight = $postvars["image_max_height"];
}
}
$tmp = imagecreatetruecolor($newwidth,$newheight);
imagecopyresampled($tmp,$image,0,0,0,0,$newwidth,$newheight,$width,$height);
imagejpeg($tmp,$filename,100);
return "fix";
imagedestroy($image);
imagedestroy($tmp);
}
}
}
?>
Now if I want to use it, and I upload image for example 500x300px and I have set max size to 205x205px it don't want to make resized picture proportion. It make something like 375x205 (height is still OK). Can somebody help how to fix it?
Just scale your image twice, once to match the width, once to match the height. To save on processing, get your scaling first, then do the resizing:
$max_w = 205;
$max_h = 205;
$img_w = ...;
$img_h = ...;
if ($img_w > $max_w) {
$img_h = $img_h * $max_w / $img_w;
$img_w = $max_w;
}
if ($img_h > $max_h) {
$img_w = $img_w * $max_h / $img_h;
$img_h = $max_h;
}
// $img_w and $img_h should now have your scaled down image complying with both restrictions.

PHP - Duplicating $_FILES superglobal

I have a PHP function that I use regularly for working with images (resizing, watermarking, converting to grayscale, etc). I am happy with it and it works well. However, it is designed to work with the $_FILES superglobal, and accepts it as a parameter.
I've run into a situation where I have an existing directory of files on my server that I need to process in the same way as I do for files uploaded from a form into the $_FILES array.
Figuring it would be easiest to work with my existing function, I have been looking for a way to duplicate the $_FILES superglobal, so I can pass it to my script, but I am not finding the functions/properties I need to accomplish this. (Although, at a glance, the getimagesize and filesize functions looks like they may help).
Can anyone advise on what functions/properties I would need to duplicate the $_FILES array? (Or an alternate way to accomplish what I am trying to do?)
For reference's sake, the image function I use is here:
function resize_upload ($file, $dest, $maxw = 50, $maxh = 50, $grey = false, $wm = false, $mark = "a/i/watermark.png", $opa = 40) {
$allowext = array("gif", "jpg", "png", "jpeg", "bmp");
$fileext = strtolower(getExtension($file['name']));
if (!in_array($fileext,$allowext)) {
echo "Wrong file extension.";
exit();
}
list($width, $height, $imgcon) = getimagesize($file['tmp_name']);
if ($file['size'] && ($width > $maxw || $height > $maxh)) {
if($file['type'] == "image/pjpeg" || $file['type'] == "image/jpeg"){$newimg = imagecreatefromjpeg($file['tmp_name']);}
elseif($file['type'] == "image/x-png" || $file['type'] == "image/png"){$newimg = imagecreatefrompng($file['tmp_name']);}
elseif($file['type'] == "image/gif"){$newimg = imagecreatefromgif($file['tmp_name']);}
$ratio = $width/$height;
if ($ratio < 1) { // Width < Height
$newheight = $maxh;
$newwidth = $width * ($maxh/$height);
if ($newwidth > $maxw) {
$newheight = $newheight * ($maxw/$newwidth);
$newwidth = $maxw;
}
} elseif ($ratio == 1) { // Width = Height
if ($maxw < $maxh) {
$newheight = $maxw;
$newwidth = $maxw;
} elseif ($maxw == $maxh) {
$newheight = $maxh;
$newwidth = $maxw;
} elseif ($maxw > $maxh) {
$newheight = $maxh;
$newwidth = $maxh;
}
} elseif ($ratio > 1) { // Width > Height
$newwidth = $maxw;
$newheight = $height * ($maxw/$width);
if ($newheight > $maxh) {
$newwidth = $newwidth * ($maxh/$newheight);
$newheight = $maxh;
}
}
if (function_exists(imagecreatetruecolor)) {$resize = imagecreatetruecolor($newwidth, $newheight);}
if (($imgcon == IMAGETYPE_GIF)) {
$trnprt_indx = imagecolortransparent($newimg);
if ($trnprt_indx >= 0) {
$trnprt_color = imagecolorsforindex($newimg, $trnprt_indx);
$trnprt_indx = imagecolorallocate($resize, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
imagefill($resize, 0, 0, $trnprt_indx);
imagecolortransparent($resize, $trnprt_indx);
}
} elseif ($imgcon == IMAGETYPE_PNG) {
imagealphablending($resize, false);
$color = imagecolorallocatealpha($resize, 0, 0, 0, 127);
imagefill($resize, 0, 0, $color);
imagesavealpha($resize, true);
}
imagecopyresampled($resize, $newimg, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
if ($wm) {
$watermark = imagecreatefrompng($mark);
$wm_width = imagesx($watermark);
$wm_height = imagesy($watermark);
$destx = $newwidth - $wm_width - 5;
$desty = $newheight - $wm_height - 5;
imagecopymerge($resize, $watermark, $destx, $desty, 0, 0, $wm_width, $wm_height, $opa);
imagedestroy($watermark);
}
$filename = random_name().".".$fileext;
if ($grey) {imagefilter($resize, IMG_FILTER_GRAYSCALE);}
if($file['type'] == "image/pjpeg" || $file['type'] == "image/jpeg"){$new = imagejpeg($resize, $dest."/".$filename, 100);}
elseif($file['type'] == "image/x-png" || $file['type'] == "image/png"){$new = imagepng($resize, $dest."/".$filename, 0);}
elseif($file['type'] == "image/gif"){$new = imagegif($resize, $dest."/".$filename);}
imagedestroy($resize);
imagedestroy($newimg);
return $filename;
} elseif ($file['size']) {
$filename = random_name().".".getExtension($file['name']);
if ($grey) {
if($file['type'] == "image/pjpeg" || $file['type'] == "image/jpeg"){$newimg = imagecreatefromjpeg($file['tmp_name']);}
elseif($file['type'] == "image/x-png" || $file['type'] == "image/png"){$newimg = imagecreatefrompng($file['tmp_name']);}
elseif($file['type'] == "image/gif"){$newimg = imagecreatefromgif($file['tmp_name']);}
imagefilter($newimg, IMG_FILTER_GRAYSCALE);
if($file['type'] == "image/pjpeg" || $file['type'] == "image/jpeg"){imagejpeg($newimg, $dest."/".$filename);}
elseif($file['type'] == "image/x-png" || $file['type'] == "image/png"){imagepng($newimg, $dest."/".$filename);}
elseif($file['type'] == "image/gif"){imagegif($newimg, $dest."/".$filename);}
imagedestroy($newimg);
return $filename;
} else {
$upload = file_upload($file, $dest);
return $upload;
}
}
}
The $_FILES array contains a nested array for an uploaded file. This nested array has 5 keys. For each key I explain what it should contain, and what function to use:
name: the name of the file, use the basename() function for this entry
type: the mime type of the file, for images set to 'image/png', 'image/jpeg', etc
tmp_name: the path to the actual file, here you should set the path to your images
error: this indicates that an error occured with the upload, in your case you can set it to 0 for no error
size: the size of the file in bytes, so you can use the filesize() function for your image
An example:
$_FILES = array('image' => array(
'name' => basename('/path/to/image.png'),
'type' => 'image/png',
'tmp_name' => '/path/to/image.png',
'error' => 0,
'size' => filesize('/path/to/image.png')
));
If you want to process multiple files at once, you should be aware that the structure of the $_FILES array is different than what you would expect in this case, see this comment in the PHP docs.

PHP: Resize/making thumbnails?

Helo i now have finish making my upload profilephoto system. Now i want include creating thumbnails of the uploaded image in different sizes eg 48x48 and 148x50, how can i do this?
Example / good tutorials for this?
You will need to use PHP's GD library or ImageMagick library.
First find out which, if any, you have installed on your development and production environments.
Then start looking for tutorials depending on which one you want to use. There are many out there.
GD usually comes pre-packed with PHP5.
Back then I used imagemagick.
$ convert -resize 48x48 xyz.jpg xyz_48x48.jpg
It is also available as a php module: http://php.net/manual/en/book.imagick.php
But I haven't used that one, but I suppose it knows exactly the same as the command line variant.
Tutorial with imagecreatefrom()... , imagecopyresized(), imagejpeg()
Here my class for resizing. Replace the 150 occurences with a variable.
<?php
/**
* Takes an image and creates a thumbnail of it.
*/
class ImageThumbnail
{
private $thumbnail;
/**
* Create a new object
*
* #param string $source Location of the original image (can be null if set using create())
* #param string $extension File extension, if it has been obfuscated (e.g. moved to PHP's tmp dir)
*/
public function __construct($source, $extension)
{
if ($source)
{
$this->create($source, $extension);
}
}
public function create($source, $extension = null)
{
if (!$extension)
{
$parts = explode('.', $source); // get the file extension
$extension = array_pop($parts);
}
else
{
$extension = ltrim($extension, '.'); // get rid of any prefixing dots
}
// Get the images size
$size = getImageSize($source);
// Width > height
if ($size[0] > $size[1])
{
$width = 150;
$height = (int) (150 * $size[1] / $size[0]);
}
// Height > width
else
{
$width = (int) (150 * $size[0] / $size[1]);
$height = 150;
}
$readFunc = 'imageCreateFrom'.filenameToImageMime($source);
if (!$source = $readFunc($source))
{
throw new Exception('The source image is unreadable');
}
// Create an blank image for the thumbnail
$thumbnail = imageCreateTrueColor($width, $height);
// Copy source image onto new image
imageCopyResized($thumbnail, $source, 0, 0, 0, 0, $width, $height, $size[0], $size[1]);
$this->thumbnail = $thumbnail;
}
public function getThumbnail()
{
return $this->thumbnail;
}
public function move($target)
{
$func = 'image'.filenameToImageMime($target);
$func($this->thumbnail, $target);
imageDestroy($this->thumbnail);
}
}
function makenicepic($srcfile,$tofile,$maxwidth,$maxheight) {
//global $_SGLOBAL;
// check file exist
if (!file_exists($srcfile)) {
return '';
}
$dstfile = $tofile;
include_once(S_ROOT.'./data/data_setting.php');
// //size
$tow = $maxwidth;
$toh =$maxheight;
$make_max = 0;
$maxtow = 950;
$maxtoh = 700;
$make_max = 1;
$im = '';
if($data = getimagesize($srcfile)) {
if($data[2] == 1) {
$make_max = 0;//gif skip
if(function_exists("imagecreatefromgif")) {
$im = imagecreatefromgif($srcfile);
}
} elseif($data[2] == 2) {
if(function_exists("imagecreatefromjpeg")) {
$im = imagecreatefromjpeg($srcfile);
}
} elseif($data[2] == 3) {
if(function_exists("imagecreatefrompng")) {
$im = imagecreatefrompng($srcfile);
}
}
}
if(!$im) return '';
$srcw = imagesx($im);
$srch = imagesy($im);
$towh = $tow/$toh;
$srcwh = $srcw/$srch;
if($towh <= $srcwh){
$ftow = $tow;
$ftoh = $ftow*($srch/$srcw);
$fmaxtow = $maxtow;
$fmaxtoh = $fmaxtow*($srch/$srcw);
} else {
$ftoh = $toh;
$ftow = $ftoh*($srcw/$srch);
$fmaxtoh = $maxtoh;
$fmaxtow = $fmaxtoh*($srcw/$srch);
}
if($srcw <= $maxtow && $srch <= $maxtoh) {
$make_max = 0;
}
if($srcw > $tow || $srch > $toh) {
if(function_exists("imagecreatetruecolor") && function_exists("imagecopyresampled") && #$ni = imagecreatetruecolor($ftow, $ftoh)) {
imagecopyresampled($ni, $im, 0, 0, 0, 0, $ftow, $ftoh, $srcw, $srch);
if($make_max && #$maxni = imagecreatetruecolor($fmaxtow, $fmaxtoh)) {
imagecopyresampled($maxni, $im, 0, 0, 0, 0, $fmaxtow, $fmaxtoh, $srcw, $srch);
}
} elseif(function_exists("imagecreate") && function_exists("imagecopyresized") && #$ni = imagecreate($ftow, $ftoh)) {
imagecopyresized($ni, $im, 0, 0, 0, 0, $ftow, $ftoh, $srcw, $srch);
if($make_max && #$maxni = imagecreate($fmaxtow, $fmaxtoh)) {
imagecopyresized($maxni, $im, 0, 0, 0, 0, $fmaxtow, $fmaxtoh, $srcw, $srch);
}
} else {
return '';
}
if(function_exists('imagejpeg')) {
imagejpeg($ni, $dstfile);
//big pic
if($make_max) {
imagejpeg($maxni, $srcfile);
}
} elseif(function_exists('imagepng')) {
imagepng($ni, $dstfile);
if($make_max) {
imagepng($maxni, $srcfile);
}
}
imagedestroy($ni);
if($make_max) {
imagedestroy($maxni);
}
}
imagedestroy($im);
if(!file_exists($dstfile)) {
return '';
} else {
return $dstfile;
}
}

Image Resizing: Poor jpeg quality and black PNG backgrounds

Final: I've decided to basically use this: http://shiftingpixel.com/2008/03/03/smart-image-resizer/
As it handles everything, Ive turned caching off and do this in the admin controllers:
$image = file_get_contents(SITE_ADMIN_IMAGE.'/SmartImage.php?width='.$this->thumb_width.'&height='.$this->thumb_height.'&image=/images/'.$this->image_directory.'/'.$formData['image_url'].'');
file_put_contents(ROOT_PATH.'/public/images/'.$this->image_directory.'/thumb/'.$formData['image_url'], $image);
EDIT: I found this works, however it creates very sharp edges, it doesn't look right.
imagecolortransparent($dstImage, $background);
imagealphablending($dstImage, false);
$colorTransparent = imagecolorallocatealpha($dstImage, 0, 0, 0, 127);
imagefill($dstImage, 0, 0, $colorTransparent);
imagesavealpha($dstImage, true);
imagepng($dstImage, $toWhere);
Ideas?
Hello,
I have two issues with my class, basically the quality of the jpeg images is quite poor, but I'm not sure if thats down to my ratio resizing. Ideally I'd like this class to be strict with image sizes and crop into them, but I cant get my head around it.
My main issue is that pngs always have a black bg, does anyone have experience with this happening?
<?php
class OpenSource_ImageResize {
function __construct($theFile, $toWhere, $mime, $extension, $newWidth, $newHeight) {
if ($mime == NULL) {
$mime = getimagesize($theFile);
$mime = $mime['mime'];
}
if ($mime == 'image/jpeg') {
$size = getimagesize($theFile);
if ($size[0] > $newWidth || $size[1] > $newHeight) {
$sourceImage = imagecreatefromjpeg($theFile);
} else {
return copy($theFile, $toWhere);
throw new exception('Could not create jpeg');
return false;
}
} else if ($mime == 'image/png') {
$size = getimagesize($theFile);
if ($size[0] > $newWidth || $size[1] > $newHeight) {
$sourceImage = imagecreatefrompng($theFile);
} else {
return copy($theFile, $toWhere);
//throw new exception('Could not create png');
return false;
}
} else if ($mime == 'image/gif') {
$size = getimagesize($theFile);
if ($size[0] > $newWidth || $size[1] > $newHeight) {
$sourceImage = imagecreatefromgif ($theFile);
} else {
return copy($theFile, $toWhere);
//throw new exception('Could not create gif');
return false;
}
} else {
throw new exception('Not a valid mime type');
return false;
}
$oldX = imageSX($sourceImage);
$oldY = imageSY($sourceImage);
if ($newWidth == NULL) {
$thumbHeight = $newHeight;
$thumbWidth = round($newHeight/($oldY/$oldX));
} else
if ($oldX > $oldY) {
$thumbWidth = $newWidth;
$thumbHeight = $oldY * ($newHeight/$oldX);
}
if ($oldX < $oldY) {
$thumbWidth = round($newHeight/($oldY/$oldX));
$thumbHeight = $newHeight;
}
if ($oldX == $oldY) {
$thumbWidth = $newWidth;
$thumbHeight = $newHeight;
}
if (!gd_info()) {
$dstImage = ImageCreate($thumbWidth, $thumbHeight);
imagecopyresized($dstImage, $sourceImage, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $oldX, $oldY);
} else {
$dstImage = ImageCreateTrueColor($thumbWidth, $thumbHeight);
imagecopyresampled($dstImage, $sourceImage, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $oldX, $oldY);
}
if ($mime == 'image/png') {
$xparent = imagecolorresolvealpha($dstImage, 255,2,240, 0) ;
imagecolortransparent($dstImage,$xparent);
imagealphablending($dstImage,true);
imagepng($dstImage, $toWhere);
} else if ($mime == 'image/jpeg') {
imagejpeg($dstImage, $toWhere);
} else if ($mime == 'image/gif') {
imagegif ($dstImage, $toWhere);
}
imagedestroy($dstImage);
imagedestroy($sourceImage);
return true;
}
}
Regarding JPEG image quality you need to make use of the third argument in imagejpeg():
imagejpeg($dstImage, $toWhere, 90); // any value above 85 should be fine
Regarding PNG transparency, you're doing it wrong. Your script is horrible and has fundamental problems, I'm gonna leave you with a revised one that fixes both of your problems. It can still be further optimized but I choose to leave some of your original less important mistakes so you don't feel lost:
class OpenSource_ImageResize
{
// $extension is not used?
function __construct($theFile, $toWhere, $mime, $extension, $newWidth, $newHeight)
{
$sourceImage = ImageCreateFromString(file_get_contents($theFile));
if (is_resource($sourceImage))
{
$info = getimagesize($theFile);
if (is_null($mime))
{
$mime = $info['mime'];
}
if ($info[0] <= $newWidth && $info[1] <= $newHeight)
{
imagedestroy($sourceImage);
return copy($theFile, $toWhere);
}
if (is_null($newWidth))
{
$thumbHeight = $newHeight;
$thumbWidth = round($newHeight/($info[1]/$info[0]));
}
else if ($info[0] > $info[1])
{
$thumbWidth = $newWidth;
$thumbHeight = $info[1] * ($newHeight/$info[0]);
}
if ($info[0] < $info[1])
{
$thumbWidth = round($newHeight/($info[1]/$info[0]));
$thumbHeight = $newHeight;
}
if ($info[0] == $info[1])
{
$thumbWidth = $newWidth;
$thumbHeight = $newHeight;
}
$dstImage = ImageCreateTrueColor($thumbWidth, $thumbHeight);
/* fix PNG transparency issues */
ImageFill($dstImage, 0, 0, IMG_COLOR_TRANSPARENT);
ImageSaveAlpha($dstImage, true);
ImageAlphaBlending($dstImage, true);
imagecopyresampled($dstImage, $sourceImage, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $info[0], $info[1]);
switch ($mime)
{
case 'image/png':
imagepng($dstImage, $toWhere, 9); // compress it (level 1 to 9)
break;
case 'image/jpeg':
imagejpeg($dstImage, $toWhere, 90); // quality = 90 (1 to 100, default is "about" 75)
break;
case 'image/gif':
imagegif($dstImage, $toWhere);
break;
}
imagedestroy($dstImage);
imagedestroy($sourceImage);
return true;
}
}
}
I'm sorry for not explicitly pointing out your mistakes but they are so many and it's 3 AM here, need to get some sleep - study it and read the manual, if you have any doubts let me know.
Musty define in your class png background color.You can also change the background color of jpg and other files after defining the background color.
this link will take you to a simple function that will either crop-to-fit, or letter box the image during resize based on the function's arguments. it also has a pretty thorough explaination as to what the function is doing.
http://www.spotlesswebdesign.com/blog.php?id=1
Edit: fixed link.

Categories