I have the task to develop a plugin for WordPress that adds watermark to uploaded images using PHP. WP hosted on AWS Bitnami. They all need to be exactly 800x800px so I upscale/downscale the source image and then add the PNG watermark.
For some reason, most of the time images end up with terrible grey artifacts on them. 5% of the time they are perfectly okay, I could not see any patterns that lead to success.
This is what happens:
Image with failed watermark
Image with good watermark
This is my code:
function add_watermark($resized_image) {
ini_set('memory_limit', '256M');
$watermark = imagecreatefrompng( '/transparency-award-watermark.png' );
imagealphablending($watermark, false); // Saw that on StackOverflow, didn't help
imagesavealpha($watermark, true); // That one too
$info = getimagesize($resized_image);
if(max($info[0], $info[1]) != 800) {
resize_image($resized_image);
}
if( $info[2] == IMG_JPG or $info[2] == IMG_JPEG ) $image = imagecreatefromjpeg($resized_image);
if( $info[2] == IMG_PNG ) $image = imagecreatefrompng($resized_image);
$sx = imagesx($watermark);
$sy = imagesy($watermark);
imagecopy($image, $watermark, imagesx($image) - $sx, imagesy($image) - $sy, 0, 0, imagesx($watermark), imagesy($watermark));
imagejpeg($image, $resized_image, 95);
imagedestroy($image);
imagedestroy($watermark);
}
function resize_image($orig_image) {
$info = getimagesize($orig_image);
if( $info[2] == IMG_JPG or $info[2] == IMG_JPEG ) $source_image = imagecreatefromjpeg($orig_image);
if( $info[2] == IMG_PNG ) $source_image = imagecreatefrompng($orig_image);
$source_imagex = imagesx($source_image);
$source_imagey = imagesy($source_image);
$dest_imagex = 800;
$dest_imagey = 800;
$dest_image = imagecreatetruecolor($dest_imagex, $dest_imagey);
imagecopyresampled($dest_image, $source_image, 0, 0, 0, 0,
$dest_imagex, $dest_imagey, $source_imagex, $source_imagey);
imagejpeg($dest_image, $orig_image, 100);
}
Related
I have this code, for changing the width of the image:
function resize_img($file,$width,$height=null){
$ext = pathinfo($file, PATHINFO_EXTENSION);
if($ext=='jpg' || $ext=='jpeg'){
$img = imagecreatefromjpeg($file);
} else if($ext=='png'){
$img = imagecreatefrompng($file);
}
$img_w = imagesx($img);
$img_h = imagesy($img);
$ratio = $width / $img_w;
$new_h = $img_h * $ratio;
$new_h = $height??$new_h;
$new_img = imagecreatetruecolor($width,$new_h);
imagecopyresampled($new_img, $img, 0, 0, 0, 0, $width, $new_h, $img_w, $img_h);
if($ext=='jpg' || $ext=='jpeg'){
imagejpeg($new_img, $file, 82);
} else if($ext=='png'){
imagepng($new_img, $file);
}
}
I would like to add the ability to change the width along with the height while keeping the aspect. Now resolution is changing, but isn't filled (it's streched) How can I do that? Is this possible?
I have a problem in my images using the GD library in my live site.
Is there an issue of GD library in linux? I implemented the resizing and cropping of image using the GD library, but somehow only the resizing works. Also, png images have black background after resized. My codes are working totally fine in local but not in my hosted site. I didn't get any errors so I am not sure where the problem is.
This is my code:
$info = getimagesize($src);
$source_image = '';
if ($info['mime'] == 'image/jpeg')
$source_image = imagecreatefromjpeg($src);
elseif ($info['mime'] == 'image/gif')
$source_image = imagecreatefromgif($src);
elseif ($info['mime'] == 'image/png')
$source_image = imagecreatefrompng($src);
$cropped = imagecropauto($source_image, IMG_CROP_DEFAULT);
if ($cropped !== false) {
imagedestroy($source_image);
$source_image = $cropped;
}
$width = imagesx($source_image);
$height = imagesy($source_image);
$maxHeight = floor($height * ($maxWidth / $width));
$dst = imagecreatetruecolor($maxWidth, $maxHeight);
$background = imagecolorallocate($dst, 0, 0, 0);
imagecolortransparent($dst, $background);
imagealphablending($dst, false);
imagesavealpha($dst,true);
imagecopyresampled($dst, $source_image, 0, 0, 0, 0, $maxWidth, $maxHeight, $width, $height);
if ($info['mime'] == 'image/jpeg')
imagejpeg($dst, $newFilename);
elseif ($info['mime'] == 'image/gif')
imagegif($dst, $newFilename);
elseif ($info['mime'] == 'image/png')
imagepng($dst, $newFilename);
Please help. Thank You
Replace IMG_CROP_DEFAULT with IMG_CROP_SIDES
also read documentation click here you also fill color using
<?php
// Create a 300x300px transparant image with a 100px wide red circle in the middle
$i = imagecreatetruecolor(300, 300);
imagealphablending($i, FALSE);
imagesavealpha($i, TRUE);
$transparant = imagecolorallocatealpha($i, 0xDD, 0xDD, 0xDD, 0x7F);
imagecolortransparent($i, $transparant); // Set background transparent
imagefill($i, 0, 0, $transparant);
$red = imagecolorallocate($i, 0xFF, 0x0, 0x0);
imagefilledellipse($i, 150, 150, 100, 100, $red);
imagepng($i, "red_300.png");
// Crop away transparant parts and save
$i2 = imagecropauto($i, IMG_CROP_DEFAULT); //Attempts to use IMG_CROP_TRANSPARENT and if it fails it falls back to IMG_CROP_SIDES.
imagepng($i2, "red_crop_trans.png");
imagedestroy($i2);
// Crop away bg-color parts and save
$i2 = imagecropauto($i, IMG_CROP_SIDES);
imagepng($i2, "red_crop_sides.png");
imagedestroy($i2);
// clean up org image
imagedestroy($i);
?>
I need to add watermark on uploaded image and also resize it to make thumbnails and icons from that watermarked image. Below is my function code which is adding watermark but I can't find out how to resize image to given height and width:
function watermark_image_new($target, $wtrmrk_file, $newcopy, $extension, $w = 0, $h = 0) {
$watermark = imagecreatefrompng($wtrmrk_file);
imagealphablending($watermark, false);
imagesavealpha($watermark, true);
//resize code
if ($w != 0) {
list($width, $height) = getimagesize($target);
if ($extension == 'jpeg' || $extension == 'jpg') {
$img = imagecreatefromjpeg($target);
} else if ($extension == 'png') {
$img = imagecreatefrompng($target);
}
$dst = imagecreatetruecolor($newwidth, $newheight);
imagecopyresampled($dst, $img, 0, 0, 0, 0, $w, $h, $width, $height);
}
$img_w = imagesx($img);
$img_h = imagesy($img);
$wtrmrk_w = imagesx($watermark);
$wtrmrk_h = imagesy($watermark);
$dst_x = ($img_w / 2) - ($wtrmrk_w / 2); // For centering the watermark on any image
$dst_y = ($img_h / 2) - ($wtrmrk_h / 2); // For centering the watermark on any image
imagecopy($img, $watermark, $dst_x, $dst_y, 0, 0, $wtrmrk_w, $wtrmrk_h);
if ($extension == 'jpeg' || $extension == 'jpg') {
imagejpeg($img, $newcopy, 100);
} else if ($extension == 'png') {
imagepng($img, $newcopy);
}
imagedestroy($img);
imagedestroy($watermark);
}
A simple example to use Imagick for solve your case. To render Watermark and resize it and output the changed image
<?php
$image = new Imagick();
$image->readImage("/path/to/image.jpg");
$watermark = new Imagick();
$watermark->readImage("/path/to/watermark.png");
// how big are the images?
$iWidth = $image->getImageWidth();
$iHeight = $image->getImageHeight();
$wWidth = $watermark->getImageWidth();
$wHeight = $watermark->getImageHeight();
if ($iHeight < $wHeight || $iWidth < $wWidth) {
// resize the watermark
$watermark->scaleImage($iWidth, $iHeight);
// get new size
$wWidth = $watermark->getImageWidth();
$wHeight = $watermark->getImageHeight();
}
// calculate the position
$x = ($iWidth - $wWidth) / 2;
$y = ($iHeight - $wHeight) / 2;
$image->compositeImage($watermark, imagick::COMPOSITE_OVER, $x, $y);
header("Content-Type: image/" . $image->getImageFormat());
echo $image;
I'm using a pre-written script found at 1st Web Magazine - Generate Thumbnail On The Fly.
I copied the script over to my server, but it's giving me the following error: Parse error: syntax error, unexpected '$ratio_orig' (T_VARIABLE) in /storage/emulated/legacy/www/jollyroger/jollyroger/img/gallery_temp/thumbnail.php on line 23
I've went through the code and I cannot spot any actual errors. Everything seems to be in order.
Could someone take a look at this code and tell me if I am overlooking something? From what I can gather it seems that something in the list() function is throwing off the variables.
This is the code actually in my file:
<?php
// thumb width
$square = 150;
$large = 200;
$small = 100;
////////////////////////////////////////////////////////////////////////////////// square
if( isset($_GET["img"]) && ( $_GET["type"] == "square" || $_GET["type"] == "" ) ){
// thumb size
$thumb_width = $square;
$thumb_height = $square;
// align
$align = $_GET["align"];
// image source
$imgSrc = $_GET["img"];
$imgExt = substr($imgSrc,-3);
// image extension
if($imgExt == "jpg"){ $myImage = imagecreatefromjpeg($imgSrc); }
if($imgExt == "gif"){ $myImage = imagecreatefromgif($imgSrc); }
if($imgExt == "png"){ $myImage = imagecreatefrompng($imgSrc); }
// getting the image dimensions
list($width_orig, $height_orig) = getimagesize($imgSrc);
// ratio
$ratio_orig = $width_orig/$height_orig;
// landscape or portrait?
if ($thumb_width/$thumb_height > $ratio_orig) {
$new_height = $thumb_width/$ratio_orig;
$new_width = $thumb_width;
} else {
$new_width = $thumb_height*$ratio_orig;
$new_height = $thumb_height;
}
// middle
$x_mid = $new_width/2;
$y_mid = $new_height/2;
// create new image
$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($thumb_width, $thumb_height);
// alignment
if($align == ""){
imagecopyresampled($thumb, $process, 0, 0, ($x_mid-($thumb_width/2)), ($y_mid-($thumb_height/2)), $thumb_width, $thumb_height, $thumb_width, $thumb_height);
}
if($align == "top"){
imagecopyresampled($thumb, $process, 0, 0, ($x_mid-($thumb_width/2)), 0, $thumb_width, $thumb_height, $thumb_width, $thumb_height);
}
if($align == "bottom"){
imagecopyresampled($thumb, $process, 0, 0, ($x_mid-($thumb_width/2)), ($new_height-$thumb_height), $thumb_width, $thumb_height, $thumb_width, $thumb_height);
}
if($align == "left"){
imagecopyresampled($thumb, $process, 0, 0, 0, ($y_mid-($thumb_height/2)), $thumb_width, $thumb_height, $thumb_width, $thumb_height);
}
if($align == "right"){
imagecopyresampled($thumb, $process, 0, 0, ($new_width-$thumb_width), ($y_mid-($thumb_height/2)), $thumb_width, $thumb_height, $thumb_width, $thumb_height);
}
imagedestroy($process);
imagedestroy($myImage);
if($imgExt == "jpg"){ imagejpeg($thumb, null, 100); }
if($imgExt == "gif"){ imagegif($thumb); }
if($imgExt == "png"){ imagepng($thumb, null, 9); }
}
// normal
if(isset($_GET["img"]) && ($_GET["type"] == "large" || $_GET["type"] == "small" ) ){
if( $_GET["type"] == "large" ){ $thumb_width = $large; }
if( $_GET["type"] == "small" ){ $thumb_width = $small; }
// image source
$imgSrc = $_GET["img"];
$imgExt = substr($imgSrc,-3);
// image extension
if($imgExt == "jpg"){ $myImage = imagecreatefromjpeg($imgSrc); }
if($imgExt == "gif"){ $myImage = imagecreatefromgif($imgSrc); }
if($imgExt == "png"){ $myImage = imagecreatefrompng($imgSrc); }
//getting the image dimensions
list($width_orig, $height_orig) = getimagesize($imgSrc);
// ratio
$ratio_orig = $width_orig/$height_orig;
$thumb_height = $thumb_width/$ratio_orig;
// new dimensions
$new_width = $thumb_width;
$new_height = $thumb_height;
// middle
$x_mid = $new_width/2;
$y_mid = $new_height/2;
// create new image
$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($thumb_width, $thumb_height);
imagecopyresampled($thumb, $process, 0, 0, ($x_mid-($thumb_width/2)), ($y_mid-($thumb_height/2)), $thumb_width, $thumb_height, $thumb_width, $thumb_height);
if($imgExt == "jpg"){ imagejpeg($thumb, null, 100); }
if($imgExt == "gif"){ imagegif($thumb); }
if($imgExt == "png"){ imagepng($thumb, null, 9); }
}
?>
Even this line in my editor is highlighted red which indicates an error, but since the variable is triggering a php error this one has not shown up in any logs yet. Looking over this line I cannot spot anything wrong at all.
if(isset($_GET["img"]) && ($_GET["type"] == "large" || $_GET["type"] == "small" ) ){
I copied the code direct from the website so I'm at a loss as to why it is not working. As I said I've looked it over and everything seems to be in order, so I'm at a complete loss.
Also this script is in the same directory as my image files. My test url looks like so: http://localhost:8080/jollyroger/jollyroger/img/gallery_temp/thumbnail.php?img=1959523_1501438810115481_7515978806557307096_n.jpg
I think I found something.
you have the following line:
list($width_orig, $height_orig) = getimagesize($imgSrc);
which seems really weird to me. You are equalling a function to a function which might cause the error on the next line.
If that's not the problem then either you forgot a ; or you tried to access the variable before you set its value somewhere.
I created a function that takes images, resizes them to fit at least one dimension perfectly onto a canvas and finally crops out excess image content.
Process:
Take a 640x400 image
Scale image fit into 450x450 canvas (image is now 450x281)
Crop out excess data if any
The problem I'm encountering currently involves images that are too small for the newly created thumbnail (such as the one provided in the example above). I expected the output to either have a white background(JPGs) or a transparent background(PNGs). However, despite my best efforts, this tends to be the resulting mess:
As can be observed, the image has a black background in place of a transparent/white background. I am completely stumped on how to correct this flaw.
A copy of my code:
function create_thumbnail($path, $saveto, $width, $height) {
ini_set('memory_limit', '128M'); //Unlocking more memory for download
$info = getimagesize($path);
$rate = $info[0]/$info[1];
// Determine image size/position
if ($info[0] < $width || $info[1] < $height) {
// Image is too small
if ($info[0] < $width && $info[1] < $height) {
// Both width and height too small
$nw = $info[0];
$nh = $info[1];
} else if ($info[0] < $width) {
// Width is too small
$nw = ($info[0]*$height)/$info[1];
$nh = $height;
} else if ($info[1] < $height) {
// Height is too small
$nw = $width;
$nh = ($info[1]*$width)/$info[0];
}
} else {
// Image fits
if (($width/$height) > $rate) {
$nw = $width;
$nh = $width/$rate;
} else {
$nw = $height*$rate;
$nh = $height;
}
}
$nw = round($nw);
$nh = round($nh);
$x_mid = round($nw/2);
$y_mid = round($nh/2);
switch($info[2]) {
case IMAGETYPE_PNG :
$src = imagecreatefrompng($path);
break;
case IMAGETYPE_JPEG :
$src = imagecreatefromjpeg($path);
break;
case IMAGETYPE_GIF :
$src = imagecreatefromgif($path);
break;
default :
return false;
}
// Create image
$proc = imagecreatetruecolor($nw, $nh);
$clr = imagecolorallocate($proc, 255, 255, 255);
imagefill($proc, 0, 0, $clr);
imagecopyresampled($proc, $src, 0, 0, 0, 0, $nw, $nh, $info[0], $info[1]);
$thmb = imagecreatetruecolor($width, $height);
$clr = imagecolorallocate($thmb, 255, 255, 255);
imagefill($thmb, 0, 0, $clr);
imagecopyresampled($thmb, $proc, 0, 0, ($x_mid-($width/2)), ($y_mid-($height/2)), $width, $height, $width, $height);
if ($info[2] == IMAGETYPE_PNG || $info[2] == IMAGETYPE_GIF) {
$trnprt_idx = imagecolortransparent($src);
if ($trnprt_idx >= 0) {
// Attempt to forcefully correct transparencies using original image's color index
$trnprt_clr = imagecolorsforindex($src, $trnprt_idx);
$trnprt_idx = imagecolorallocate($thmb, $trnprt_clr['red'], $trnprt_clr['green'], $trnprt_clr['blue']);
imagefill($thmb, 0, 0, $trnprt_idx);
imagecolortransparent($thmb, $trnprt_idx);
imagealphablending($thmb, false);
imagesavealpha($thmb, true);
} else if ($info[2] == IMAGETYPE_PNG) {
// Attempt to forcefully correct transparencies by shutting down blending
$clr = imagecolorallocatealpha($thmb, 0, 0, 0, 127);
imagefill($thmb, 0, 0, $clr);
imagealphablending($thmb, false);
imagesavealpha($thmb, true);
}
}
switch($info[2]) {
case IMAGETYPE_PNG :
imagepng($thmb, $saveto);
break;
case IMAGETYPE_JPEG :
imagejpeg($thmb, $saveto, 100);
break;
case IMAGETYPE_GIF :
imagegif($thmb, $saveto);
break;
default :
return false;
}
return true;
} //End of create_thumbnail()
I have attempted to correct the transparency/coloring (as visible in my code), but it only affects one side of the image. Everything I have tried has either resulting in one side having a transparent/white background or both sides being completely black.
After a long time spent playing around trying to figure out what exactly was going on and breaking, I have found the solution.
The problem is here:
$proc = imagecreatetruecolor($nw, $nh);
$clr = imagecolorallocate($proc, 255, 255, 255);
imagefill($proc, 0, 0, $clr);
imagecopyresampled($proc, $src, 0, 0, 0, 0, $nw, $nh, $info[0], $info[1]);
$thmb = imagecreatetruecolor($width, $height);
$clr = imagecolorallocate($thmb, 255, 255, 255);
imagefill($thmb, 0, 0, $clr);
imagecopyresampled($thmb, $proc, 0, 0, ($x_mid-($width/2)), ($y_mid-($height/2)), $width, $height, $width, $height);
The newly created image $proc was not transferring it's transparency over to $thmb when I was doing imagecopyresampled from one to the other. The solution I found was to either skip creating/using $thmb altogether, or to save $proc as a png/gif first, then use that saved image for imagecopyresample.