Reputation: 76561
I have inherited a function which resizes images. It works well in most cases, but for some reason, in some cases the result of resizing the image is totally different than the image initially contained. The function is as follows:
function image_resize($source, $destination, $width, $height, $resizeMode='fit', $type = 'jpeg', $options = array()) {
$defaults = array(
'output' => 'file',
'isFile' => true,
'quality' => '100',
'preserveAnimation' => false,
'offsetTop' => 0,
'offsetLeft' => 0,
'offsetType' => 'percent'
);
foreach ($defaults as $k => $v) {
if (!isset($options[$k])) {
$options[$k] = $v;
}
}
if ($options['isFile']) {
$image_info = getimagesize($source);
$image = null;
switch ($image_info[2]) {
case IMAGETYPE_JPEG:
$image = imagecreatefromjpeg($source);
break;
case IMAGETYPE_PNG:
$image = imagecreatefrompng($source);
break;
case IMAGETYPE_GIF:
$image = imagecreatefromgif($source);
break;
case IMAGETYPE_BMP:
$image = imagecreatefromwbmp($source);
break;
default :
return false;
}
} else {
$image = imagecreatefromstring($source);
}
//we have an image resource
$iwidth = imagesx($image);
$iheight = imagesy($image);
//We need $width and $height for this call
if (QM::isAcceptableProfilePhotoSize($width, $height) == false)
{
throw new Exception("Size of ".$width."x".$height." is not supported");
}
//determine ratios
$wratio = $width / $iwidth;
$hratio = $height / $iheight;
$mratio = min(array($wratio, $hratio));
$rimage = null;
switch ($resizeMode) {
case 'fit':
$rimage = imagecreatetruecolor($iwidth * $mratio, $iheight * $mratio);
$image = imagecopyresampled($rimage, $image, 0, 0, 0, 0, $iwidth * $mratio, $iheight * $mratio, $iwidth, $iheight);
break;
case 'crop':
$rratio = $width / $height;
if ($rratio < 1) {
$nwidth = $iwidth;
$nheight = $iwidth * 1/$rratio;
if ($nheight>$iheight) {
$nwidth = $nwidth*$iheight/$nheight;
$nheight = $iheight;
}
} else {
$nwidth = $iheight*$rratio;
$nheight = $iheight;
if ($nwidth>$iwidth) {
$nheight = $nheight*$iwidth/$nwidth;
$nwidth = $iwidth;
}
}
switch ($options['offsetType']) {
case 'percent':
$sx = ($iwidth-$nwidth)*$options['offsetLeft']/100;
$sy = ($iheight-$nheight)*$options['offsetTop']/100;
break;
default :
return false;
}
$rimage = imagecreatetruecolor($width, $height);
$image = imagecopyresampled($rimage, $image, 0, 0, $sx, $sy, $width, $height, $nwidth, $nheight);
break;
default :
return false;
break;
}
if (!is_writeable(dirname($destination))) {
throw new Exception(getcwd(). "/" .dirname($destination)." is not writeable");
}
switch ($options['output']) {
case 'file':
switch ($image_info[2]) {
case IMAGETYPE_JPEG:
return imagejpeg($rimage, $destination, $options['quality']);
case IMAGETYPE_PNG:
return imagepng($rimage, $destination, 0);
case IMAGETYPE_GIF:
return imagegif($rimage, $destination);
case IMAGETYPE_BMP:
return imagejpeg($rimage, $destination, $options['quality']);
default :
return false;
break;
}
return true;
break;
default :
return false;
break;
}
}
Example image causing the problem:
This image is successfully uploaded, but when I try to resize it, the resulting image is:
I call the function this way:
image_resize($ofile, $cfile, $width, $height, 'crop', 'jpeg');
Where $ofile
is the original file, $cfile
is the planned destination, $width
is the desired width (90 in this case), $height
is the desired height (90 in this case), 'crop'
is the selected strategy and 'jpeg'
is a certain $type
value, which is unused in the function (as I have mentioned, I have inherited the code). Also, the only example where the problem could be reproduced is the attached image, which is a png, other png files are uploaded correctly, so I do not understand the cause of the issue and do not know how to solve it. Can anybody describe the cause of the problem? I have searched and experimented for a long while without achieving success.
Upvotes: 0
Views: 108
Reputation: 1784
i tried your "image_resize" function with your bird picture, and it works perfectly fine on my computer, whether i set the source image to jpg or png, it works as expected :
However why not choosing "fit" instead of "crop" like so :
image_resize($ofile, $cfile, $width = 90, $height = 90, 'fit', 'jpeg');
Edit: based on other people's issues about getting black image after resizing PNG, this would be the correction:
function image_resize($source, $destination, $width, $height, $resizeMode='fit', $type = 'jpeg', $options = array()) {
$defaults = array(
'output' => 'file',
'isFile' => true,
'quality' => '100',
'preserveAnimation' => false,
'offsetTop' => 0,
'offsetLeft' => 0,
'offsetType' => 'percent'
);
foreach ($defaults as $k => $v) {
if (!isset($options[$k])) {
$options[$k] = $v;
}
}
if ($options['isFile']) {
$image_info = getimagesize($source);
$image = null;
switch ($image_info[2]) {
case IMAGETYPE_JPEG:
$image = imagecreatefromjpeg($source);
break;
case IMAGETYPE_PNG:
$image = imagecreatefrompng($source);
break;
case IMAGETYPE_GIF:
$image = imagecreatefromgif($source);
break;
case IMAGETYPE_BMP:
$image = imagecreatefromwbmp($source);
break;
default :
return false;
}
} else {
$image = imagecreatefromstring($source);
}
//we have an image resource
$iwidth = imagesx($image);
$iheight = imagesy($image);
//determine ratios
$wratio = $width / $iwidth;
$hratio = $height / $iheight;
$mratio = min(array($wratio, $hratio));
$rimage = null;
switch ($resizeMode) {
case 'fit':
$rimage = imagecreatetruecolor($iwidth * $mratio, $iheight * $mratio);
imagealphablending( $rimage, false );
imagesavealpha( $rimage, true );
$image = imagecopyresampled($rimage, $image, 0, 0, 0, 0, $iwidth * $mratio, $iheight * $mratio, $iwidth, $iheight);
break;
case 'crop':
$rratio = $width / $height;
if ($rratio < 1) {
$nwidth = $iwidth;
$nheight = $iwidth * 1/$rratio;
if ($nheight>$iheight) {
$nwidth = $nwidth*$iheight/$nheight;
$nheight = $iheight;
}
} else {
$nwidth = $iheight*$rratio;
$nheight = $iheight;
if ($nwidth>$iwidth) {
$nheight = $nheight*$iwidth/$nwidth;
$nwidth = $iwidth;
}
}
switch ($options['offsetType']) {
case 'percent':
$sx = ($iwidth-$nwidth)*$options['offsetLeft']/100;
$sy = ($iheight-$nheight)*$options['offsetTop']/100;
break;
default :
return false;
}
$rimage = imagecreatetruecolor($width, $height);
imagealphablending( $rimage, false );
imagesavealpha( $rimage, true );
$image = imagecopyresampled($rimage, $image, 0, 0, $sx, $sy, $width, $height, $nwidth, $nheight);
break;
default :
return false;
break;
}
if (!is_writeable(dirname($destination))) {
throw new Exception(getcwd(). "/" .dirname($destination)." is not writeable");
}
switch ($options['output']) {
case 'file':
switch ($image_info[2]) {
case IMAGETYPE_JPEG:
return imagejpeg($rimage, $destination, $options['quality']);
case IMAGETYPE_PNG:
return imagepng($rimage, $destination, 0);
case IMAGETYPE_GIF:
return imagegif($rimage, $destination);
case IMAGETYPE_BMP:
return imagejpeg($rimage, $destination, $options['quality']);
default :
return false;
break;
}
return true;
break;
default :
return false;
break;
}
}
Upvotes: 1