Image magician and PNG uploads - php

I have a problem with GD when trying to upload png. The error which I've got is
Warning: imagepng(): gd-png error: compression level must be 0 through 9... on line 2474
on line 2474 in php_image_magician.php is case for png
case '.png':
// *** Scale quality from 0-100 to 0-9
$scaleQuality = round(($imageQuality/100) * 9);
// *** Invert qualit setting as 0 is best, not 9
$invertScaleQuality = 9 - $scaleQuality;
$this->checkInterlaceImage($this->isInterlace);
if (imagetypes() & IMG_PNG) {
imagepng($this->imageResized, $savePath, $invertScaleQuality);
} else { $error = 'png'; }
break;
and more specifically this
imagepng($this->imageResized, $savePath, $invertScaleQuality);
There is no errors while I upload jpg images..
Here is in my upload file where is the problem
$magicianObj = new imageLib($filepath);
$magicianObj->resizeImage(300, 300);
$magicianObj->saveImage($folderName . 'thumb/' . $filename, 300);
When I resize them,.

Rereading your post again it looks like you are having problems with all png files. What value are you using for the png image quality as this line recalculates it:
$scaleQuality = round(($imageQuality/100) * 9);
If you use an image quality in you code of 9 it will be changed to 0.81
Then again this line
$invertScaleQuality = 9 - $scaleQuality;
would convert the 0.81 to 8.19
Anyway I guess the problem is in the php file and not GD. I would echo some of the code out to see what values are being passed to the GD code.
You could also try hardcoding $invertScaleQuality to a value between 0 and 9 to see if that works.

Related

Imagemagick does not set image to exact sizes

I have an image that i want to set to 1024 x 768 and this is the code i am using
<?php
function autoRotateImage($image) {
$orientation = $image->getImageOrientation();
switch($orientation) {
case imagick::ORIENTATION_BOTTOMRIGHT:
$image->rotateimage("#000", 180); // rotate 180 degrees
break;
case imagick::ORIENTATION_RIGHTTOP:
$image->rotateimage("#000", 90); // rotate 90 degrees CW
break;
case imagick::ORIENTATION_LEFTBOTTOM:
$image->rotateimage("#000", -90); // rotate 90 degrees CCW
break;
}
// Now that it's auto-rotated, make sure the EXIF data is correct in case the EXIF gets saved with the image!
$image->setImageOrientation(imagick::ORIENTATION_TOPLEFT);
}
$image = 'C:\xampp\htdocs\uncompressed_images\20221016_120159.jpg';
// Create new Imagick Object
$imagick = new Imagick($image);
// Set the Compression to COMPRESSION_JPEG
$imagick->setImageCompression(imagick::COMPRESSION_JPEG);
// Set the Compression quality
// This is where that compression method imagick::COMPRESSION_JPEG is
// used in the program.
$imagick->setImageCompressionQuality(26);
$imagick->thumbnailImage(1024,768);
autoRotateImage($imagick);
// Show the output
$imagick->setformat('jpg');
$imagick->writeImage($image);
header("Content-Type: image/jpg");
echo $imagick->getImageBlob();
?>
However the output image is always 768 x 1024 How can i have the resulting to be 1024 x 768?
How can i also write image to a specific directory in this line $imagick->writeImage($image); i.e output directory
You should use autoRotateImage to fix any orientation issue first (so now the image is in right orientation) , and then apply thumbnailImage for resizing
So change
$imagick->thumbnailImage(1024,768);
autoRotateImage($imagick);
to
autoRotateImage($imagick);
$imagick->thumbnailImage(1024,768);

Image is rotated 90 degree when displayed (image captured by a smartphone)

