Image creating functions not working on https - php

I am working on project on php and created a module for cropping a image. My code for cropping image is:
$targ_w = 400;
$targ_h = 400;
$jpeg_quality = 90;
$src = "PATH_OF_ORIGINAL_IMAGE";
$filename = pathinfo($src);
$extension = $filename['extension'];
if($extension == 'jpg' || $extension == 'jpeg')
{
$img_r = imagecreatefromjpeg($src);
}
if($extension == 'png')
{
$img_r = imagecreatefrompng($src);
}
if($extension == 'gif')
{
$img_r = imagecreatefromgif($src);
}
$dst_r = ImageCreateTrueColor( $targ_w, $targ_h );
$imageName = "cropped.jpeg";
imagecopyresampled($dst_r,$img_r,0,0,600,600,$targ_w,$targ_h,600,600);
$path = "PATH_FOR_NEW_IMAGE".$imageName;
header('Content-type: image/jpeg');
imagejpeg($dst_r,$path,$jpeg_quality);
This code is working great and cropping image with provided details. But I had moved my website from http to https, This code stops working. No error is displaying and creating image. But images are blank and black image. When I moved website back to http it's again starts working. But I want my website to be on https. I have two questions and they are:
Why is the created image blank?
If it's server issue how can I solve this?

Looking at your answer I think you are loading your $src from an url.
I would try downloading the file before manipulating it, like this:
$context = stream_context_create(["ssl" => [
"verify_peer" => false,
"verify_peer_name" => false]
]);
$fileContent = file_get_contents($src, false, $context);
Then you can create your image with:
$img_r = imagecreatefromstring($fileContent);
Without checking the extension, it will return a valid image resource or false if the content of the string is not an image.
With this method you avoid also errors occurring where a png image is renamed with jpg extension.
Note that you are disabling ssl check and it could be a security hole.

Would you consider handling the cropping (and perhaps other image manipulation operations) via a service that can also serve the processed image using HTTPS to your users via a fast CDN? e.g. http://cloudinary.com/documentation/php_integration#display_and_manipulate_images

Related

Compress & resize images using PHP GD lib not working for png and weird results for jpg

