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.
Related
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
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
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..
I have a client that sends me text messages from his iPhone with images for me to upload into his gallery. I'm trying to create a admin system so I can simply take the images from the texts, go to the admin page on my iPhone and upload the images straight to the gallery.
This would save me tons of time in my day to day work schedule.
Using the provided code. How can I add the following functions:
I would like to compress the file size down to a smaller size if possible, similar to the save to web jpg function in Photoshop. (Most images I get are around 1-3 MB. I would like to get them down to around 150-500kb max)
I would like to automatically change the width to 760px, but keep the aspect ratio so the images are not squished. He sends me landscape and portrait images.
Beings they are iPhone images. They have an extension .JPG (all caps) I would like this to change to .jpg (all lower case.) This is not a deal breaker I would just like to know how to do this for future use.
Either one of these functions would be very helpful, but all 3 would be ideal for my situation.
Here is the code I'm working with?
THIS IS THE FINAL CORRECT CODE FOR UPLOADING AND RESIZING IMAGES PROVIDED By #tman
Make sure you have imagick installed in your php.ini file. Check with your hosting provider to install it.
<?php
include($_SERVER['DOCUMENT_ROOT'] . "/connections/dbconnect.php");
for($i=0;$i<count($_FILES["image"]["name"]);$i++){
if($_FILES["image"]["name"][$i] != ''){ // don't insert if file name empty
$dataType = mysql_real_escape_string($_POST["dataType"][$i]);
$title = mysql_real_escape_string($_POST["title"][$i]);
$fileData = pathinfo($_FILES["image"]["name"][$i]);
$fileName = uniqid() . '.' . $fileData['extension'];
$target_path = $_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $fileName;
if (move_uploaded_file($_FILES["image"]["tmp_name"][$i], $target_path)){ // The file is in the images/gallery folder.
// Insert record into database by executing the following query:
$sql="INSERT INTO images (data_type, title, file_name) "."VALUES('$dataType','$title','$fileName')";
$retval = mysql_query($sql);
///NEW
$size = getimagesize($target_path);
$width=$size[0];
$height=$size[1];
$newwidth = 760;
$newheight = $height*($newwidth/$width);
$pic = new Imagick($target_path);//specify name
$pic->resizeImage($newwidth,$newhight,Imagick::FILTER_LANCZOS,1);
unlink($target_path);
$pic->writeImage($target_path);
$pic->destroy();
///NEW
echo "The image {$_FILES['image']['name'][$i]} was successfully uploaded and added to the gallery<br />
<a href='index.php'>Add another image</a><br />";
}
else
{
echo "There was an error uploading the file {$_FILES['image']['name'][$i]}, please try again!<br />";
}
}
} // close your foreach
?>
uploader.php Original code. Allows me to upload 4 images at once. WORKS!!!
<?php
include($_SERVER['DOCUMENT_ROOT'] . "/connections/dbconnect.php");
for($i=0;$i<count($_FILES["image"]["name"]);$i++){
if($_FILES["image"]["name"][$i] != ''){ // don't insert if file name empty
$dataType = mysql_real_escape_string($_POST["dataType"][$i]);
$title = mysql_real_escape_string($_POST["title"][$i]);
$fileData = pathinfo($_FILES["image"]["name"][$i]);
$fileName = uniqid() . '.' . $fileData['extension'];
$target_path = $_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $fileName;
if (move_uploaded_file($_FILES["image"]["tmp_name"][$i], $target_path)){ // The file is in the images/gallery folder.
// Insert record into database by executing the following query:
$sql="INSERT INTO images (data_type, title, file_name) "."VALUES('$dataType','$title','$fileName')";
$retval = mysql_query($sql);
echo "The image {$_FILES['image']['name'][$i]} was successfully uploaded and added to the gallery<br />
<a href='index.php'>Add another image</a><br />";
}
else
{
echo "There was an error uploading the file {$_FILES['image']['name'][$i]}, please try again!<br />";
}
}
} // close your foreach
?>
FYI, This will allow you to give a unique names to your images, resize the width, but keep the correct aspect ratio and upload multiple file at the same time.
Awesome Stuff!
Like this:
$filelocation='http://help.com/images/help.jpg';
$newfilelocation='http://help.com/images/help1.jpg';
$size = getimagesize($filelocation);
$width=$size[0];//might need to be ['1'] im tired .. :)
$height=$size[1];
// Plz note im not sure of units pixles? & i could have the width and height confused
//just had some knee surgery so im kinda loopy :)
$newwidth = 760;
$newheight = $height*($newwidth/$width)
$pic = new Imagick( $filelocation);//specify name
$pic->resizeImage($newwidth,$newhight,Imagick::FILTER_LANCZOS,1);
//again might have width and heing confused
$pic->writeImage($newfilelocation);//output name
$pic->destroy();
unlink($filelocation);//deletes image
Here is something kind of similar, lets check the size and compress if the image seems that it is too big. I didn't resize it which just requires that you get the dimensions and resize based on desire.
All this is doing is if the file is greater than 250KB compress it to 85% ..
$bytes = filesize($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
//$maxSizeInBytes = 26400; //is 250KB? No? compress it.
if ($bytes > 26400) {
$img = new Imagick($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
$img->setImageCompression(imagick::COMPRESSION_JPEG);
$img->stripImage();
$img->setImageCompressionQuality(85);
$img->writeImage($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
}
OR:
// resize with imagejpeg ($image, $destination, $quality); if greater than byte size KB
// Assume only supported file formats on website are jpg,jpeg,png, and gif. (any others will not be compressed)
$bytes = filesize($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
//$maxSizeInBytes = 26400; //is gtr than 250KB? No? compress it.
if ($bytes > 26400) {
$info = getimagesize($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
$quality = 85; //(1-100), 85-92 produces 75% quality
if ($info['mime'] == 'image/jpeg') {
$image = imagecreatefromjpeg($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
imagejpeg($image,$inventory_path.DIRECTORY_SEPARATOR.$this->uploadName,$quality);
} elseif ($info['mime'] == 'image/gif') {
$image = imagecreatefromgif($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
imagejpeg($image,$inventory_path.DIRECTORY_SEPARATOR.$this->uploadName,$quality);
} elseif ($info['mime'] == 'image/png') {
$image = imagecreatefrompng($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName
imagejpeg($image,$inventory_path.DIRECTORY_SEPARATOR.$this->uploadName,$quality);
}
}
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.