Compression of PNG - php

I have this piece of code for uploading images. It makes thumbnails with PNG extension with level 9 compression, but the images do not look good. I want just -50% or little more compression of PNG with transparency.
$path_thumbs = "../pictures/thumbs/";
$path_big = "../pictures/";
$img_thumb_width = 140; //
$extlimit = "yes";
$limitedext = array(".gif",".jpg",".png",".jpeg",".bmp");
$file_type = $_FILES['image']['type'];
$file_name = $_FILES['image']['name'];
$file_size = $_FILES['image']['size'];
$file_tmp = $_FILES['image']['tmp_name'];
if(!is_uploaded_file($file_tmp)){
echo "choose file for upload!. <br>--return";
exit();
}
$ext = strrchr($file_name,'.');
$ext = strtolower($ext);
if (($extlimit == "yes") && (!in_array($ext,$limitedext))) {
echo "dissallowed! <br>--return";
exit();
}
$getExt = explode ('.', $file_name);
$file_ext = $getExt[count($getExt)-1];
$rand_name = md5(time());
$rand_name= rand(0,10000);
$ThumbWidth = $img_thumb_width;
if($file_size){
if($file_type == "image/pjpeg" || $file_type == "image/jpeg"){
$new_img = imagecreatefromjpeg($file_tmp);
}elseif($file_type == "image/x-png" || $file_type == "image/png"){
$new_img = imagecreatefrompng($file_tmp);
}elseif($file_type == "image/gif"){
$new_img = imagecreatefromgif($file_tmp);
}
list($width, $height) = getimagesize($file_tmp);
$imgratio = $width/$height;
if ($imgratio>1){
$newwidth = $ThumbWidth;
$newheight = $ThumbWidth/$imgratio;
}else{
$newheight = $ThumbWidth;
$newwidth = $ThumbWidth*$imgratio;
}
if (#function_exists(imagecreatetruecolor)){
$resized_img = imagecreatetruecolor($newwidth, $newheight);
}else{
die("Error: Please make sure you have GD library ver 2+");
}
imagecopyresized($resized_img, $new_img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
ImagePng ($resized_img, "$path_thumbs/$rand_name.$file_ext,9");
ImageDestroy ($resized_img);
ImageDestroy ($new_img);
}
move_uploaded_file ($file_tmp, "$path_big/$rand_name.$file_ext");

For better better quality of the resized image, you should use imagecopyresampled instread of imagecopyresized.
For image transparency you should look at imagesavealpha.
To make it work, you need to enable it, before you resize the image and you also need to disable alpha blending. It's best, to put it just after imagecreatetruecolor.
$resized_img = imagecreatetruecolor($newwidth, $newheight);
imagealphablending($resized_img, false);
imagesavealpha($resized_img, true);
As for the size, you have a typo in your code
ImagePng ($resized_img,"$path_thumbs/$rand_name.$file_ext,9");
should be
ImagePng ($resized_img, "$path_thumbs/$rand_name.$file_ext", 9);
you put your compression level parameter into the filename instead of the function.
And compression level here doesn't mean it will make your filesize much smaller. It's a tradeoff between speed and filesize.
There is a limit how much you can losslessly compress a file.
If filesize is a concern, you should compress it with lossy compression like JPEG.

I think (I did not verify) that you should use the function imagecopyresampled instead of imagecopyresize. I think imagecopyresampled has a higher quality. You might also want to start of by using imagecreatetruecolor

Related

Issue with cropping picture from mysql database using PHP? Image shows up black?

Im having a weird problem retrieving/cropping a smaller version of an original image from mysql database. Kind of new to this and need some help.
I have a script that uploads an image to a database (the original image) as well as a smaller, cropped image to be used as a profile image and that kind of thing. Here is that code:
if(isset($_FILES["file"]["type"]))
{
$validextensions = array("jpeg", "jpg", "png");
$maxsize = 99999999;
$temporary = explode(".", $_FILES["file"]["name"]);
$file_extension = end($temporary);
if ((($_FILES["file"]["type"] == "image/png") || ($_FILES["file"]["type"] == "image/jpg") || ($_FILES["file"]["type"] == "image/jpeg")
) && ($_FILES["file"]["size"] < $maxsize)//Approx. 100kb files can be uploaded.
&& in_array($file_extension, $validextensions)) {
$size = getimagesize($_FILES['file']['tmp_name']);
$type = $size['mime'];
$imgfp = fopen($_FILES['file']['tmp_name'], 'rb');
$size = $size[3];
$name = $_FILES['file']['name'];
$sql = new mysqli("localhost","username","password","sqlserver");
$imgfp64 = base64_encode(stream_get_contents($imgfp));
$update = "UPDATE sqlserver.imageblob set image='".$imgfp64."', image_type='".$type."', image_name='".$name."', image_size='".$size."' where user_id=".$account['id'];
$sql->query($update);
This is the part where scaling takes place:
//small image
$w=50;$h=50;
list($width, $height) = getimagesize($_FILES['file']['tmp_name']);
$r = $width / $height;
if ($w/$h > $r) {
$newwidth = $h*$r;
$newheight = $h;
} else {
$newheight = $w/$r;
$newwidth = $w;
}
$src = imagecreatefromjpeg($_FILES['file']['tmp_name']);
$dst = imagecreatetruecolor($newwidth, $newheight);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
ob_start();
imagejpeg($dst,null);
$dst=ob_get_clean();
$dst = base64_encode($dst);
$update2 = "UPDATE sqlserver.imageblob set chatimage='".$dst."' where user_id=".$account['id'];
$sql->query($update2);
And here is the result with only SOME images -
The original is not black. I read this post PHP: black image when cropping using php and think the script might be cropping outside the picture. What can I change in my code to mitigate this?
How can I make it scale down and crop the image from the image not outside?

Image cropping and thumb creation

I need to help a friend to make his own artistic gallery.
I already have all done, but I need a tool/plugin/script to make him independent from me in uploading his own images. My gallery needs two images: a cropped one of a certain proportion (so i need him to crop by himself in an uploading page) and a thumb one (I want this be done automatically).
Do you know an easy way to do this? What would you do?
Thanks.
Personally i use this in all of my projects - http://www.verot.net/php_class_upload.htm
Works perfectly with upload files and with files that's already on the system.
Can do many things convert, resize and work on uploaded images in many ways, apply effects, add labels, watermarks and reflections and other image editing features.
Easy to work with.
If you're not going to be having heavy traffic to start - look at http://phpthumb.sourceforge.net/ which can create your resized images on the fly.
You need only GD library, function imagecopyresampled will suit you. PHP manual has really good example code for thumbnail creation http://php.net/manual/en/function.imagecopyresampled.php
You will need just to create exceptions for different file formats
function create_jpeg_thumbnail($thumbImageName,$imgSrc,$thumbDirectory,$thumbnail_width,$thumbnail_height) { //$imgSrc is a FILE - Returns an image resource.
$thumbDirectory = trim($thumbDirectory);
$imageSourceExploded = explode('/', $imgSrc);
$imageName = $imageSourceExploded[count($imageSourceExploded)-1];
$imageDirectory = str_replace($imageName, '', $imgSrc);
$filetype = explode('.',$imageName);
$filetype = strtolower($filetype[count($filetype)-1]);
//getting the image dimensions
list($width_orig, $height_orig) = getimagesize($imgSrc);
//$myImage = imagecreatefromjpeg($imgSrc);
if ($filetype == 'jpg') {
$myImage = imagecreatefromjpeg("$imageDirectory/$imageName");
} else
if ($filetype == 'jpeg') {
$myImage = imagecreatefromjpeg("$imageDirectory/$imageName");
} else
if ($filetype == 'png') {
$myImage = imagecreatefrompng("$imageDirectory/$imageName");
} else
if ($filetype == 'gif') {
$myImage = imagecreatefromgif("$imageDirectory/$imageName");
}
$ratio_orig = $width_orig/$height_orig;
if ($thumbnail_width/$thumbnail_height > $ratio_orig) {
$new_height = $thumbnail_width/$ratio_orig;
$new_width = $thumbnail_width;
} else {
$new_width = $thumbnail_height*$ratio_orig;
$new_height = $thumbnail_height;
}
$x_mid = $new_width/2; //horizontal middle
$y_mid = $new_height/2; //vertical middle
$process = imagecreatetruecolor(round($new_width), round($new_height));
imagecopyresampled($process, $myImage, 0, 0, 0, 0, $new_width, $new_height, $width_orig, $height_orig);
$thumb = imagecreatetruecolor($thumbnail_width, $thumbnail_height);
imagecopyresampled($thumb, $process, 0, 0, 0, 0, $thumbnail_width, $thumbnail_height, $thumbnail_width, $thumbnail_height);
//$thumbImageName = 'thumb_'.get_random_no().'.jpeg';
$destination = $thumbDirectory=='' ? $thumbImageName : $thumbDirectory."/".$thumbImageName;
imagejpeg($thumb, $destination, 100);
return $thumbImageName;
}

help needed to resize an image in php

I have a bit of code that generates thumbnails from an uploaded image. The only problem is that it cuts portrait images off, rather than resizing the portrait image to fit the height of the thumbnail, landscape images are fine. I was wondering if anyone could help me out to change the code so it will place portrait images inside the thumbnail properly? (if that makes sense?)
Here's the code:
$setSize = 150;
$setHSize = 113;
$jpeg_quality = 75;
list($width, $height, $type, $attr) = getimagesize($origPath);
$newW = $setSize;
$newH = round( $height * ( $setSize / $width ) );
$img_r = imagecreatefromjpeg($origPath) or notfound();
$dst_r = ImageCreateTrueColor( $setSize, $setHSize );
$heightOffset = round( ($setHSize-$newH)/2 );
$white = imagecolorallocate($dst_r, 255, 255, 255);
imagefilledrectangle($dst_r, 0, 0, $setSize, $setHSize, $white);
imagecopyresampled($dst_r, $img_r, 0, $heightOffset, 0, 0, $newW, $newH, $width, $height);
header("Content-type: image/jpeg");
imagejpeg($dst_r, $thbPath, $jpeg_quality);
I just don't fully understand the way php creates images, so any help would be appreciated :)
The way you compute $newW and $newH is incorrect for what you want. You are giving preference to the width, so most landscape images will look okay, but portrait will be cut off. Try the following instead:
// assume landscape and see how things look
$newW = $setSize;
$newH = round( $height * ( $setSize / $width ) );
if ($newH > $setHSize) {
// portrait image
$newH = $setHSize;
$newW = round( $width * ( $setHSize / $height ) );
}
I hope this helps!
Hope this helps.
<?php
define('DOCROOT', $_SERVER['DOCUMENT_ROOT']);
include_once(DOCROOT."/dbc.php");
//**********************| Resize based on height
$photo_height = 350;
//**********************| Get the file from the post
$file = $_FILES['file'];
$path_thumbs = (DOCROOT."/gallery/");
$path_big = (DOCROOT."/trash/");
//**********************| Check permission
if (!is_writeable($path_thumbs)){
die ("Error: The directory <b>($path_thumbs)</b> is NOT writable");
}
if (!is_writeable($path_big)){
die ("Error: The directory <b>($path_big)</b> is NOT writable");
}
//**********************| Make sure you have a file
if (isset($file)){
$file_type = $_FILES['file']['type'];
$file_name = $_FILES['file']['name'];
$file_size = $_FILES['file']['size'];
$file_tmp = $_FILES['file']['tmp_name'];
$getExt = explode ('.', $file_name);
$file_ext = $getExt[count($getExt)-1];
//**********************| Make new name
$rand_name = md5(time());
$rand_name= rand(0,999999999);
//**********************| See the kind of file we have
if($file_size){
if($file_type == "image/pjpeg" || $file_type == "image/jpeg"){
$new_img = imagecreatefromjpeg($file_tmp);
}
elseif($file_type == "image/x-png" || $file_type == "image/png"){
$new_img = imagecreatefrompng($file_tmp);
}
elseif($file_type == "image/gif"){
$new_img = imagecreatefromgif($file_tmp);
}
//**********************| Get the height and width
list($width, $height) = getimagesize($file_tmp);
$imgratio=$height/$width;
if ($photo_height >= $height){
//*********** Dont resize if the image is smaller then $photo_height = 350;
$newwidth = $width;
$newheight = $height;
}
elseif ($imgratio>1){
$newheight = $photo_height;
$newwidth = $photo_height/$imgratio;
}
else{
$newwidth = $photo_height;
$newheight = $photo_height*$imgratio;
}
if (function_exists(imagecreatetruecolor)){ $resized_img = imagecreatetruecolor($newwidth,$newheight); }
else{ die("Error: Please make sure you have GD library ver 2+");
}
imagecopyresampled($resized_img, $new_img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
ImageJpeg ($resized_img,"$path_thumbs/$rand_name.$file_ext",'100');
ImageDestroy ($resized_img);
ImageDestroy ($new_img);
}
move_uploaded_file ($file_tmp, "$path_big/$rand_name.$file_ext");
$newimage = "$rand_name.$file_ext";
}
else {
echo "Sorry, there was a problem, Please try again.\n\n";
}
adaptiveResizeImage
or
adaptiveCropThumblanil
in Imagick can help you

PHP: if more than ..px resize to

I want to do so if the image are over the dimensions 604x453, then resize it to 604x453.
Ive made it this far:
$org_name = stripslashes($_FILES[$upload_name]['name']);
$file_size = $_FILES[$upload_name]['size'];
$file_temp = $_FILES[$upload_name]['tmp_name'];
$file_type = $_FILES[$upload_name]["type"];
$file_err = $_FILES[$upload_name]['error'];
list($width, $height, $type, $attr) = $imageSizeInfo;
$move_me = "images/users/status/".$org_name;
if(move_uploaded_file($file_temp, $move_me)) {
echo "{";
echo "msg: '".$org_name."'";
echo "}";
}
if($width > 604 && $height > 453) {
$jpeg_quality = 90;
$src = "images/users/status/".$org_name;
$ext= pathinfo($src, PATHINFO_EXTENSION);
$targ_h = 453;
$targ_w = 604;
$path_thumbs = "images/users/status/";
$thumb_path = $path_thumbs . '/' . $newfilename;
if($ext == "jpg" OR $ext == "jpeg" OR $ext == "JPG"){
$img_r = imagecreatefromjpeg($src);
}elseif($ext == "png" OR $ext == "PNG"){
$img_r = imagecreatefrompng($src);
}elseif($ext == "gif" OR $ext == "GIF"){
$img_r = imagecreatefromgif($src);
}
$dst_r = ImageCreateTrueColor( $targ_w, $targ_h );
imagejpeg($dst_r,$thumb_path,$jpeg_quality);
unlink($move_me);
}
So first it uploads the file with the original dimensions and everything, and then after it checks for dimensions and then resizes it, and unlinks(remove) the original one..
Now I dont know what, but somehow at the resize procedure it goes wrong and i only get a black square in the dimensions 604x453 as output..
What did i miss, how can i solve this?
Between your ImageCreateTrueColor and imagejpeg lines, you need something like this:
imagecopyresampled($dst_r, $img_r, 0, 0, 0, 0, $targ_w, $targ_h, $width, $height);
See the PHP manual for imagecopyresampled().
Your old code was essentially creating a blank canvas of the correct size, then creating your "black square" from it.
You should also use getimagesize() to determine what type of image has been uploaded, instead of using the file extension.
Index 2 is one of the IMAGETYPE_XXX
constants indicating the type of the
image.
The reason for this is that it is perfectly plausible that an image is uploaded which is called file.jpg, but it is actually a .png file - getimagesize() examines the bytes inside the image to determine what format it is.

compress image file size on upload?

I am uploading product screenshots to my website... I want to upload the original image as it is and also create a thumbnail for it, but after uploading both the files the filesize of the thumbnail created is a bit larger than expected. Is there any way I could reduce the filesize of the thumbnail without compromising much on the quality in php or by using Imagemagick( which I have no idea how to use but I'm willing to learn if needed)...
Below is the code I'm using to upload my files..
<form action="<?php echo $_server['php-self']; ?>" method="post" enctype="multipart/form-data" id="something" class="uniForm">
<input name="new_image" id="new_image" size="30" type="file" class="fileUpload" />
<button name="submit" type="submit" class="submitButton">Upload/Resize Image</button>
<?php
if(isset($_POST['submit'])){
if (isset ($_FILES['new_image'])){
$imagename = $_FILES['new_image']['name'];
$source = $_FILES['new_image']['tmp_name'];
$target = "images/".$imagename;
move_uploaded_file($source, $target);
$imagepath = $imagename;
$save = "images/" . $imagepath; //This is the new file you saving
$file = "images/" . $imagepath; //This is the original file
list($width, $height) = getimagesize($file) ;
$tn = imagecreatetruecolor($width, $height) ;
$image = imagecreatefromjpeg($file) ;
imagecopyresampled($tn, $image, 0, 0, 0, 0, $width, $height, $width, $height) ;
imagejpeg($tn, $save, 100) ;
$save = "images/sml_" . $imagepath; //This is the new file you saving
$file = "images/" . $imagepath; //This is the original file
list($width, $height) = getimagesize($file) ;
$modwidth = 130;
$diff = $width / $modwidth;
$modheight = 185;
$tn = imagecreatetruecolor($modwidth, $modheight) ;
$image = imagecreatefromjpeg($file) ;
imagecopyresampled($tn, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height) ;
imagejpeg($tn, $save, 100) ;
echo "Large image: <img src='images/".$imagepath."'><br>";
echo "Thumbnail: <img src='images/sml_".$imagepath."'>";
}
} ?>
Kindly point me in the right direction...Thanks
Don't pass 100 as the quality for imagejpeg() - anything over 90 is generally overkill and just gets you a bigger JPEG. For a thumbnail, try 75 and work downwards until the quality/size tradeoff is acceptable.
//try this
imagejpeg($tn, $save, 75) ;
Hello #halocursed I just try to compress using your code for different image type like png and gif than image comes black. So, I modify the block of code and good working for jpg, png.
<?php
if(isset($_POST['submit'])){
if (isset ($_FILES['new_image'])){
// print_r($_FILES); die;
$imagename = $_FILES['new_image']['name'];
$source = $_FILES['new_image']['tmp_name'];
$target = "images/".$imagename;
move_uploaded_file($source, $target);
$imagepath = $imagename;
$save = "images/" . $imagepath; //This is the new file you saving
$file = "images/" . $imagepath; //This is the original file
list($width, $height) = getimagesize($file);
$tn = imagecreatetruecolor($width, $height);
//$image = imagecreatefromjpeg($file);
$info = getimagesize($target);
if ($info['mime'] == 'image/jpeg'){
$image = imagecreatefromjpeg($file);
}elseif ($info['mime'] == 'image/gif'){
$image = imagecreatefromgif($file);
}elseif ($info['mime'] == 'image/png'){
$image = imagecreatefrompng($file);
}
imagecopyresampled($tn, $image, 0, 0, 0, 0, $width, $height, $width, $height);
imagejpeg($tn, $save, 60);
echo "Large image: ".$imagepath;
}
}
?>
75 is the default quality setting, however you'll notice quality decrease considerably if you use it. 90 gives you a great image quality and reduces the file size in half, if you want to decrease the file size even more use 85 or 80 but nothing bellow that.
It should be 60, it stands for 60 percent.
Example:
If you open an image in Photoshop and try save it for web and select jpg, you can see that by using 60 it's still under high quality, but lower file size. If you would like lower, with more degradation, meaning the colors are distorted more.
More than 60 does not give you anything better, only larger file size.
It's standard image optimization for web. Keep high quality but keep file size as low as possible.
A quality setting of 100% ist quite to large. try 85 or 90% you wont see a difference on most of the images.
see:
http://www.ampsoft.net/webdesign-l/jpeg-compression.html
If using jpeg, using a quality between 75 and 85 is generally more than acceptable (and 100 takes way too much space, for a gain that is not that important, btw), at least for photos.
As a sidenote, if you are dealing with screenshots, using PNG might get you a better quality : jpeg degrades the images (it is quite OK for photos, but for screenshots, with fonts that are drawn by pixels, it can bring some not nice-looking effect)
it moving compressed image with original. actually i want to move only compressed image that starts with "rxn-".
include("do.php");
session_start();
if(is_array($_FILES)) {
for($i=0; $i<count($_FILES['userImage']['tmp_name']); $i++){
if(is_uploaded_file($_FILES['userImage']['tmp_name'][$i])) {
$sourcePath = $_FILES['userImage']['tmp_name'][$i];
$upload_dir = "images/";
$targetPath = "images/".basename($_FILES['userImage']['name'][$i]);
$source_image = "images/".basename($_FILES['userImage']['name'][$i]);
$imageName =$_FILES['userImage']['name'][$i];
$imageFileType = strtolower(pathinfo($targetPath,PATHINFO_EXTENSION));
$check = getimagesize($_FILES["userImage"]["tmp_name"][$i]);
if (file_exists($targetPath)) {
// echo "<span style='color:red;'> file already exists</span> ";
}
if($check !== false) {
// echo "File is an image - " . $check["mime"] . ".";
$uploadOk = 1;
} else {
echo "<span style='color:red;'>File is not an image.</span><br>";
$uploadOk = 0;
}
if($imageFileType == "jpg" || $imageFileType == "png" || $imageFileType == "jpeg"
|| $imageFileType =="gif" ) {
if(move_uploaded_file($sourcePath,$targetPath))
//if(1)
{
$image_destination = $upload_dir."rxn-".$imageName;
$compress_images = compressImage($source_image, $image_destination);
$pId=$_SESSION['pId'];
$sql="insert into image(p_id,img_path) values('$pId','$compress_images')";
$result = mysql_query($sql);
echo "
<div class='col-sm-3' id='randomdiv' style='padding-bottom: 15px;'>
<div class='bg_prcs uk-height-small uk-flex uk-flex-center uk-flex-middle uk-background-cover uk-light uk-card-default uk-card-hover imgt' data-src='$image_destination' uk-img>
</div>
</div>
";
}
}
else{ echo "<span style='color:red;'> only JPG, JPEG, PNG & GIF files are allowed.</span>";
}
}
}
}
// created compressed JPEG file from source file
function compressImage($source_image, $compress_image) {
$image_info = getimagesize($source_image);
if ($image_info['mime'] == 'image/jpeg') {
$source_image = imagecreatefromjpeg($source_image);
imagejpeg($source_image, $compress_image, 75);
} elseif ($image_info['mime'] == 'image/gif') {
$source_image = imagecreatefromgif($source_image);
imagegif($source_image, $compress_image, 75);
} elseif ($image_info['mime'] == 'image/png') {
$source_image = imagecreatefrompng($source_image);
imagepng($source_image, $compress_image, 6);
}
return $compress_image;
}
?>

Categories