imagecopyresampled results to black square image, but imagescale is fine - php

I have a straightforward PHP script (php version 7+) that I run to resize images to a smaller dimension around 1200px wide ...
I use imagecreatefromjpeg and imagecopyresampled method and the save new file with imagejpeg # 88% compression.
I and ran over 100 images through it and most images worked out great, except for a few stubborn images that results to BLACK square image.
I tried imagecopyresized and played with different new dimensions but it just didnt work. I even tried outputting the ob stream from these tests at the point of resizing instead of saving to file (no compressions applied) and i can confirm that the moment the image was resized, it is already black square.
On the images that produces black square the result is false.
I did verify mime type IMAGETYPE_JPEG of file, regardless of file extension, before running the code.
Now, I tried running the same files thru imagescale instead
$new_img = imagescale($img, $new_width, $new_height, IMG_SINC );
and that worked.
Now I prefer to use the previous method for better more crispier output so I've been trying to get it to work :(
Why is this happening? I searched stack for similar issues but they are describing a issues that completely didnt work on any images, not my case, where only a select few images had issues.
I am dealing with JPG only, but is it possible that the jpg file is just named with extension ".jpg" but actually a png, bmp, or something else? Will that cause issues?
I'm stuck, and i hope you guys can help.
Thank you
Most images resized nicely

Related

How to Combine/merge two image using PHP imagecopy() or imagecopymerge()?

Please help to combine three jpg images using php image processing functions imagecopy, imagecopymerge
image 1- b.jpg
image 2- l.jpg
image3: r.jpg
output look like
I tried some example codes of the PHP functions imagecopy() or imagecopymerge()
but not working with my images.
Could you give more information about: "not working"
I would suggest you to take a look at: imagecopyresampled
For the code, you have to load the images as image ressources, so you can use something like:
$im1 = imagecreatefrompng($path.'image1.png');
$im2 = imagecreatefrompng($path.'image2.png');
imagecopyresampled($im1,$im2,250,150,0,0,100,150,100,150);
unset($im2);
$im3 = imagecreatefrompng($path.'image3.png');
imagecopyresampled($im1,$im3,550,150,0,0,100,150,100,150);
unset($im3);
So $im1 now have the 3 images.
Just make sure to unset the image ressources, because you will run out of memory really fast.
Edit: I used imagecopyresampled because image 2-3 seem smaller on the last image, I don't know how more resource intensive it is, I guess imagecopymerge could work too.

cropping an image via a php file

so i have an image that is originally 1696x1696. i want to use a php file to MIME a png file. what i want the php to do is crop the original file and produce a quarter of the image. Later i plan to use $_GET variables to return which quadrant i want, but for testing/debugging, im just aiming to get the top left quadrant.
here's the code:
Header("Content-type:image/png");
$newImg =imagecreatefrompng('test.png');
//manually entered half height and width
$img=imagecreatetruecolor(848,848);
//here is where the bugs keep flawing the image
imagecopyresampled($img,$newImg,0,0,0,0,1696,1696,1696,1696);
imagepng($img);
imagedestroy($img);
this will produce the image (top, left) like it's supposed to, however it adds several smaller resampled images on top of it. no matter how i toy with it, i cant get it right. i've also tried imagecopy() and cant get it right as well. looked up tutorials and i cant seem to find on that helps.
Your code looks fine. The only thing I would change is to use imagecopyresized() instead of imagecopyresampled() in this use case.
Header("Content-type:image/png");
$source = imagecreatefrompng('images/test.png');
// manually entered half height and width
$thumb = imagecreatetruecolor(848,848);
imagecopyresized($thumb, $source, 0, 0, 0, 0, 1696, 1696, 1696, 1696);
imagepng($thumb);
imagedestroy($thumb);
I am guessing that earlier in your tests, you were overwriting your original image. That would explain the...
however it adds several smaller resampled images on top of it...
...part of your experience. Each time you ran the code, you picked up the previously modified file.
ok, so after enough headbanging and hair-tearing out, i decided to just go back to photoshop and overwrite the .png with my original .psd. starting to get somewhere now. i got my quadrant without all the ridiculousness. when i get a better understanding, i might come back and explain where i kept going wrong

Taking care of transparency using IMagick via PHP makes some images darker