Hi I am working on a php site where user can use PHP to upload an image and then the system will display the image , resized (to a smaller size). The resize codes are as follows:
<?php
ini_set('memory_limit', -1);
ini_set('max_execution_time', 40000);
require_once 'ThumbLib.inc.php';
$fileName = (isset($_GET['file'])) ? urldecode($_GET['file']) : null;
$thumb = PhpThumbFactory::create($fileName);
$thumb->Resize($_GET['width'], $_GET['height']);
$thumb->show();
?>
where the html codes are
<img src="show_image.php?width=230&height=1000000&file=appsub/<?php echo $v["xfile"]; ?>">
There is nothing wrong if the user uploads the image thru a PC, but when the user captures a photo using a smartphone (e.g. iPhone), sometimes the image displayed will be rotated by 90 degree .
How can I fix the problem ?
if you are not saving the rotated image, you may use the following to display it (after rotation)
<?php
// File and rotation
$filename = 'test.jpg';
$degrees = 180;
// Content type
header('Content-type: image/jpeg');
// Load
$source = imagecreatefromjpeg($filename);
// Rotate
$rotate = imagerotate($source, $degrees, );
// Output
imagejpeg($rotate);
// Free the memory
imagedestroy($source);
imagedestroy($rotate);
?>
The photo may have a "orientation" data so that you can rotate it back to normal if you want. You may use the following codes right after the user has uploaded the image:
Please note that your server must have Imagick installed. (most new servers have)
<?php
function autoRotateImage($image) {
$orientation = $image->getImageOrientation();
switch($orientation) {
case imagick::ORIENTATION_BOTTOMRIGHT:
$image->rotateimage("#000", 180); // rotate 180 degrees
break;
case imagick::ORIENTATION_RIGHTTOP:
$image->rotateimage("#000", 90); // rotate 90 degrees CW
break;
case imagick::ORIENTATION_LEFTBOTTOM:
$image->rotateimage("#000", -90); // rotate 90 degrees CCW
break;
}
// Now that it's auto-rotated, make sure the EXIF data is correct in case the EXIF gets saved with the image!
$image->setImageOrientation(imagick::ORIENTATION_TOPLEFT);
}
?>
<?php
$image = new Imagick('./sourcepath/'.$upload1);
autoRotateImage($image);
// - Do other stuff to the image here -
$image->writeImage('./destinationpath/'. $upload1);
?>

Why size becomes bigger when using imagecreatefromjpeg / png / gif / bmp as needed to add watermark

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.

Resizing picture with PHP? [duplicate]

This question already has answers here:
imagecreatefromjpeg and similar functions are not working in PHP
(14 answers)
Closed 8 years ago.
I need to resize a picture to a fixed size. But it doesn't work and have error, what do i do?
ONLINE DEMO: http://codepad.org/3OrIHfoy
ERROR:
Fatal error: Call to undefined function imagecreatefromjpeg() on line
58
PHP:
<?php
function thumbnail_box($img, $box_w, $box_h) {
//create the image, of the required size
$new = imagecreatetruecolor($box_w, $box_h);
if($new === false) {
//creation failed -- probably not enough memory
return null;
}
//Fill the image with a light grey color
//(this will be visible in the padding around the image,
//if the aspect ratios of the image and the thumbnail do not match)
//Replace this with any color you want, or comment it out for black.
//I used grey for testing =)
$fill = imagecolorallocate($new, 200, 200, 205);
imagefill($new, 0, 0, $fill);
//compute resize ratio
$hratio = $box_h / imagesy($img);
$wratio = $box_w / imagesx($img);
$ratio = min($hratio, $wratio);
//if the source is smaller than the thumbnail size,
//don't resize -- add a margin instead
//(that is, dont magnify images)
if($ratio > 1.0)
$ratio = 1.0;
//compute sizes
$sy = floor(imagesy($img) * $ratio);
$sx = floor(imagesx($img) * $ratio);
//compute margins
//Using these margins centers the image in the thumbnail.
//If you always want the image to the top left,
//set both of these to 0
$m_y = floor(($box_h - $sy) / 2);
$m_x = floor(($box_w - $sx) / 2);
//Copy the image data, and resample
//
//If you want a fast and ugly thumbnail,
//replace imagecopyresampled with imagecopyresized
if(!imagecopyresampled($new, $img,
$m_x, $m_y, //dest x, y (margins)
0, 0, //src x, y (0,0 means top left)
$sx, $sy,//dest w, h (resample to this size (computed above)
imagesx($img), imagesy($img)) //src w, h (the full size of the original)
) {
//copy failed
imagedestroy($new);
return null;
}
//copy successful
return $new;
}
$i = imagecreatefromjpeg("http://techstroke.com/wp-content/uploads/2008/12/image2.png");
$thumb = thumbnail_box($i, 210, 150);
imagedestroy($i);
if(is_null($thumb)) {
/* image creation or copying failed */
header('HTTP/1.1 500 Internal Server Error');
exit();
}
header('Content-Type: image/jpeg');
imagejpeg($thumb);
that error...
Fatal error: Call to undefined function imagecreatefromjpeg() on line 58
imagecreatefromjpeg() is not callable because it does not exist. This means that the GD library has yet to be installed on your system.
here are the installation notes. you'll need them to get everything going. since you snagged that php function off the internet, it should work okay once you get the GD library installed.