I am trying to compress & resize my images using the php GD library. Nearly every answer on SO and everywhere else is the same, but for my solution, the PNG's are not being correctly transformed, and some jpg's are giving bizarre results.
This is the code I am using:
public function resizeImages() {
ini_set('max_execution_time', 0);
//Initial settings, Just specify Source and Destination Image folder.
$ImagesDirectory = FCPATH . 'design/img/test/'; //Source Image Directory End with Slash
$DestImagesDirectory = FCPATH . 'design/img/test/thumb/'; //Destination Image Directory End with Slash
$NewImageWidth = 150; //New Width of Image
$NewImageHeight = 150; // New Height of Image
$Quality = 90; //Image Quality
//Open Source Image directory, loop through each Image and resize it.
if($dir = opendir($ImagesDirectory)){
while(($file = readdir($dir))!== false){
$imagePath = $ImagesDirectory.$file;
$destPath = $DestImagesDirectory.$file;
$checkValidImage = #getimagesize($imagePath);
if(file_exists($imagePath) && $checkValidImage) //Continue only if 2 given parameters are true
{
//Image looks valid, resize.
if (resize_image($imagePath,$destPath,$NewImageWidth,$NewImageHeight,$Quality))
{
echo $file.' resize Success!<br />';
/*
Now Image is resized, may be save information in database?
*/
} else {
echo $file.' resize Failed!<br />';
}
}
}
closedir($dir);
}
}
and the resize_image function looks like this:
function resize_image($SrcImage,$DestImage, $MaxWidth,$MaxHeight,$Quality)
{
list($iWidth,$iHeight,$type) = getimagesize($SrcImage);
$ImageScale = min($MaxWidth/$iWidth, $MaxHeight/$iHeight);
$NewWidth = ceil($ImageScale*$iWidth);
$NewHeight = ceil($ImageScale*$iHeight);
$NewCanves = imagecreatetruecolor($NewWidth, $NewHeight);
$imagetype = strtolower(image_type_to_mime_type($type));
switch($imagetype)
{
case 'image/jpeg':
$NewImage = imagecreatefromjpeg($SrcImage);
break;
case 'image/png':
$NewImage = imagecreatefrompng($SrcImage);
break;
default:
return false;
}
//allow transparency for pngs
imagealphablending($NewCanves, false);
imagesavealpha($NewCanves, true);
// Resize Image
if(imagecopyresampled($NewCanves, $NewImage,0, 0, 0, 0, $NewWidth, $NewHeight, $iWidth, $iHeight))
{
switch ($imagetype) {
case 'image/jpeg':
if(imagejpeg($NewCanves,$DestImage,$Quality))
{
imagedestroy($NewCanves);
}
break;
case 'image/png':
if(imagepng($NewCanves,$DestImage,$Quality))
{
imagedestroy($NewCanves);
}
break;
default:
return false;
}
return true;
}
}
Every single png is not working, it just returns a file with 0 bytes and "file type is not supported", even though the type is recognized as .PNG in Windows...
Some JPG's return a weird result as well, see the following screenshot which indicates my issues regarding png's and some jpg's:
1) Do not use getimagesize to verify that the file is a valid image, to mention the manual:
Do not use getimagesize() to check that a given file is a valid image. Use a purpose-built solution such as the Fileinfo extension instead.
$checkValidImage = exif_imagetype($imagePath);
if(file_exists($imagePath) && ($checkValidImage == IMAGETYPE_JPEG || $checkValidImage == IMAGETYPE_PNG))
2) While imagejpeg() accepts quality from 0 to 100, imagepng() wants values between 0 and 9, you could do something like that:
if(imagepng($NewCanves,$DestImage,round(($Quality/100)*9)))
3) Using readdir () you should skip the current directory . and the parent..
while(($file = readdir($dir))!== false){
if ($file == "." || $file == "..")
continue;
edit
Point 2 is particularly important, imagepng () accepts values greater than 9 but then often fails with error in zlib or libpng generating corrupt png files.
I tried resizing some png and jpeg and I didn't encounter any problems with these changes.

How to compress image file size laravel

I have some images in my S3 bucket on AWS. I am trying to get the images and send them to my android app (along with other information from my database). My current setup works fine but I would like to reduce the image file sizes (currently around 1-1.5mb) before I send them to the app.
I have tried to use this code:
function compress($source, $destination, $quality) {
$info = getimagesize($source);
if ($info['mime'] == 'image/jpeg')
$image = imagecreatefromjpeg($source);
elseif ($info['mime'] == 'image/gif')
$image = imagecreatefromgif($source);
elseif ($info['mime'] == 'image/png')
$image = imagecreatefrompng($source);
imagejpeg($image, $destination, $quality);
return $destination;
}
$image_file = Storage::disk('s3_upload')->get("s3bucketpath");
$new_image_file = $this->replace_extension($image->filename, '.jpg');
$this->compress($image_file,$new_image_file, 50);
I get
failed to open stream: No such file or directory in file
error from
$info = getimagesize($source);
I have checked the file path and it is in the bucket and exists and I have var-dumped source and gotten
����JFIF��C$<'$!!$J58,<XM\[VMUSam�vag�hSUy�z������^t�����������C$ $G''G�dUd����������������������������������������������������#0"����A!1A"Q2aq#B���3R�$4b�rC���%S���5D�����#!1A2"Q#��?��HS-�  B�#)( #�
#!#������(��(� �
#�UF�LHU#�d ��
# �)#RB�(R�E]��(
(� #B'...
What is the best way to go about doing this.
Try http://image.intervention.io/ to compress file.
It is simple and efficient.
Compression details:
http://image.intervention.io/api/encode
How to start? Simply:
// include composer autoload
require 'vendor/autoload.php';
// import the Intervention Image Manager Class
use Intervention\Image\ImageManager;
// create an image manager instance with favored driver
$manager = new ImageManager(array('driver' => 'imagick'));
// to finally create image instances
$image = $manager->make('public/foo.jpg')->resize(300, 200);
If you are really serious about compressing and resizing your images, you can use libraries like PNGQuant for PNG compression without losing the quality and jpegoptim for jpeg images.

creating thumbnails on image upload - 'SOME' are black, yet others are ok

I have the following image upload script, that uploads an image, renames and resizes a thumbnail too. When uploading image (all JPG) some upload and display fine, yet others upload the main image fine but the thumbnail is just a black square.
Does anyone have any idea as to what the problem is?
[edit] I have added PNG to the filetypes, and it uploads correctly, however 'real' JPG files now upload the black thumbnail. I am thinking that I need to somehow check the file extension and apply imagecreatefromjpeg/imagecreatefrompng based on what is returned?
if this is the case, i am thinking an if/else statement where highlighted will do? - not sure what to check against to get the extension (jpg/png) though...
if(isset($_POST['submit'])){
// get file info
$file = $_FILES['file'];
$fileName = $_FILES['file']['name'];
$fileTmpName = $_FILES['file']['tmp_name'];
$fileSize = $_FILES['file']['size'];
$thumbName = $_FILES['file']['name']; //
$thumbTmpName = $_FILES['file']['tmp_name']; //
$thumbSize = $_FILES['file']['size']; //
$fileError = $_FILES['file']['error'];
$fileType = $_FILES['file']['type'];
//allow file types
$fileExt = explode('.', $fileName);
$fileActualExt = strtolower(end($fileExt));
$allowed = array('jpg', 'jpeg', 'png'); // ADDED PNG HERE
if(in_array($fileActualExt, $allowed)){
if($fileError === 0){
if($fileSize < 1000000){
$fileNameNew = $row['item_img'].".".$fileActualExt; //code!
$fileDestination = 'images/'.$col_id.'/'.$fileNameNew; //number
move_uploaded_file($fileTmpName, $fileDestination);
// if(???){ // START POSSIBLE IF/ELSE HERE?
// create thumbnail
$src = imagecreatefromjpeg($fileDestination);
list($width, $height) = getimagesize($fileDestination);
$thumbWidth = 100;
$thumbHeight = 100;
// } else { // POSSIBLE ELSE HERE?
// ADDED THIS FOR PNG
$src = imagecreatefrompng($fileDestination);
list($width, $height) = getimagesize($fileDestination);
$thumbWidth = 100;
$thumbHeight = 100;
// } // END POSSIBLE IF/ELSE HERE?
$tmp = imagecreatetruecolor($thumbWidth,$thumbHeight);
imagecopyresampled($tmp, $src, 0,0,0,0, $thumbWidth, $thumbHeight, $width, $height);
imagejpeg($tmp, 'images/'.$col_id.'/thumbs/'.$fileNameNew.'', 100);
imagedestroy($src);
imagedestroy($tmp);
//CHECK FOR IMAGE
$checkImgQuery = $db->prepare("SELECT item_image.item_image, item_item.item_id FROM item_image JOIN item_item ON item_item.item_img = item_image.item_image WHERE item_id = :item_id");
$checkImgQuery->execute(array(':item_id' => $item_id));
$check = $checkImgQuery->rowCount();
if($check > 0){
// UPDATE
} else {
// ADD
}
} else {
$error[] = 'your file is too big';
}
} else {
$error[] = 'there was an error uploading your file';
}
} else {
$error[] = 'you cannot upload files of this type';
}
}
Since it is not always happening, this is almost certain to come from the files, as they are the only thing that changes... I'm guessing your jpeg files are either corrupted (but not enough to not display the picture, but maybe make the PHP code crash) or they simply aren't real jpegs...
Here's what I'd recommend: There is no need to force the users on only one file type while PHP alone can handle multiple, so we can check the mime type and act accordingly.
switch(mime_content_type($fileDestination){
case 'image/jpeg':
$src = imagecreatefromjpeg($fileDestination);
break;
case 'image/png':
$src = imagecreatefrompng($fileDestination);
break;
case 'image/gif':
$src = imagecreatefromgif($fileDestination);
break;
default:
$error[] = 'your file is not of a recognized type';
}
if(isset($src)){
//do what you were doing.
}
So we test the mime type and use the corresponding function. Not that I did not include everything, but that should be a good start.
If you want an easier implementation, you could use this:
$src = imagecreatefromstring(file_get_content($fileDestination));
When creating an image from a string, the type is automatically detected. This would return false if the file is not recognized.
You will want to be careful with transparency when saving from PNG to JPG... But I'll leave that part to you.

imagecreatefromjpeg() returns a black image when resized

I have following code
// load image and get image size
$img = imagecreatefrompng( "{$pathToImages}{$fname}" );
$width = imagesx( $img );
$height = imagesy( $img );
// calculate thumbnail size
$new_width = $imageWidth;
$new_height = 500;
// create a new temporary image
$tmp_img = imagecreatetruecolor( $new_width, $new_height );
// copy and resize old image into new image
imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );
It works fine with some images..but with certain images it shows an error like
Warning: imagecreatefromjpeg() [function.imagecreatefromjpeg]: gd-jpeg: JPEG library reports unrecoverable error:
Warning: imagesx() expects parameter 1 to be resource, boolean given
Warning: imagesy() expects parameter 1 to be resource, boolean given
I have also enabled
gd.jpeg_ignore_warning = 1
in php.ini
Any help appreciated.
According to a blog post from (Feb 2010) its a bug in the implementation of imagecreatefromjpeg which should return false but throws an error instead.
The solution is to check for the filetype of your image (I removed the duplicate call to imagecreatefromjpeg because its totally superfluous; we already check for right file type before and if an error occurs due to some other reason, imagecreatefromjpeg will return false correctly):
function imagecreatefromjpeg_if_correct($file_tempname) {
$file_dimensions = getimagesize($file_tempname);
$file_type = strtolower($file_dimensions['mime']);
if ($file_type == 'image/jpeg' || $file_type == 'image/pjpeg'){
$im = imagecreatefromjpeg($file_tempname);
return $im;
}
return false;
}
Then you can write your code like this:
$img = imagecreatefrompng_if_correct("{$pathToImages}{$fname}");
if ($img == false) {
// report some error
} else {
// enter all your other functions here, because everything is ok
}
Of course you can do the same for png, if you want to open a png file (like your code suggests). Actually, usually you will check which filetype your file really has and then call the correct function between the three (jpeg, png, gif).
Please see PHP Bug #39918 imagecreatefromjpeg doesn't work. The suggestion is to change the GD setting for jpeg image loading:
ini_set("gd.jpeg_ignore_warning", 1);
You then additionally need to check the return value from the imagecreatefromjpegDocs call:
$img = imagecreatefromjpeg($file);
if (!$img) {
printf("Failed to load jpeg image \"%s\".\n", $file);
die();
}
Also please see the potentially duplicate question:
the dreaded “Warning: imagecreatefromjpeg() : '/tmp/filename' is not a valid JPEG file in /phpfile.php on line xxx”
It has nearly the same error description like yours.
My solution for this issue: detect if imagecreatefromjpeg returns 'false' and in that case use imagecreatefromstring on file_get_contents instead.
Worked for me.
See code sample below:
$ind=0;
do{
if($mime == 'image/jpeg'){
$img = imagecreatefromjpeg($image_url_to_upload);
}elseif ($mime == 'image/png') {
$img = imagecreatefrompng($image_url_to_upload);
}
if ($img===false){
echo "imagecreatefromjpeg error!\n";
}
if ($img===false){
$img = imagecreatefromstring(file_get_contents($image_url_to_upload));
}
if ($img===false){
echo "imagecreatefromstring error!\n";
}
$ind++;
}while($img===false&&$ind<5);
Could you give any example of files that do / don't work?
According to http://www.php.net/manual/en/function.imagecreatefromjpeg.php#100338 blanks in remote filenamnes might cause issues.
In case you're using an URL as the source of the image, you will need to make sure the php setting allow_url_fopen is enabled.

getting blank 'temp_name' in image upload

I'm working in my site which is in zen cart, actually a want to add a little functionality on it, and that is.... When I upload a image for a product I also want to create a thumbnail size of that image to be in a folder. Now I tried to search a file where the code to upload image goes on... I found a file in htdocs/admin_folder/includes/modules/new_product_preview.php
Now after getting details from user from a page htdocs/admin_folder/product.php it form post it in new_product_review.php page with a action defined in it and here the code for uploading image I've just simply added code as follows but it is not uploading the image in folder.
I've tried to echo the name of the file, so I've just put the alert for the image name parameters, I'm getting the $_FILES["products_image"]["tmp_name"] as something like, /tmp/gsnVaX.. like but
when I check $_FILES["products_image"]["name"] it gives the correct name of the file...
Why its not putting the image in temporary folder? When I put the resize code on it then it saves image in my folder with the same size which I wanted but whole image is just blank black.
Code is:
$image = "../images/thumbs/anki_".$_FILES["products_image"]["name"];
move_uploaded_file($_FILES["products_image"]["tmp_name"],$image);
and code when I'm doing this through resize is:
$control = "products_image";
$fileName = $_FILES[$control]['name'];
$uploadedfile = $_FILES[$control]['tmp_name'];
echo "<script>alert('".$fileName."');</script>";
$exts = explode(".",$fileName);
$ext = array_pop($exts);
$uploadedfile = $_FILES[$control]['name'];
$extension = $ext;
$extension = strtolower($extension);
if($extension=="jpg" || $extension=="jpeg" )
{
$src = imagecreatefromjpeg($uploadedfile);
}
else if($extension=="png")
{
$src = imagecreatefrompng($uploadedfile);
}
else
{
$src = imagecreatefromgif($uploadedfile);
}
$newwidth = 140;
list($width,$height)=getimagesize($uploadedfile);
$newheight=($height/$width)*$newwidth;
$newheight = 135;
$tmp=imagecreatetruecolor($newwidth,$newheight);
imagecopyresampled($tmp,$src,0,0,0,0,$newwidth,$newheight,$width,$height);
$filename = "../images/thumbs/". $fileName;
imagejpeg($tmp,$filename,100);
imagedestroy($src);
imagedestroy($tmp);
What am I doing wrong with it?

Categories