I have a script that handles/scales uploaded images. I noticed that some of the images come out significantly darkened, and through a process of elimination tracked the darkening back to this section of code:
$scaled = new IMagick();
$scaled->newPseudoImage($original->getImageWidth(), $original->getImageHeight(), 'xc:white');
$scaled->compositeImage($original, Imagick::COMPOSITE_DEFAULT, 0, 0);
$scaled->flattenImages();
What I'm doing here is trying to eliminate issues with transparent backgrounds in some images coming through as black when I convert to jpg.
Does anyone have any idea which part of this code is darkening the image and what a good way to fix it might be?
Edit: Still haven't figured out the heart of this issue, but I did find that I can avoid doing this to images that don't need it by wrapping it in:
if($original->getImageAlphaChannel()){

PHP Imagick - convert image to greyscale (very bad result)

I was doing some image editing with PHP, since GD provides less functionalities, I switched to Imagick.
One of the processes is to greyscale images. Everything went fine (locally on Windows 7, Imagick 2.2.1-dev 6.5.8-7 Q16) till I uploaded the script to my web hosting server (Linux, Imagick 3.0.1, 6.2.8, 2010-10-20, Q16).
I'v tried to change the quality, but it didn't improve anything.
$img->setImageCompression(imagick::COMPRESSION_JPEG);
$img->setImageCompressionQuality(100);
Here is the results from GD, Imagick and Photoshop
I believe something's wrong with version 3.0.1. Can someone please confirm that?
Q1: Is there an alternative way to convert an image to greyscale with Imagick?
Q2: Is it possible to convert a GD resource to Imagick? So I can use imagefilter($img, IMG_FILTER_GRAYSCALE); to get the correct result and then output with Imagick.
ps: For Q2, you might suggest me to just use GD to process the image. But the problem is that imagejpeg() cannot save images with resolution preserved. and that is actually the reason I switched to Imagick.
This is my preferred way to make a B&W photo in php/imagick: $im = $im->fxImage('intensity');
That applies a function to the image, where intensity is equal to 0.299*red+0.587*green+0.114*blue.
That formula is based on how our eyes are more sensitive to different colours, and as such the difference between that and a "flat" grayscale image really is night and day.
More details here:
http://php.net/manual/en/imagick.fximage.php
http://www.imagemagick.org/script/fx.php
function ImagickToGD($imagick){
$tmpfile = tmpfile();
$imagick->writeImage($tmpfile);
return imagecreatefromstring(file_get_contents($tmpfile));
}
Note that this function does not do any cleanup (except the temp file, which PHP cleans automatically).
So, for example, your code should look like:
$img = new Imagick();
// ...
$gd = ImagickToGD($img);
unset($img); // destroy imagick
imagefilter($gd, IMG_FILTER_GRAYSCALE);
imagejpeg($gd, $target_name, 100);
imagedestroy($gd);
Also, I did not understand the part about "preserving resolution". There is nothing in these operations relating to resolution. My guess is you meant compression? If you want full quality (ie, no compression) simply use 100 as compression value (as I did).
This results in maintaining the existing quality, since opening an image of 70% quality and saving it back with 70% quality actually decreases the final quality by 49% (70% of 70%).
function GDToImagickTo($gd){
$tmpfile = tmpfile();
imagepng($tmpfile); // Png is our best image deal:
// lossless compression, transparency etc..
$imagick = new Imagick()
$imagick->readImage($tmpfile);
return $imagick;
}
Refer this website and check out the image Magick operators found here www.rubblewebs.co.uk/imagemagick/
Also go with www.fmwconcepts.com/imagemagick/ you will find some examples out here...
You can use the image class what you prefer and then use the method readImageBlob to send it to the imagick http://www.php.net/manual/en/imagick.readimageblob.php

How to compress images in CodeIgniter, yet do not change their dimensions?

I have a site where users can upload images. I process these images directly and resize them into 5 additional formats using the CodeIgniter Image Manipulation class. I do this quite efficiently as follow:
I always resize from the previous format, instead of from the original
I resize using an image quality of 90% which about halves the file size of jpegs
The above way of doing things I implemented after advise I got from another question I asked. My test case is a 1.6MB JPEG in RGB mode with a high resolution of 3872 x 2592. For that image, which is kind of borderline case, the resize process in total takes about 2 secs, which is acceptable to me.
Now, only one challenge remains. I want the original file to be compressed using that 90% quality but without resizing it. The idea being that that file too will take half the file size. I figured I could simply resize it to its' current dimensions, but that doesn't seem to do anything to the file or its size. Here's my code, somewhat simplified:
$sourceimage = "test.jpg";
$resize_settings['image_library'] = 'gd2';
$resize_settings['source_image'] = $sourceimage;
$resize_settings['maintain_ratio'] = false;
$resize_settings['quality'] = '90%';
$this->load->library('image_lib', $resize_settings);
$resize_settings['width'] = $imagefile['width'];
$resize_settings['height'] = $imagefile['height'];
$resize_settings['new_image'] = $filename;
$this->image_lib->initialize($resize_settings);
$this->image_lib->resize();
The above code works fine for all formats except the original. I tried debugging into the CI class to see why nothing happens and I noticed that the script detects that the dimensions did not change. Next, it simply makes a copy of that file without processing it at all. I commented that piece of code to force it to resize but now still nothing happens.
Does anybody know how to compress an image (any image, not just jpegs) to 90% using the CI class without changing the dimensions?
I guess you could do something like this:
$original_size = getimagesize('/path/to/original.jpg');
And then set the following options like this:
$resize_settings['width'] = $original_size[0];
$resize_settings['height'] = $original_size[1];
Ok, so that doesn't work due to CI trying to be smart, the way I see it you've three possible options:
Rotate the Image by 360ยบ
Watermark the Image (with a 1x1 Transparent Image)
Do It Yourself
The DIY approach is really simple, I know you don't want to use "custom" functions but take a look:
ImageJPEG(ImageCreateFromString(file_get_contents('/path/to/original.jpg')), '/where/to/save/optimized.jpg', 90);
As you can see, it's even more simpler than using CI.
PS: The snippet above can open any type of image (GIF, PNG and JPEG) and it always saves the image as JPEG with 90% of quality, I believe this is what you're trying to archive.

Categories