Checking image file type

I'm attempting to add a function to my site where users can set their profile picture as an image from an external url, instead of saving it to their pc, then uploading it to my server.
This is what I've come up with so far:
$filename = $inputs['image_url'];
if(getimagesize($filename)){
// Get new dimensions
list($width, $height) = getimagesize($filename);
$new_width = 100;
$new_height = 100;
// Resample
$image_p = imagecreatetruecolor($new_width, $new_height);
//a check needs to be done here $image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
$filename = "profile_pictures/". md5( uniqid(rand(),true) ).".jpg";
imagejpeg($image_p,$filename,100);
}else{
echo 'This is not an image';
}
The code can download .jpg images fine, but I want to support other filetypes too.
I need to somehow check the file type of the image so I can save other images with different filetypes...
if($extension=="jpg" || $extension=="jpeg"){
$image = imagecreatefromjpeg($filename);
}else if($extension=="png"){
image = imagecreatefrompng($filename);
}else{
$image = imagecreatefromgif($filename);
}
Does anyone know of a function that would allow me to do this?
Thanks in advance for any replies.
Most straight forward and for GD compatiblity checking you can just create it from string:
$image = imagecreatefromstring(file_get_contents($filename));
If this fails to load, you know that you can not process that image.
But see as well getimagesize, it inspects the filetype as well, not only width and height:
list($width, $height, $type) = getimagesize($filename);
The third element, $type, then is any of these IMAGETYPE_XXX constants:
Value Constant
1 IMAGETYPE_GIF
2 IMAGETYPE_JPEG
3 IMAGETYPE_PNG
4 IMAGETYPE_SWF
5 IMAGETYPE_PSD
6 IMAGETYPE_BMP
7 IMAGETYPE_TIFF_II (intel byte order)
8 IMAGETYPE_TIFF_MM (motorola byte order)
9 IMAGETYPE_JPC
10 IMAGETYPE_JP2
11 IMAGETYPE_JPX
12 IMAGETYPE_JB2
13 IMAGETYPE_SWC
14 IMAGETYPE_IFF
15 IMAGETYPE_WBMP
16 IMAGETYPE_XBM
17 IMAGETYPE_ICO
From exif_imagetype. If you combine both, you could first check if the type is okay to load for you and you then check if you can load it.
Splfileinfo::getextension.php might be just what you need.
Edit : I misread, you only want to check the extension of a string. There isn't built-in function for that in PHP, you can simply use a regexp :
$ext = substr(strrchr($fileName,'.'),1);
You can try of of this
$fileExtention = pathinfo ( $filename, PATHINFO_EXTENSION );
Or
$fileExtention = image_type_to_extension(exif_imagetype($filename));
Finally i would advice you use something like http://phpthumb.sourceforge.net/ is has more than what you need to manipulate images

Categories