I need to resize image based on weight on my page php.
Ex: I have image of 10MB, when I upload image I want to resize to 5MB.
It's possible?
<?php
header('Content-type: image/jpeg');
$filename = 'http://www.yoursite.com/images/cowboybebop27.JPG';
$image = imagecreatefromjpeg($filename);
$dest='temp_image.jpg';
imagejpeg($image, null, 10);
imagejpeg($image, $dest, 10);
?>
The above code will pull an image and save it at the file location of temp_image.jpg.
imagejpeg($image, null, 10); //This line displays the image with a quality of 10% which is roughly 1/10 the original file size as well.
imagejpeg($image, $dest, 10); //This line saves the image with an image quality of 10%.
see here
If you're OK with using a library, take a look at WideImage.
<?php
include "path/to/WideImage.php";
$image = 'path/to/image.jpg';
$wi_image = WideImage::load($image);
//Get the file size & dimensions of the image
$size = filesize($image);
$dimensions = getfilesize($image);
//Determine image size
if ($size > 10000000) {
//Image is over 10MB - half dimensions
$resized = $wi_image->resize(
$dimensions[0] / 2, //half of width
$dimensions[1] / 2 //half of height
);
//Save image
$resized->saveToFile('small.jpg');
}
?>
<img src="small.jpg" />
It's worth noting that this will not necessarily halve image size but in most cases it will make the size smaller.
Related
When user upload AI file then if Dimension of an uploaded file is less than or equal to (180 x 180) then I want to resize this file to increased dimension (277 x 277) and then convert it to JPG. I tried code mentioned below. I tried all ways which are commented in the code.
$image_rs = new Imagick();
$image_rs->readimage(realpath(SOURCE_UPLOAD_PATH.$source_file_name));
if($fileType == "ai"){
$image_rs->setIteratorIndex(0);
}
$dimensions = $image_rs->getImageGeometry();
$width = $dimensions['width'];
$height = $dimensions['height'];
if($width <= 180 && $height <= 180){
//$image_rs->magnifyImage();
$image_rs->setImageFormat($source_file_ext);
$image_rs->scaleImage(277,0);
// $image_rs->adaptiveResizeImage(277,277);
// $image_rs->resizeImage(277,277,\Imagick::FILTER_CATROM, 1, true);
$image_rs->writeImage(realpath(RESIZED_UPLOAD_PATH)."/". $source_file_name);
$image = new Imagick();
$image->readimage(realpath(RESIZED_UPLOAD_PATH.$source_file_name));
if($fileType == "ai"){
$image->setIteratorIndex(0);
}
$dimensions = $image->getImageGeometry();
$width = $dimensions['width'];
$height = $dimensions['height'];
$image->thumbnailImage($width, $height);
$image->writeImage(realpath(CONVERTED_UPLOAD_PATH)."/". $source_file_name_without_ext.".jpg");
}
Issue: By using this code image is resized successfully but resized AI file also becomes blurry. because of Imagick library when resizing the image it converts AI file to jpg. AI file is vector file so there is no chance to become blurry even if we increase dimension. So how I can do this by imagemagick?
My topic is about adding watermark to images using PHP code. Example is here http://php.net/manual/en/image.examples-watermark.php
I face a problem is that the example mentioned only deals with JPEG images only as it uses imagecreatefromjpeg() function.
I used this function I do not remember from where I got it. It creates image of other types png, bmp and gif.
function imageCreateFromAny($filepath){
$type = exif_imagetype($filepath); // [] if you don't have exif you could use getImageSize()
$allowedTypes = array(
1, // [] gif
2, // [] jpg
3, // [] png
6 // [] bmp
);
if (!in_array($type, $allowedTypes)) {
return false;
}
switch ($type) {
case 1 :
$im = imageCreateFromGif($filepath);
break;
case 2 :
$im = imageCreateFromJpeg($filepath);
break;
case 3 :
$im = imageCreateFromPng($filepath);
break;
case 6 :
$im = imageCreateFromBmp($filepath);
break;
}
return $im;
}
THE PROBLEM: The output image of the function is an image which its size number is multiplied by 4, I mean the size becomes bigger around 4 times. For example, if the function received the image as 94K, it outputs it around 380K.
I want to resolve the problem of maximizing the size number, I want to get the same image size as before the image size was input to the function imageCreateFromAny($filepath)
Hint:
The below function is calling the above function
function Stamp($filename){
// Load the stamp and the photo to apply the watermark to
$stamp = imagecreatefrompng('../../style/images/stamp1.png');
// $im = imagecreatefromjpeg('../../gallery/black-white/'.$filename);
$im = imageCreateFromAny('../../gallery/black-white/'.$filename);
// Set the margins for the stamp and get the height/width of the stamp image
$marge_right = 10;
$marge_bottom = 10;
$sx = imagesx($stamp);
$sy = imagesy($stamp);
// Copy the stamp image onto our photo using the margin offsets and the photo
// width to calculate positioning of the stamp.
imagecopy($im, $stamp, imagesx($im) - $sx - $marge_right, imagesy($im) - $sy - $marge_bottom, 0, 0, imagesx($stamp), imagesy($stamp));
// Output and free memory
// header('Content-type: image/png');
// imagepng($im);
$filename_new = '../../gallery/black-white/'.$filename.'';
// if (move_uploaded_file(imagepng($im), '../../gallery/black-white/2' ))
imagepng($im, $filename_new);
imagedestroy($im);
}
You're saving the image to a PNG, which, yes, is often significantly larger than a JPEG, but also has higher quality. JPEG is a lossy format, which discards quality for a smaller file size. PNG is a lossless format, which retains all possible information and just tries to compress the data as much as it can. For an image with a lot of detail, that will result in massively bigger sizes than JPEG with a low quality setting.
I'm working on a website which I didn't originally create/develop.
Users can upload an image and when they do that, there's a function that creates a duplicate of that image with a watermark.
But the copy with the watermark is of low quality and also its size is much smaller than the original image
Without watermark
With watermark
function watermark( $path ){
$watermark = imagecreatefrompng('files/watermark.png');
$wmsize = getimagesize('files/watermark.png');
$image = imagecreatefromjpeg($path);
$size = getimagesize($path);
$dest_x = (8);
$dest_y = ($size[1] - 35 );
imagecopy($image, $watermark, $dest_x, $dest_y, 0, 0, $wmsize[0], $wmsize[1]);
ob_start();
imagejpeg($image);
$img2 = ob_get_contents();
ob_end_clean();
imagedestroy($image);
return $img2 ;
}
The image quality is decreased because of JPEG compression.
Every time you save image as JPEG you decrease its quality because JPEG uses lossy compression. You can minimize the loss by setting the compress quality to 100%, but if you would like to perform lossless compression it is not possible for JPEG and you must look for another image format, e.g. TIFF.
A quick brief. We currently have to make small, medium and large images based on product images we have on our site. Not being a wiz on PHP I thought I would still try to automate this nightmare.
The image we upload and dimension of the thumb is below
800 width x 1400 width LARGE
300 width x 525 width THUMB
The problem with my PHP script is that it just resizes with scaling to proportion. I want to it to be able to scale down like in Photoshop, you just click shift and the image scales. I am trying to use imagecopyresized but with little luck.
<?php
// PHP UPLOAD SCRIPT
// VALIDATION OF FORM
if($_FILES['user_image']['type'] == "image/jpeg" && $_FILES['user_image']['size'] < 3000000)
{
// VARS
$target_folder = 'images/';
$upload_image = $target_folder.basename($_FILES['user_image']['name']);
// UPLOAD FUNCTION
if(move_uploaded_file($_FILES['user_image']['tmp_name'], $upload_image))
{
// VARS FOR FILE NAMES
$thumbnail = $target_folder."medium_x.jpg";
$actual = $target_folder."large_x.jpg";
// THUMBNAIL SIZE
list($width, $height) = getimagesize($upload_image);
$newwidth = "300";
$newheight = "525";
// VARS FOR CALL BACK
$thumb = imagecreatetruecolor($newwidth, $newheight);
$source = imagecreatefromjpeg($upload_image);
// RESIZE WITH PROPORTION LIKE PHOTOSHOP HOLDING SHIFT
imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
// MAKE NEW FILES
imagejpeg($thumb, $thumbnail, 100);
// FILE RENAMES
rename($upload_image, $actual);
{
// SUCCESS MESSAGES
?>
<p>
Image Successfully uploaded!<br />
Actual image: <?=$actual;?><br />
Thumbnail image: <?=$thumbnail;?><br />
<h1>Large</h1>
<img src="<?=$actual;?>"/><br /><br />
<h1>Medium</h1>
<img src="<?=$thumbnail;?>"/><br /><br />
</p>
<?
}
// FAILED MESSAGES
}
else
{
echo 'Upload failed.';
}
}
else
{
// NOT A JPEG
echo 'Not a JPEG';
}
// END OF SCRIPT
?>
How can I resize properly without having a stretched image? Is it possible?
The easiest way to achieve this without buckets of PHP code is with Image Magick. See examples and sample command line here: http://www.imagemagick.org/Usage/resize/#fill
(can call from PHP using exec() or similar)
Edit: Implementation as follows:
if($_FILES['user_image']['type'] == "image/jpeg" && $_FILES['user_image']['size'] < 3000000)
{
// VARS
$target_folder = 'images/';
$upload_image = $target_folder.basename($_FILES['user_image']['name']);
$thumbnail = $target_folder."medium_x.jpg";
$actual = $target_folder."large_x.jpg";
$newwidth = "300";
$newheight = "525";
if(move_uploaded_file($_FILES['user_image']['tmp_name'], $upload_image))
{
exec('convert '.$upload_image.' -resize '.$newwidth.'x'.$newheight.'^ '.$thumbnail);
rename($upload_image, $actual);
}
}
...
etc
You could optimise the way you handle the upload but I didn't want too totally change the structure of your code as I don't know what surrounds it. But basically, you push the image to ImageMagick's convert, and it will work it's magic.
If you want to crop as well as scale, the exec command would be:
exec('convert '.$upload_image.' -resize '.$newwidth.'x'.$newheight.'^ -gravity center -extent '.$newwidth.'x'.$newheight.' '.$thumbnail);
Look at this code snippet. Does what you need. Basically used to maintain ratio when creating the thumb.
http://snipplr.com/view/753/
I am quite confused why PNG images that are resized using GD library are much bigger in size than the original.
This is the code I am using to resize the image:
// create image from posted file
$src = imagecreatefrompng($file['tmp_name']);
// get original size of uploaded image
list($width,$height) = getimagesize($file['tmp_name']);
if($width>$maxImgWidth) {
// resize the image to maxImgWidth, maintain the original aspect ratio
$newwidth = $maxImgWidth;
$newheight=($height/$width)*$newwidth;
$newImage=imagecreatetruecolor($newwidth,$newheight);
// fill transparent with white
/*$white=imagecolorallocate($newImage, 255, 255, 255);
imagefill($newImage, 0, 0, $white);*/
// the following is to keep PNG's alpha channels
// turn off transparency blending temporarily
imagealphablending($newImage, false);
// Fill the image with transparent color
$color = imagecolorallocatealpha($newImage,255,255,255,127);
imagefill($newImage, 0, 0, $color);
// restore transparency blending
imagesavealpha($newImage, true);
// do the image resizing by copying from the original into $newImage image
imagecopyresampled($newImage,$src,0,0,0,0,$newwidth,$newheight,$width,$height);
// write image to buffer and save in variable
ob_start(); // Stdout --> buffer
imagepng($newImage,NULL,5); // last parameter is compression 0-none 9-best (slow), see also http://www.php.net/manual/en/function.imagepng.php
$newImageToSave = ob_get_contents(); // store stdout in $newImageToSave
ob_end_clean(); // clear buffer
// remove images from php buffer
imagedestroy($src);
imagedestroy($newImage);
$resizedFlag = true;
}
Then I save $newImageToSave as blob in mysql database.
I tried to prevent alpha channel and just set white background, no significant change in file size. I tried setting the "compression" parameters (0 to 9), but still bigger then the original.
Example
I took this image (1058px*1296px) and resized it to 900px * 1102px. These are the results:
Original File: 328 KB
PNG (0): 3,79 MB
PNG (5): 564 KB
PNG (9): 503 KB
Any tip how to get the resized image smaller in file size is appreciated.
--
PS: I thought it could be bit depth, but as you can see, the example image above has 32 bits, whereas the resized image is 24 bits.
You don't most of the functions you are calling to reduce the image , imagefill , imagealphablending etc can result to higher file size.
To Maintain the transparent use imagecreate instead of imagecreatetruecolor and just do a simple resize
$file['tmp_name'] = "wiki.png";
$maxImgWidth = 900;
// create image from posted file
$src = imagecreatefrompng($file['tmp_name']);
// get original size of uploaded image
list($width, $height) = getimagesize($file['tmp_name']);
if ($width > $maxImgWidth) {
$newwidth = $maxImgWidth;
$newheight = ($height / $width) * $newwidth;
$newImage = imagecreate($newwidth, $newheight);
imagecopyresampled($newImage, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
imagepng($newImage, "wiki2.png", 5);
imagedestroy($src);
imagedestroy($newImage);
$resizedFlag = true;
}
Final Size : 164KB