I've a local server running a website with IIS.
When i run (move_uploaded_file($tempfile, $uploadfile)) all goes well (POST method used).
Now i wish to compress the image, here is the code:
// Compress image
function compressImage($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);
}
$foo= compressImage($tempfile, $uploadfile, 75);
who gives me 500 error.
Should i enable some plugin on the server side? I've tried a bunch of code, it still doesn't work (i've played also with dir names.. actually they goes well with move_uploaded_file)
edit: strange thing, the $tempfile content is: C:WindowsTempphp92AF.tmp without slashes, but it works moving the file....
$uploadfile instead, is: ../../../Users/admin/Documents/uploads/2image.png
And so.. i've figured out!
request tracing was not so useful (for me). Instead i've added those 2 small lines to my php code to log errors:
ini_set('display_errors',1);
error_reporting(E_ALL);
The first was
Fatal error: Uncaught Error: Call to undefined function
imagecreatefromjpeg() in C:\inet
Resolved with:
extension=php_gd.dll
in php.ini. Then another error about the permissions.
FYI
Related
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.
I am trying to get filesize of images from a specific folder AFTER and BEFORE they are optimized.
I get same size for $imgsize as well as $newsize even though the latter appears AFTER they images are optimized. What i actually want is that it gets me the NEW size, not the old!
$array has the list of URLs for images (absolute URLs, belongs to another server)
(also let me know, is this fine that i'm replacing the same image after optimizing size in this part $optimized_image= compress_image($path, $path, 50); ) ?
Here is my code:
$f_path='newfolder';
foreach ($array as $imglink)
{
$image = file_get_contents($imglink);
$path= $f_path . "/" . basename($imglink);
$new_image=file_put_contents($path , $image);
$imgsize = filesize($path);
$optimized_image= compress_image($path, $path, 50);
$newsize = filesize($path);
$percentage = ($imgsize / $newsize)*100;
echo $imgsize . "<br/>"; //this size appears fine
echo $newsize; //gives same size as above, no change!
}
And here is the function i'm using for compressing image (which seem to work perfectly fine to me)
function compress_image($src, $dest , $quality)
{
$info = getimagesize($src);
if ($info['mime'] == 'image/jpeg')
{
$image = imagecreatefromjpeg($src);
}
elseif ($info['mime'] == 'image/gif')
{
$image = imagecreatefromgif($src);
}
elseif ($info['mime'] == 'image/png')
{
$image = imagecreatefrompng($src);
}
else
{
die('uknown format');
}
imagejpeg($image, $dest, $quality);
}
Thanks to #u_mulder for the answer. The clearstatcache worked perfectly and solved the problem! :) This is because it deletes the old variable data.
Here is the function that compress image file.
function compress_image($source_url, $destination_url, $quality) {
$info = getimagesize($source_url);
if ($info['mime'] == 'image/jpeg'){
$image = imagecreatefromjpeg($source_url);
}elseif ($info['mime'] == 'image/gif') {
$image = imagecreatefromgif($source_url);
}elseif ($info['mime'] == 'image/png') {
$image = imagecreatefrompng($source_url);
}imagejpeg($image, $destination_url, $quality);
return $destination_url;
}
$filename = compress_image($_FILES["home_image"]["tmp_name"], $_FILES["home_image"]["name"], 80);
$buffer = file_get_contents($_FILES["home_image"]["name"]);
Here is my code that want to move the compressed image to my specific folder
move_uploaded_file($_FILES["home_image"]["tmp_name"][$i],"../../../Test/image/home_banner/" .$filename);
But the image that move to the folder is still remain the original size without compress.
Am I doing the mistake..?
I think move_uplodaded_file() is not appropriate here, because you change the uploaded file contents:
This function checks to ensure that the file designated by filename is
a valid upload file (meaning that it was uploaded via PHP's HTTP POST
upload mechanism). If the file is valid, it will be moved to the
filename given by destination.
Use rename() instead.
I'm also not 100% if you can edit the uploaded file directly..
When running Page Speed in Google Chrome it suggests to optimize/compress the images. These images are mostly uploaded by users, so I would need to optimize them during uploading. What I find about optimizing jpeg images with php is something like using the following GD functions:
getimagesize()
imagecreatefromjpeg()
imagejpeg()
Since I am resizing the images after upload I'm already pulling the image through these functions and in addition I use imagecopyresampled() after imagecreatefromjpeg() to resize it.
But then, Page Speed is still telling me these images can be optimized. How can I accomplish this optimisation in a php script? Set the quality lower in imagejpeg() doesn't make a difference either.
The imagejpeg function is where you assign the quality. If you're already setting that to an appropriate value then there is little else you can do.
Page speed probably considers all images above a certain size to be "needing compression", perhaps just ensure they are all as small as reasonable (in terms of height/width) and compressed.
You can find more about page speed and it's compression suggestions on the pagespeed docs http://code.google.com/speed/page-speed/docs/payload.html#CompressImages which describes some of the techniques/tools to compress appropriately.
I've also just read the following:
Several tools are available that perform further, lossless compression on JPEG and PNG files, with no effect on image quality. For JPEG, we recommend jpegtran or jpegoptim (available on Linux only; run with the --strip-all option). For PNG, we recommend OptiPNG or PNGOUT.
So perhaps (if you really want to stick to Google's suggestions) you could use PHP's exec to run one of those tools on files as they are uploaded.
To compress with php you do the following (sounds like you are already doing this):
Where $source_url is the image, $destination_url is where to save and $quality is a number between 1 and 100 choosing how much jpeg compression to use.
function compressImage($source_url, $destination_url, $quality) {
$info = getimagesize($source_url);
if ($info['mime'] == 'image/jpeg') $image = imagecreatefromjpeg($source_url);
elseif ($info['mime'] == 'image/gif') $image = imagecreatefromgif($source_url);
elseif ($info['mime'] == 'image/png') $image = imagecreatefrompng($source_url);
//save file
imagejpeg($image, $destination_url, $quality);
//return destination file
return $destination_url;
}
Repaired function:
function compressImage($source_url, $destination_url, $quality) {
//$quality :: 0 - 100
if( $destination_url == NULL || $destination_url == "" ) $destination_url = $source_url;
$info = getimagesize($source_url);
if ($info['mime'] == 'image/jpeg' || $info['mime'] == 'image/jpg')
{
$image = imagecreatefromjpeg($source_url);
//save file
//ranges from 0 (worst quality, smaller file) to 100 (best quality, biggest file). The default is the default IJG quality value (about 75).
imagejpeg($image, $destination_url, $quality);
//Free up memory
imagedestroy($image);
}
elseif ($info['mime'] == 'image/png')
{
$image = imagecreatefrompng($source_url);
imageAlphaBlending($image, true);
imageSaveAlpha($image, true);
/* chang to png quality */
$png_quality = 9 - round(($quality / 100 ) * 9 );
imagePng($image, $destination_url, $png_quality);//Compression level: from 0 (no compression) to 9(full compression).
//Free up memory
imagedestroy($image);
}else
return FALSE;
return $destination_url;
}
You could use Imagick class for this. Consider following wrapper function:
<?php
function resizeImage($imagePath, $width, $height, $blur, $filterType = Imagick::FILTER_LANCZOS, $bestFit = false)
{
//The blur factor where > 1 is blurry, < 1 is sharp.
$img= new \Imagick(realpath($imagePath));
$img->setCompression(Imagick::COMPRESSION_JPEG);
$img->setCompressionQuality(40);
$img->stripImage();
$img->resizeImage($width, $height, $filterType, $blur, $bestFit);
$img->writeImage();
}
?>
Read more on how to resize images with Imagick at:
http://php.net/manual/en/class.imagick.php
http://php.net/manual/en/imagick.resizeimage.php
http://php.net/manual/en/imagick.constants.php#imagick.constants.filters
it is very important to optimize your images. Several CMS platforms out there have modules or plugins to preform this process. However if you are programming it yourself there is a complete php tutorial located at this page https://a1websitepro.com/optimize-images-with-php-in-a-directory-on-your-server/ You will be shown how to implement the imagecreatefromjpeg($SrcImage); and imagecreatefrompng($SrcImage); and imagecreatefromgif($SrcImage); There are written and video instruction on the page.
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.