I'm refactoring an old image crop/resize library i wrote about 5 years ago and i'm stuck trying to restore one of it's functionalities. The funny part is that i'm not even sure it worked back then since i probably never actually used it.
I need to be able to work on png images while keeping transparency (which works), but i also wan't to be able to fill the transparent part of the image with a color.
Creating a blank image and filling it with a color works fine, but when i try to paste my png over it, the background is transparent again.
Here's a simplified version of my code:
<?php
$src = imagecreatefrompng($pathToSomePngFile);
imagealphablending($src, false);
imagesavealpha($src, true);
$output = imagecreatetruecolor($width, $height);
if ($backgroundColor) {
$fillColor = imagecolorallocate(
$output,
$backgroundColor['r'],
$backgroundColor['g'],
$backgroundColor['b']
);
imagefilledrectangle(
$output,
0,
0,
$width,
$height,
$fillColor
);
} else {
imagealphablending($output, false);
imagesavealpha($output, true);
}
imagecopyresampled(
$output,
$src,
0,
0,
0,
0,
$width,
$height,
$width,
$height
);
imagepng($output, $pathToWhereImageIsSaved);
UPDATE
Updated with delboy1978uk's solution to get it to work without changing my other settings.
Something like this should work.
<?php
// open original image
$img = imagecreatefrompng($originalTransparentImage);
$width = imagesx($img);
$height = imagesy($img);
// make a plain background with the dimensions
$background = imagecreatetruecolor($width, $height);
$color = imagecolorallocate($background, 127, 127, 127); // grey background
imagefill($background, 0, 0, $color);
// place image on top of background
imagecopy($background, $img, 0, 0, 0, 0, $width, $height);
//save as png
imagepng($background, '/path/to/new.png', 0);
Related
I have created a script where I am placing an image in the center of another image using the PHP GD library. After that I've placed a PNG frame above that center placed image.
I now want to a give that image a 3D effect, or some shadow around the edges will work for me. How can I do that ?
// Get Product Image sizes
list($width, $height) = getimagesize($filename);
// Load
$source = imagecreatefromjpeg($filename);
// Output
if(isset($frame_image) && !empty($frame_image))
{
$png = imagecreatefrompng($frame_image);
list($newwidthf, $newheightf) = getimagesize($frame_image);
$out = imagecreatetruecolor($width, $height);
imagecopyresampled($out, $source, 0, 0, 0, 0, $width, $height, $width, $height);
imagecopyresampled($out, $png,0, 0, 0, 0, $width, $height, $newwidthf, $newheightf);
$final = imagejpeg($out);
}
else
{
$final = imagejpeg($source);
}
Here is the image which I have generated:
I'm using imagescale and a shadow background, work
I'm currently writing a script to add watermarks to images. Said watermarks vary in their opacity.
For example, the base watermark image is a PNG with a fully visible text and a transparent background. When added, I want to fade this base PNG to fit my needs and to make an opaque watermark.
To do that, I use imagefilter() to fade the PNG:
$opacity = 0.25;
$watermarkRes = imagecreatefrompng($filename);
imagealphablending($watermarkRes, false);
imagesavealpha($watermarkRes, true);
$transparency = 1 - $opacity;
imagefilter(
$watermarkRes,
IMG_FILTER_COLORIZE,
0,
0,
0,
127*$transparency
);
imagepng($watermarkRes, $filename);
All non-transparent areas get faded nicely, but the existing transarent areas get blackened.
This is the result of the above code:
https://preview.ibb.co/j8zePF/TEST.png
Used as a watermark it looks like this:
https://preview.ibb.co/mLvKPF/15027295625991d55a1ef081_42502547.jpg
While the desired result should be this:
https://preview.ibb.co/f81R4F/TEST_15027295625991d55a1ef081_42502547.jpg
How can I achieve to add opacity to the text while maintaining the transparent areas as they are?
Nevermind. The issue was not the function itself, but the fact that I resized the height of the watermark according to its use beforehand.
I removed this code to resize the watermark:
$new_image = imagecreatetruecolor($width, $height);
imagecopyresampled($new_image, $watermarkRes, 0, 0, 0, 0, $width, $height, imagesx($watermarkRes), imagesy($watermarkRes));
$watermarkRes = $new_image;
And instead used the resize code of Dycey provided in the answer to this question:
How do I resize pngs with transparency in PHP?
For my case I created this function to resize images:
/**
* #param int $width
* #param int $height
*/
public function resize($width, $height)
{
$new_image = imagecreatetruecolor($width, $height);
if($this->image_type === IMAGETYPE_PNG || $this->image_type === IMAGETYPE_GIF) {
imagealphablending($new_image, false);
imagesavealpha($new_image,true);
$transparent = imagecolorallocatealpha(
$new_image, 255, 255, 255, 127
);
imagefilledrectangle(
$new_image, 0, 0, $width, $height, $transparent
);
}
imagecopyresampled(
$new_image,
$this->image,
0, 0, 0, 0,
$width, $height,
imagesx($this->image), imagesy($this->image)
);
$this->image = $new_image;
}
I have looked through so many other threads with people having trouble with a png image going black where it should be transparent and none of the solutions have worked for me.
Maybe I am going wrong else where in the code? Maybe imagealhpablending isnt supported by my web server?
Thanks for anyone that can help.
$photo = imagecreatefrompng( "{$thumb_folder}{$new_file_name}" );
$width = imagesx($photo);
$height = imagesy($photo);
$new_width = 32;
$new_height = floor($height / ($width / $new_width));
$temp_photo = imagecreatetruecolor($new_width, $new_height);
imagealphablending($temp_photo, false);
imagesavealpha($temp_photo, true);
$transparent = imagecolorallocatealpha($temp_photo, 255, 255, 255, 127);
imagefilledrectangle($temp_photo, 0, 0, $new_width, $new_height, $transparent);
imagecopyresampled($temp_photo, $photo, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
imagepng($temp_photo, "{$thumb_folder}{$new_file_name}" );
The first colour allocated to an image is always the background colour anyway, so there is no need to draw that filled rectangle. Remove it from the code, and see what you get.
I have a small class which handles image manipulation.
I use following to resize a image
$this->image = imagecreatefrompng($filename);
....
$new_image = imagecreatetruecolor($width, $height);
imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
...
$this->image = $new_image;
imagepng($this->image,$filename)) { return true; }
But the resized image is not preserving transparency, instead black is comming, how can i preserve the transparency.
Update
After, using #Manuel's code, black portion has decreased, but still black background are still present. The source image and the resulting image are
Source & Sub corresponding
main http://www.freeimagehosting.net/newuploads/820a0.png sub http://www.freeimagehosting.net/newuploads/30526.png
The newest comment, posted on the 8th of May, on the manual page for imagecopyresampled, tells you how to do this.
imagecolortransparent($new_image, imagecolorallocatealpha($new_image, 0, 0, 0, 127));
imagealphablending($new_image, false);
imagesavealpha($new_image, true);
Put that right after creating $new_image.
add this before the imagecopyresampled(...)
// preserve transparency
imagecolortransparent($new_image , imagecolorallocatealpha($new_image , 0, 0, 0, 127));
imagealphablending($new_image , false);
imagesavealpha($new_image , true);
I am trying to write text onto a png, however when I do it puts a dark border around it, I am not sure why.
The original image:
The processed image:
Code:
// Load the image
$im = imagecreatefrompng("admin/public/images/map/order/wally.png");
// If there's an error, gtfo
if(!$im) {
die("");
}
$textColor = imagecolorallocate($im, 68, 68, 68);
$width = imagesx($im);
$height = imagesy($im);
$fontSize = 5;
$text = "AC";
// Calculate the left position of the text
$leftTextPos = ($width - imagefontwidth($fontSize)*strlen($text)) / 2;
// Write the string
imagestring($im, $fontSize, $leftTextPos, $height-28, $text, $textColor);
// Output the image
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
I've had this issue several times, let me find the answer...
Ok, found something:
imagesavealpha($im, true);
imagealphablending($im, true);
Write that before imagepng.
Yes, saving with alpha is important but loading it is important as well. Your PNG image might have transparency but it is good practice to account for that as well.
You'd need to create true color image, set alpha color and then draw your loaded image with text over it. So something like this:
// create true color image
$img = imagecreatetruecolor($width, $height);
$transparent_color = imagecolorallocatealpha($img, 255, 255, 255, 0);
imagealphablending($img, false);
imagefillrectangle($img, 0, 0, $width, $height, $transparent_color);
imagealphablending($img, true);
// draw previously loaded PNG image
imagecopy($img, $loaded_img, 0, 0, 0, 0, $width, $height);
// draw your text
// save the whole thing
imagesavealpha($img, true);
imagepng($img, $file);