PHP image resize script? - php

Okay I'm really new to PHP I found the following script below. But I dont know how to use it I was wondering where do I put the link to the image for example images/photo.jpg inorder to get me started in learning this script thanks.
Here is the code.
<?php
function resizeImage($originalImage,$toWidth,$toHeight){
// Get the original geometry and calculate scales
list($width, $height) = getimagesize($originalImage);
$xscale=$width/$toWidth;
$yscale=$height/$toHeight;
// Recalculate new size with default ratio
if ($yscale>$xscale){
$new_width = round($width * (1/$yscale));
$new_height = round($height * (1/$yscale));
}
else {
$new_width = round($width * (1/$xscale));
$new_height = round($height * (1/$xscale));
}
// Resize the original image
$imageResized = imagecreatetruecolor($new_width, $new_height);
$imageTmp = imagecreatefromjpeg ($originalImage);
imagecopyresampled($imageResized, $imageTmp, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
return $imageResized;
}
?>

There are a couple of potential gotchas here, so I'll give you a few of the potential issues you can run into:
You need to give the full path to the image so that it can be read. I use the following script for this:
function getRoot(){
$cwd = getcwd();
$splitCwd = explode("/", $cwd);
$root = "";
for($count=0; $count<count($splitCwd)-1;$count++){
$root .= '/' . $splitCwd[$count];
}
$root = $root . '/';
return $root;
}
Then you can pass in (getRoot() . $image, ...)
Create a switch that will check the file type (see my answer here). This will allow you to resize more than just jpegs, and output more than just jpegs, which is good when transparency may be involved.
There possible could be a final parameter or two, which is output filename. That way, you can make thumbnails while leaving the original image intact. In that case, you would do the imagejpeg (or imagepng, etc), and pass it the new name parameter if it is set.

You'd pass the link to the original JPEG as the first parameter in the function, which would be set as $originalImage.
So when calling the function, you'd use:
resizeImage("images/photo.jpg",800,600);
The two numbers would be your width/height values.

Instead of the return line you must add
header('Content-type: image/jpeg');
imagejpeg($imageResized);
Or check http://www.php.net/manual/en/function.imagejpeg.php and the Example #2 Saving a JPEG image

Related

How to compress / reduce quality of base64 image with php?

I have stored multiple images in base64 inside my database. I get images using php as image path. But I want to reduce size of my image when decoding it from base64, because it slows down my app if I load full size image. (Full size image I need just in backend).
/*
DB stuff getting base64 string from database
$img = base64 string (can be with 'data:image/jpg;base64,' in front, thats for the str_replace())
*/
if($img){
header("Content-Type: image/png");
echo base64_decode(str_replace("data:image/jpg;base64,","",$img));
}
Everything works nice this way. I use it like this:
<img src="http://example.com/getimg.php?id=4" />
or in css. I need this because of security reasons, I cant store any image on server, also in path I have access_token variable, so random person cant see images.
Is there a way to do this without storing the actual image in server?
You can use imagecreatefromstring and imagecopyresized.
Live example here
<?php
if ($img) {
$percent = 0.5;
// Content type
header('Content-Type: image/jpeg');
$data = base64_decode($img);
$im = imagecreatefromstring($data);
$width = imagesx($im);
$height = imagesy($im);
$newwidth = $width * $percent;
$newheight = $height * $percent;
$thumb = imagecreatetruecolor($newwidth, $newheight);
// Resize
imagecopyresized($thumb, $im, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
// Output
imagejpeg($thumb);
}

getting image file from php image resoure

When i use imagecopyresized() function on php it returns as image resource, and what i want is to get the image data from this image resource.may be like a file location in a string or an array containg several data of the file like the one you get in the $_FILES[] global array. thanks
$source = $_FILES['image']['tmp_name'];
list($width,$height) = getimagesize($source);
echo BR.$height." ".$width;
$desired_height = 28;
$scale = $width/$height;
$new_width = $desired_height * $scale;
$new_height = $desired_height;
$original_image = imagecreatefromjpeg($source);
$resized_image = imagecreatetruecolor($new_width, $new_height);
if(imagecopyresized($resized_image, $original_image, 0, 0, 0, 0, $new_width, $new_height, $width, $height)){
echo BR."image resized".BR;
}
i want to store the location of $resized_image in to database but i cant seem to access the file location from this variable.
This will put your image contents to the $buffer variable as a jpeg.
ob_start();
imagejpeg($im, null, 90);
$buffer = ob_get_contents();
ob_end_clean();
You can then save it with file_put_contents to a desired path and save the path to the database.
See https://secure.php.net/manual/en/function.imagejpeg.php
Alternatively, you could use a 3rd party library with a nicer API, such as Nette\Utils\Image or Intervention\Image.
imagecreatetruecolor creates an image resource in memory and returns its identifier. It does not create any physical file with the image in it.
Use imagejpeg like:
imagejpeg($resized_image, '/path/to/save/img.jpg')
It will create and save an image file to disk. And then you can store that path in database.
See: http://php.net/manual/en/function.imagejpeg.php and http://php.net/manual/en/function.imagecreatetruecolor.php
$resized_image is not associated with afile.
You need to use imagejpeg, imagepng, .. methods to save resources to a file.
imagejpeg($resized_image, 'path/file.jpg');

PHP: how to use getimgasize() after the image is resized using getimageresized after upload?

using the example given at http://www.php.net/manual/en/function.imagecopyresized.php ... how to get image sizes afterward using getimagesize() function?
CODE:
<?php
if(isset($_FILES['images'])){
//TEST1:
$img = resize_this_image_now($_FILES['images']['tmp_name']);
//TEST2:
$img = resize_this_image_now($_FILES['images']['name']);/// This Drastically failed.
$new_image = getimagesize($img);
var_dump($new_image[0]);// I guessed this should have printed out the WIDTH_OF_THE_IMAGE... but, it prints some NON_READABLE stuffs (why?)
}
// The PHP.NET CODE in a Function
function resize_this_image_now($filename){
// File and new size
// $filename = 'test.jpg';
$percent = 0.5;
// Content type
header('Content-Type: image/jpeg');
// Get new sizes
list($width, $height) = getimagesize($filename);
$newwidth = $width * $percent;
$newheight = $height * $percent;
// Load
$thumb = imagecreatetruecolor($newwidth, $newheight);
$source = imagecreatefromjpeg($filename);
// Resize
imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
// Output
return imagejpeg($thumb);
}
?>
All I want is to get the Size of the Image.... also, is it possible to do something like:
$_FILES['images']['tmp_name'] = $the_newly_resized_image_returned_from_the_PHP_dot_NET_code'; .... So that the ['images']['tmp_name'] will now have as source this new image??
Any suggestion is highly appreciated...
I decided to spend sometime examining you question. What I found out is that, I don't think you'd need to return the resized image through imagejpeg() the way you did. You might also need to add a imagedestroy(), after you call imagejpeg() in you function, to destroy the temporary memory used.
You need to first fully Upload the Image before resizing it. If you'd like, you could send the image in a temporary storage while you do whatever you want to it so that Php does not have to deal with it in a 'tmp_name' format...Then You can destroy the image later on.
Once the image is fully uploaded, things become easier. The codes might look something like:
if(isset($_FILES['images'])){
//may be some random numbers to accompany it.
$rand = floor((mt_rand()+rand()+mt_rand())/3);
//Send it to the temporary folder you have had to create.
if(move_uploaded_file(
$_FILES['images']['tmp_name'],'temporary_storage/image_'.$rand.'.jpg')){
//Then run the `resize` function from here.
$image_resized = resize_this_image_now('temporary_storage/image_'.$rand.'.jpg');
//Now You can get the size if you wish.
list($width,$height) = getimagesize('temporary_storage/image_'.$rand.'.jpg');
// Out put
echo "W:".$width."<br>H:".$height;
//After you use it as desired, you can now destroy it using unlink or so.
unlink('temporary_storage/image_'.$rand.'.jpg');
}else{
echo "Upload Error goes here";
}
}
Note this answer is produced after several trials and errors... Please use this strategy wisely.
Hope it helps.

Img displayed in binary code with correct header on browser

I build a class of imgResize:
class imgResize
{
public static function resizeAndOutput($img) {
$orginal_img = $img;
$width = 591;
$height = 332;
$new_width = 161;
$new_height = 91;
$edit_img = imagecreatetruecolor($new_width, $new_height);
$image = imagecreatefromjpeg($orginal_img);
imagecopyresampled($edit_img, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
header('Content-Type: image/jpeg');
imagejpeg($edit_img);
}
}
and in html I try to get this on the fly img displayed:
<img class="img_small" src="<?php imgResize::resizeAndOutput($img)">
just getting binary datas like this:
�����JFIF���������>CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), default quality ���C� $.'
How can i solve my problem?
you have to encode your image in a data uri (and embedding the base64 encoded data as a string in your html) and removing that header() line in php,
or create a link to that image, for example http://example.com/?myimage=id and outputting the image as you are doing (as in giving correct headers and echoing the resulting image)
tell me if you need more info or this gives enough insights.
If you output it directly into a src element, it will of course just be binary garbage inside HTML. That's not how <img> elements work. An <img> element's src needs to have a URL pointing to the image. This can be either a URL like img/foo.jpg, or app/some_script_that_outputs_an_image.php, or a Data URI. But not simply binary data. The script that outputs the image would work in this second case, as target of a app/some_script_that_outputs_an_image.php link.
You actually do it right but in the last part you have a problem. You have to save the image and then return the url of the image to the img element.. Try this code:
class imgResize
{
public static function resizeAndOutput($img) {
$orginal_img = $img;
$width = 591;
$height = 332;
$new_width = 161;
$new_height = 91;
$edit_img = imagecreatetruecolor($new_width, $new_height);
$image = imagecreatefromjpeg($orginal_img);
imagecopyresampled($edit_img, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
header('Content-Type: image/jpeg');
//Now we have the image lets create a random filename
//Modify this to your needs
$filename = "images/IMG_" . mt_rand(1000,9999) . ".jpg";
//Random sometimes sucks.. Lets see if we already got a file with that name
//And if exists, loop until we get a unique one
while(file_exists($filename)) {
$filename = "images/IMG_" . mt_rand(1000,9999) . ".jpg";
}
//Now let's save the file
imagejpeg($edit_img, $filename);
//And finally return the file url
return $filename;
}
}
If you don't want to save it, you should output it directly to the browser. You don't need any img tags. That's because when using imagejpeg it's like you have directly opened an image file in the browser. (I don't know if I was clear or not. I'm just trying to describe what it really is)
So the php file will be same and you don't need any html. Just call the function. it will do what it is needed:
imgResize::resizeAndOutput($img);
class imgResize
{
public static function resizeAndOutput($img) {
$orginal_img = $img;
$width = 591;
$height = 332;
$new_width = 161;
$new_height = 91;
$edit_img = imagecreatetruecolor($new_width, $new_height);
$image = imagecreatefromjpeg($orginal_img);
imagecopyresampled($edit_img, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
ob_start ();
imagejpeg($edit_img);
$image_data = ob_get_contents ();
ob_end_clean ();
return base64_encode($image_data);
}
HTML
<img class="img_small" src="data:image/jpeg;base64,<?php echo imgResize::resizeAndOutput($img)">

How do I resize and convert an uploaded image to a PNG using GD?

I want to allow users to upload avatar-type images in a variety of formats (GIF, JPEG, and PNG at least), but to save them all as PNG database BLOBs. If the images are oversized, pixelwise, I want to resize them before DB-insertion.
What is the best way to use GD to do the resizing and PNG conversion?
Edit: Sadly, only GD is available on the server I need to use, no ImageMagick.
<?php
/*
Resizes an image and converts it to PNG returning the PNG data as a string
*/
function imageToPng($srcFile, $maxSize = 100) {
list($width_orig, $height_orig, $type) = getimagesize($srcFile);
// Get the aspect ratio
$ratio_orig = $width_orig / $height_orig;
$width = $maxSize;
$height = $maxSize;
// resize to height (orig is portrait)
if ($ratio_orig < 1) {
$width = $height * $ratio_orig;
}
// resize to width (orig is landscape)
else {
$height = $width / $ratio_orig;
}
// Temporarily increase the memory limit to allow for larger images
ini_set('memory_limit', '32M');
switch ($type)
{
case IMAGETYPE_GIF:
$image = imagecreatefromgif($srcFile);
break;
case IMAGETYPE_JPEG:
$image = imagecreatefromjpeg($srcFile);
break;
case IMAGETYPE_PNG:
$image = imagecreatefrompng($srcFile);
break;
default:
throw new Exception('Unrecognized image type ' . $type);
}
// create a new blank image
$newImage = imagecreatetruecolor($width, $height);
// Copy the old image to the new image
imagecopyresampled($newImage, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
// Output to a temp file
$destFile = tempnam();
imagepng($newImage, $destFile);
// Free memory
imagedestroy($newImage);
if ( is_file($destFile) ) {
$f = fopen($destFile, 'rb');
$data = fread($f);
fclose($f);
// Remove the tempfile
unlink($destFile);
return $data;
}
throw new Exception('Image conversion failed.');
}
Your process steps should look like this:
Verify the filetype
Load the image if it is a supported filetype into GD using imagecreatefrom*
Resizing using imagecopyresize or imagecopyresampled
Save the image using imagepng($handle, 'filename.png', $quality, $filters)
ImageMagick is faster, generates better images, is more configurable, and finally is (IMO) much easier to code for.
#ceejayoz Just wait for the new GD - it's OOP like MySQLi and it's actually not bad :)
If you want to use gdlib, use gdlib 2 or higher. It has a function called imagecopyresampled(), which will interpolate pixels while resizing and look much better.
Also, I've always heard noted around the net that storing images in the database is bad form:
It's slower to access than the disk
Your server will need to run a script to get to the image instead
of simply serving a file
Your script now is responsible for a lot of stuff the web server used
to handle:
Setting the proper Content-Type header
Setting the proper caching/timeout/E-tag headers, so clients can properly cache the image. If do not do this properly, the image serving script will be hit on every request, increasing the load on the server even more.
The only advantage I can see is that you don't need to keep your database and image files synchronized. I would still recommend against it though.
Are you sure you have no ImageMagick on server?
I guest you use PHP (question is tagged with PHP). Hosting company which I use has no ImageMagick extension turned on according to phpinfo().
But when I asked them about they said here is the list of ImageMagick programs available from PHP code. So simply -- there are no IM interface in PHP, but I can call IM programs directly from PHP.
I hope you have the same option.
And I strongly agree -- storing images in database is not good idea.
Something like this, perhaps:
<?php
//Input file
$file = "myImage.png";
$img = ImageCreateFromPNG($file);
//Dimensions
$width = imagesx($img);
$height = imagesy($img);
$max_width = 300;
$max_height = 300;
$percentage = 1;
//Image scaling calculations
if ( $width > $max_width ) {
$percentage = ($height / ($width / $max_width)) > $max_height ?
$height / $max_height :
$width / $max_width;
}
elseif ( $height > $max_height) {
$percentage = ($width / ($height / $max_height)) > $max_width ?
$width / $max_width :
$height / $max_height;
}
$new_width = $width / $percentage;
$new_height = $height / $percentage;
//scaled image
$out = imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($out, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
//output image
imagepng($out);
?>
I haven't tested the code so there might be some syntax errors, however it should give you a fair presentation on how it could be done. Also, I assumed a PNG file. You might want to have some kind of switch statement to determine the file type.
Is GD absolutely required? ImageMagick is faster, generates better images, is more configurable, and finally is (IMO) much easier to code for.
This article seems like it would fit what you want. You'll need to change the saving imagejpeg() function to imagepng() and have it save the file to a string rather than output it to the page, but other than that it should be easy copy/paste into your existing code.
I think this page is a good starting point. It uses imagecreatefrom(jpeg/gif/png) and resize and converts the image and then outputs to the browser. Instead of outputting the browser you could output to a BLOB in a DB without many minuttes of code-rewrite.
phpThumb is a high-level abstraction that may be worth looking at.

Categories