php imagepng() generating black image only on server - php

I am dynamically generating a waveform image from a user-uploaded sound file, using a script I've based on: http://andrewfreiday.com/2010/04/29/generating-mp3-waveforms-with-php/
The script works fine on my dev environment Windows 7, Apache2, PHP 5. But when I put it on my server Ubuntu Linux, Apache2 PHP 5, imagepng() outputs a black box.
I've looked into similar problems, such as Why is this creating a black image? and have made sure that my imagealphablending() and imagesavealpha() are being used the way described. But still no luck. I've checked folder permissions and confirmed that LAME can write into the proper folder without throwing an error.
I've also tried to simply set the background color to the same color as my pages backgground, as the transparency is a "nice to have," not a necessity.
Anyway, here is the PHP that outputs my image:
// want it resized?
if ($width) {
// resample the image to the proportions defined in the form
$rimg = imagecreatetruecolor($width, $height);
// save alpha from original image
imagealphablending($rimg, false);
imagesavealpha($rimg, true);
// copy to resized
imagecopyresampled($rimg, $img, 0, 0, 0, 0, $width, $height, imagesx($img), imagesy($img));
imagepng($rimg, "../img/" . $genFileName .".png");
imagedestroy($rimg);
} else {
imagealphablending($img, false);
imagesavealpha($img, true);
imagepng($img, "../img/" . $genFileName .".png");
}
imagedestroy($img);
echo "img/" . $genFileName . ".png";
} else {
echo "An error.";
}
And this is the Javascript that calls it:
//pass the audio data to the server to have the wave drawn
_generateWaveForm = function(_file){
//create the form data
_form.append('file',_file); //mp3 to be sent to the server
_form.append('height',300); //height of image to be returned
_form.append('width',window.innerWidth - 20); //width of image to be returned
_form.append('foreground','#FFFF51'); //color of image to be returned
_form.append('background',''); //background (left empty for transparent BG)
_form.append('flat',true); //setting flat to true
//pass it on
$.ajax({
url: "php/php-waveform-png_3.php",
type: "POST",
data: _form,
processData: false,
contentType: false,
success: function(_result){_gotTheWaveForm(_result)}
});
},
I've been banging my head against this for two days now, any help will be appreciated.

Try adding
$transparentColor = imagecolorallocatealpha($rimg, 0, 0, 0, 127);
imagefill($rimg, 0, 0, $transparentColor);
to
$rimg = imagecreatetruecolor($width, $height);
imagealphablending($rimg, false);
imagesavealpha($rimg, true);
Whole part:
$rimg = imagecreatetruecolor($width, $height);
imagealphablending($rimg, false);
imagesavealpha($rimg, true);
$transparentColor = imagecolorallocatealpha($rimg, 0, 0, 0, 127);
imagefill($rimg, 0, 0, $transparentColor);

Related

Fill png transparency with background color

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);

Fabric.js canvas.toDataURL() sent to PHP by Ajax

I have a problem here when I need create a image with transparent background. I still don´t know if the problem is with fabricjs or with php. Everything works fine when I sent a image with colored background. The problem occurs when I send a image with transparent background.
The generated image is created with black background.
So, let me explain better:
When the user click in save button, I´m sending the string representation of the canvas to php in the server-side, to be generated the image of the canvas. So I´m using the follow function to sending the string representation of the canvas by Ajax (POST function of jQuery):
function sendStringRepresentation(){
var strDataURI = canvas.toDataURL();
strDataURI = strDataURI.substr(22, strDataURI.length);
$.post("action/createImage.php",
{
str: strDataURI
},
function(data){
if(data == "OK"){
$("#msg").html("Image created.");
}
else{
$("#msg").html("Image not created.");
}
});
}
In PHP file I´m using the follow code to generate the image:
// createImage.php
$data = base64_decode($_POST["str"]);
$urlUploadImages = "../uploads/img/";
$nameImage = "test.png";
$img = imagecreatefromstring($data);
if($img) {
imagepng($img, $urlUploadImages.$nameImage, 0);
imagedestroy($img);
// [database code]
echo "OK";
}
else {
echo 'ERROR';
}
Again, the problem is just with background transparent canvas. With colored background everything works fine.
The last step is quite the opposite:
imagecopyresampled( $img, $alpha_image, 0, 0, 0, 0, $w, $h, $w, $h );
And voila! The image is transparent!
Why did you use GD for this? You can use file_put_contents for save png file from your canvas.
// createImage.php
$data = base64_decode($_POST["str"]);
$urlUploadImages = "../uploads/img/test.png";
file_put_contents($urlUploadImages, $data);
I don't know if this is exactly the problem you're experiencing, but some of the GD library's imagecreate* functions create images without the alpha channel.
The workaround I've found is to create an image using imagecreatetruecolor and copy your transparent image onto it.
Try a process like this:
$img = imagecreatefromstring($data);
$w = imagesx($img);
$h = imagesy($img);
$alpha_image = imagecreatetruecolor( $w, $h );
imagecopyresampled( $alpha_image, $img, 0, 0, 0, 0, $w, $h, $w, $h );
That should ensure that you end up with a "true color" image with the proper alpha channel.
JPG toDataURL transforms transparent background to black.
I had the exact same problem and added this
imageAlphaBlending($img, true);
imageSaveAlpha($img, true);
to rodrigopandini's code and it works perfect now.:)
// createImage.php
$data = base64_decode($_POST["str"]);
$urlUploadImages = "../uploads/img/";
$nameImage = "test.png";
$img = imagecreatefromstring($data);
imageAlphaBlending($img, true);
imageSaveAlpha($img, true);
if($img) {
imagepng($img, $urlUploadImages.$nameImage, 0);
imagedestroy($img);
// [database code]
echo "OK";
}
else {
echo 'ERROR';
}

