I have a $this->_tempFile that holds the temp path of an uploaded image file.
Now I wish to scale an image, it do resizes it but it doesn't scale right. The output is a big black square the bottom at the height and half of the image (width). And i tried with other images, and all turns out being these dimensions:
293px × 453px , why i don't know?
Here's my function for the scaleImage();
scaleImage(900, 582);
public function scaleImage($width, $height){
$rel_difference = array('width'=>0, 'height'=>0);
if($width > 604) $rel_difference['width'] = ($width-604)/604;
if($height > 453) $rel_difference['height'] = ($height-453)/453;
asort($rel_difference);
$tmpname = $this->_tempFile;
$newwidth = $width/(1+end($rel_difference));
$newheight = $height/(1+end($rel_difference));
$newwidth = round($newwidth);
$newheight = round($newheight);
$jpeg_quality = 90;
switch(exif_imagetype($tmpname)) {
case IMAGETYPE_GIF:
$img_r = imagecreatefromgif($tmpname);
break;
case IMAGETYPE_JPEG:
$img_r = imagecreatefromjpeg($tmpname);
break;
case IMAGETYPE_PNG:
$img_r = imagecreatefrompng($tmpname);
break;
default:
echo json_encode(array('error' => 'Not an image!'));
exit(0);
break;
}
$dst_r = ImageCreateTrueColor( $newwidth, $newheight );
imagecopyresampled($dst_r, $img_r, 0, 0, 0, 0, $newwidth , $newheight, $width, $height);
imagejpeg($dst_r,$tmpname,$jpeg_quality);
}
What is wrong here?
I suspect you have accidentally flipped the height and width in the parameters you're passing. So do
scaleImage(582, 900);
Related
Currently, I am resizing avatars on my server using PHP's resize_crop_image. The code below takes an image, crops and resizes it so that it's exactly 500px X 500px square.
resize_crop_image(500, 500, $filename, $filename);
But I'd like to move this process from the server to the flutter app. Most of the plugins I'm seeing on pub.dev are overkill with the user cropping the image using a crop tool. But I'd like this function to happen automatically the way I currently do it in PHP.
Here's the resize_crop_image code;
function resize_crop_image($max_width, $max_height, $source_file, $dst_dir, $quality = 100){
$imgsize = getimagesize($source_file);
$width = $imgsize[0];
$height = $imgsize[1];
$mime = $imgsize['mime'];
switch($mime){
case 'image/gif':
$image_create = "imagecreatefromgif";
$image = "imagegif";
break;
case 'image/png':
$image_create = "imagecreatefrompng";
$image = "imagepng";
$quality = 10;
break;
case 'image/jpeg':
$image_create = "imagecreatefromjpeg";
$image = "imagejpeg";
$quality = 100;
break;
default:
return false;
break;
}
$dst_img = imagecreatetruecolor($max_width, $max_height);
$src_img = $image_create($source_file);
$width_new = $height * $max_width / $max_height;
$height_new = $width * $max_height / $max_width;
//if the new width is greater than the actual width of the image, then the height is too large and the rest cut off, or vice versa
if($width_new > $width){
//cut point by height
$h_point = (($height - $height_new) / 2);
//copy image
imagecopyresampled($dst_img, $src_img, 0, 0, 0, $h_point, $max_width, $max_height, $width, $height_new);
}else{
//cut point by width
$w_point = (($width - $width_new) / 2);
imagecopyresampled($dst_img, $src_img, 0, 0, $w_point, 0, $max_width, $max_height, $width_new, $height);
}
$image($dst_img, $dst_dir, $quality);
if($dst_img)imagedestroy($dst_img);
if($src_img)imagedestroy($src_img);
}
?>
You could use this library: flutter_native_image for resizing/croping your images.
Important to take a look at the other parameters of this function, you can probably customize the way the image will be cropped.
Something like that:
ImageProperties properties = await FlutterNativeImage.getImageProperties(file.path);
File croppedFile = await FlutterNativeImage.cropImage(file.path, originX, originY, 500, 500);
originX/originY: x/y position for the cut.
I use this code in images.php to show the images :
imagepng($out);
and if i want to reduce the images quality for thumbnails i tried this code :
imagepng($out,$filename,$quality);
i want to know how to reduce image quality without saving.
function resize_image($file, $w, $h, $crop=false) {
list($width, $height) = getimagesize($file);
$r = $width / $height;
if ($crop) {
if ($width > $height) {
$width = ceil($width-($width*abs($r-$w/$h)));
} else {
$height = ceil($height-($height*abs($r-$w/$h)));
}
$newwidth = $w;
$newheight = $h;
} else {
if ($w/$h > $r) {
$newwidth = $h*$r;
$newheight = $h;
} else {
$newheight = $w/$r;
$newwidth = $w;
}
}
//Get file extension
$exploding = explode(".",$file);
$ext = end($exploding);
switch($ext){
case "png":
$src = imagecreatefrompng($file);
break;
case "jpeg":
case "jpg":
$src = imagecreatefromjpeg($file);
break;
case "gif":
$src = imagecreatefromgif($file);
break;
default:
$src = imagecreatefromjpeg($file);
break;
}
$dst = imagecreatetruecolor($newwidth, $newheight);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
return $dst;
}
$filename = "/var/www/images/mynormalimage.png";
$resizedFilename = "/var/www/images/myresizedimage.png";
// resize the image with 300x300
$imgData = resize_image($filename, 300, 300);
// save the image on the given filename
imagepng($imgData, $resizedFilename);
// or according to the original format, use another method
// imagejpeg($imgData, $resizedFilename);
// imagegif($imgData, $resizedFilename);
https://ourcodeworld.com/articles/read/197/how-to-resize-an-image-and-reduce-quality-in-php-without-imagickenter code here
I am trying to resize an image after uploading but the image is always converted to black. Though the image has the right dimension, it just shows black. I'm not sure where I messed up. I already searched SO to no avail.
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $full_path)){
$orig_image = imagecreatefromjpeg($full_path);
$image_info = getimagesize($full_path);
$width_orig = $image_info[0]; // current width as found in image file
$height_orig = $image_info[1]; // current height as found in image file
if($width_orig > $height_orig){
$width = 105;
$ratio = $width/$width_orig;
$height = $height_orig*$ratio;
}else{
$height = 360;
$ratio = $height/$height_orig;
$width = $width_orig*$ratio;
}
$destination_image = imagecreatetruecolor($width, $height);
imagecopyresampled($destination_image, $orig_image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
imagejpeg($destination_image, $full_path, 100);
}
Check image type before function imagecreatefromjpeg() to be shure.
Something like this:
$image_type = exif_imagetype($full_path);
switch ($image_type)
{
case IMAGETYPE_GIF : $orig_image = imagecreatefromgif($file); break;
case IMAGETYPE_JPEG : $orig_image = imagecreatefromjpeg($file); break;
case IMAGETYPE_PNG : $orig_image = imagecreatefrompng($file); break;
//...
default: echo 'Wrong image type'; break;
}
I want to make a thumbnail(64X64) of images uploaded by user to reduce the overall page size. I did it using the following PHP code, But the result is really disappointing! in one instance the original file size was 554 byte (70X70). by converting it to a 64X64 image, the file size has increase to 1.43 KB! while the quality of the image is terribly degraded.
What is wrong here? Isn't it any other way to resize the images by PHP and have a better output?
Thank you very much
function image_resize($src, $dst, $width, $height, $crop=0){
if(!list($w, $h) = getimagesize($src)) return "Unsupported picture type!";
$type = strtolower(substr(strrchr($src,"."),1));
if($type == 'jpeg') $type = 'jpg';
switch($type){
case 'bmp': $img = imagecreatefromwbmp($src); break;
case 'gif': $img = imagecreatefromgif($src); break;
case 'jpg': $img = imagecreatefromjpeg($src); break;
case 'png': $img = imagecreatefrompng($src); break;
default : return "Unsupported picture type!";
}
// resize
if($crop){
if($w < $width or $h < $height) return "Picture is too small!";
$ratio = max($width/$w, $height/$h);
$h = $height / $ratio;
$x = ($w - $width / $ratio) / 2;
$w = $width / $ratio;
}
else{
if($w < $width and $h < $height) return "Picture is too small!";
$ratio = min($width/$w, $height/$h);
$width = $w * $ratio;
$height = $h * $ratio;
$x = 0;
}
$new = imagecreatetruecolor($width, $height);
// preserve transparency
if($type == "gif" or $type == "png"){
imagecolortransparent($new, imagecolorallocatealpha($new, 0, 0, 0, 127));
imagealphablending($new, false);
imagesavealpha($new, true);
}
imagecopyresampled($new, $img, 0, 0, $x, 0, $width, $height, $w, $h);
switch($type){
case 'bmp': imagewbmp($new, $dst); break;
case 'gif': imagegif($new, $dst); break;
case 'jpg': imagejpeg($new, $dst); break;
case 'png': imagepng($new, $dst); break;
}
return true;
}
I think that probably nothing is wrong here. 1.43KB is not very much, so it's not clear that the image produced is inefficiently stored. As for image quality, we're talking about a very small image; resizing from 70x70 to 64x64 is very likely to produce an odd-looking result. If you have a larger image to start with then it will probably work better.
There are other PHP image libraries (e.g. WideImage), but I'd be surprised if using them would make a great deal of difference here. In fact they probably use GD internally anyway.
When resizing some png images they appear stretched and have what looks like vertical interlacing. I'm unsure of where the issue could be, however I'm starting to think its because the image starts in grayscale and needs to have a different color profile.
Any help or suggestions would be greatly appreciated.
Original image
Image showing the problem
function createImageSize($sourcefile, $setNewName, $maxwidth, $maxheight, $quality){
$fileInfoArray = #getimagesize($sourcefile);
$imagetype = $fileInfoArray['mime'];
list($width, $height, $attr) = getimagesize($sourcefile);
switch($imagetype){
case 'image/jpeg':
$img = imagecreatefromjpeg($sourcefile);
break;
case 'image/gif':
$img = imagecreatefromgif($sourcefile);
break;
case 'image/png':
$img = imagecreatefrompng($sourcefile);
break;
case 'image/x-png':
$img = imagecreatefrompng($sourcefile);
break;
}
if ($width > $maxwidth || $height > $maxheight){
if ( $width > $height ){
$newwidth = $maxwidth;
$ratio = $maxwidth / $width;
$newheight = floor($height * $ratio);
if ($newheight > $maxheight){
$newheight = $maxheight;
$ratio = $maxheight / $height;
$newwidth = floor($width * $ratio);
}
}else{
$newheight = $maxheight;
$ratio = $maxheight / $height;
$newwidth = floor($width * $ratio);
if ($newwidth > $maxwidth){
$newwidth = $maxwidth;
$ratio = $maxwidth / $width;
$newheight = floor($height * $ratio);
}
}
}else{
$newwidth = $width;
$newheight = $height;
}
$tmpimg = imagecreatetruecolor( $newwidth, $newheight );
if($imagetype == 'image/png'||$imagetype == 'image/x-png'){
imagealphablending($tmpimg, false);
imagesavealpha($tmpimg, true);
if($imagetype == 'image/gif'){
$transparent = imagecolorallocatealpha($tmpimg, 0, 0, 0, 127);
imagecolortransparent($tmpimg, $transparent);
}
imagefilledrectangle($tmpimg, 0, 0, $newwidth, $newheight, $transparent);
}
imagecopyresampled( $tmpimg, $img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height );
switch($imagetype){
case 'image/jpeg':
imagejpeg($tmpimg, $setNewName, $quality);
break;
case 'image/gif':
imagegif($tmpimg, $setNewName);
break;
case 'image/png':
imagepng($tmpimg, $setNewName, 3);
break;
case 'image/x-png':
imagepng($tmpimg, $setNewName, 3);
break;
}
imagedestroy($tmpimg);
imagedestroy($img);
}
I had the same problem. While generating EPS files into transparent PNG files (to use as mask images later), iMagick created the PNG files as grayscale. When GD reads grayscale PNGs, it doubles them horizontally with vertical lines in them.
My solution was handled on the iMagic side, by forcing it to write the PNGs as RGBA:
before:
$image->setImageFileName("image.png");
After:
$image->setImageFileName("png32:image.png");
I don't know where your grayscale PNGs are coming from, but if you are generating them, make sure they are created RGBA. Otherwise perhaps there is a way to read them with GD properly, specifying grayscale source.
I have the same issue and still haven't found any solutions. It would seem that GD doesn't like grayscale PNG8 images and is interpreting as colored.
I may have to convert the image back to 24 bits using "convert" with exec() and then delete the image, but it's far from optimal.