how to colorize PHP result image using GD

I have a code that resize and colorize the image accordingly input values... the problem is I can able to colorize only one time with fresh image saved by other application..Please help me.. I hope there are many PHP expers are here.....
<?php
createImage(50,50, 0,0, 255);
function createImage($width, $height, $nR, $nG, $nB)
{
$image = imagecreatefrompng("source.png");
imagealphablending($image, false);
imagesavealpha($image, true);
//resize the image
$new_image = imagecreatetruecolor($width, $height);
imagealphablending($new_image, false);
imagesavealpha($new_image, true);
imagecopyresampled($new_image, $image, 0, 0, 0, 0, $width, $height, imagesx($image), imagesx($image));
//colorize the image
$nrgb = str_pad(dechex($nR), 2, '0', STR_PAD_LEFT). str_pad(dechex($nG), 2, '0', STR_PAD_LEFT). str_pad(dechex($nB), 2, '0', STR_PAD_LEFT);
$newColor = $nrgb;
$c2 = sscanf($newColor ,"%2x%2x%2x");
for($i=0;$i<$width;$i++)
{
for($j=0;$j<$height;$j++)
{
$cIndex = imagecolorat($new_image,$i,$j);
imagecolorset($new_image,$cIndex,$c2[0],$c2[1],$c2[2]);
}
}
header("Content-Type: image/png");
imagepng($new_image,"test.png");
}
?>
Sounds to me like you are manipulating an image resource and outputting it and then wanting to go back and further manipulate it without starting over. You can do this by
a) save the image resource as a session variable, and then use the session variable in subsequent alterations.
b) save the altered image before outputting it, and then open the saved altered image and go from there. I don't know what file type you are using but for instance with gif images your code should be using imagegif() to output the image. You would utilize this same function (or other image type equivalent function) to also save the image.
I suggest looking at the imagefilter function found here: http://php.net/manual/en/function.imagefilter.php
Look at IMG_FILTER_COLORIZE on that page.

Applying text to png transparency issue PHP

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);

Background transperancy in imagerotate()

Since last 2 days, I was trying to add transperancy to the background after rotating an image using imagerotate() PHP-GD function.
But, to my great disappointment, it's not working at all.
It's just giving out a black background behind it.
Here's my code -
$patchImageS = 'image.png'; // the image to be patched over the final bg
$patchImage = imagecreatefrompng($patchImageS); // resource of image to be patched
$patchImage = imagerotate($patchImage, 23, 0, 0);
imagepng($patchImage,'tt.png');
I tried to change the parameters being passed in function to
imagerotate($patchImage, 23, 5, 0);
imagerotate($patchImage, 23, 0, 5);
Any help would be highly appreciated.
After a number of 99% finished answers, here's the solution I've found:
// Create, or create from image, a PNG canvas
$png = imagecreatetruecolor($width, $height);
// Preserve transparency
imagesavealpha($png , true);
$pngTransparency = imagecolorallocatealpha($png , 0, 0, 0, 127);
imagefill($png , 0, 0, $pngTransparency);
// Rotate the canvas including the required transparent "color"
$png = imagerotate($png, $rotationAmount, $pngTransparency);
// Set your appropriate header
header('Content-Type: image/png');
// Render canvas to the browser
imagepng($png);
// Clean up
imagedestroy($png);
The key here is to include your imagecolorallocatealpha() in your imagerotate() call...
look for imagesavealpha() in the php-documentation - i think this is what you are looking for.
EDIT: here's an example:
$png = imagecreatefrompng('./alphachannel_example.png');
// Do required operations
$png = imagerotate($png, 23, 0, 0);
// Turn off alpha blending and set alpha flag
imagealphablending($png, false);
imagesavealpha($png, true);
// Output image to browser
header('Content-Type: image/png');
imagepng($png);
imagedestroy($png);
For anyone having problems with imagecopyresampled or imagerotate with black bars on background, I have found a code example here:
https://qna.habr.com/q/646622#answer_1417035
// get image sizes (X,Y)
$wx = imagesx($imageW);
$wy = imagesy($imageW);
// create a new image from the sizes on transparent canvas
$new = imagecreatetruecolor($wx, $wy);
$transparent = imagecolorallocatealpha($new, 0, 0, 0, 127);
$rotate = imagerotate($imageW, 280, $transparent);
imagealphablending($rotate, true);
imagesavealpha($rotate, true);
// get the newest image X and Y
$ix = imagesx($rotate);
$iy = imagesy($rotate);
//copy the image to the canvas
imagecopyresampled($destImg, $rotate, 940, 2050, 0, 0, $ix, $iy, $ix, $iy);

Categories