PHP convert to transparent doesn't literally make it transparent - php

I'm trying to make imageA.png transparent then merge it to another fully transparent image using imagecopy function, But after merging, imageA.png becomes white background instead of transparent
I believe it is because it was not converted to transparent properly
Here's what I used
This is a stand-alone file to convert the image to transparent ( It works ) :
$img = imagecreatefrompng("imageA.png");
$white = imagecolorallocate($img, 255, 255, 255);
imagecolortransparent($img, $white);
header('Content-Type: image/png');
imagepng($img);
and this one is to merge the above result with another transparent image
$src = imagecreatefrompng("imageA_transparent.png");
$dest = imagecreatefrompng('another_transparent_image.png');
imagesavealpha($dest, true);
imagealphablending($dest, true);
imagecopy($dest, $src, 0, 0, 0, 0, 400, 400);
the result is imageA_transparent.png becomes with white background while it is actually transparent over the second transparent used image (another_transparent_image.png)
I tried using a normal photoshopped transparent image and it worked with no problem
I tried to use both imagesavealpha and imagealphablending with $src and no effect
Both images are properly transparent before using imagecopy
** Finally, when i tried to open imageA_transparent.png ( The php-generated transparent image ), In photoshop, it appeared with white background and locked layer, This means PHP didn't convert it to transparent/png properly ( I believe )

Related

Resizing images with `imagecopyresampled` from PHP GD

Using the PHP GD library, I generate image resource that is opaque white, with some "holes" here and there, which are fully transparent disk shapes. I've attached it bellow, although you'll need to first save it and open it (in Windows) with the Image Preview application in order to see the holes in it, due to the blue-ish background. Otherwise you'll only see white.
The original image:
From that image resource, which is 2550 x 3000px, I need to create a smaller version. I do so using imagecopyresampled(). All is fine with the resulting image, with one exception: here and there, it contains grey pixels (RGB: 254,254,254):
The resized image:
Part of the code I use is bellow:
$previewPxWidth = $this->viewportWidth_;
$previewPxHeight = round($this->viewportWidth_ / $schematic['paper.aspect.ratio']);
$preview = imagecreatetruecolor($previewPxWidth, $previewPxHeight);
$noColor = imagecolorallocatealpha($preview, 255, 255, 255, 127);
imagesavealpha($preview,true);
imagefill($preview, 0, 0, $noColor);
imagecopyresampled($preview, $sheet, 0, 0, 0, 0, $previewPxWidth, $previewPxHeight, $sheetPxWidth, $sheetPxHeight);
imagedestroy($sheet);
header("Content-type: image/png");
header("Content-disposition: inline; filename=image.png");
imagepng($preview);
Where are those very light and (apparently) randomly positioned grey pixels coming from and how can I get rid of them?
Try imageAlphaBlending(), but ImageMagic is best way.

Transparent background with GD in PHP

I am trying to create a chart with PHP and GD. The chart is already working but I
can't get the background to be transparent (with anti-aliasing).
I want to place an anti-aliased line on a gradient background (this is the HTML background) but it shows some white pixels (see the image link and my code below). Is it possible to do this with GD? I have searched a lot on the Internet but can't find any solutions.
PHP
<?php
$img = imagecreatetruecolor(1000, 1000);
imagesavealpha($img, true);
imagealphablending($img, true);
$color = imagecolorallocatealpha($img, 255, 255, 255, 127);
$red = imagecolorallocate($img, 255, 0, 0);
imagefill($img, 0, 0, $color);
imageantialias($img, true);
imageline($img, 10, 10, 500, 20, $red);
header("content-type: image/png");
imagepng($img);
imagedestroy($img);
?>
HTML
<style type="text/css">
body{
background:url('/Image/background.png');
}
</style>
<img src="./example.php" />
The PHP manual basically states that you cannot:
It does not support alpha components. It works using a direct blend
operation. It works only with truecolor images.
Thickness and styled are not supported.
Using antialiased primitives with transparent background color can end
with some unexpected results. The blend method uses the background
color as any other colors. The lack of alpha component support does
not allow an alpha based antialiasing method.
http://es.php.net/imageantialias
So unless someone comes with third-party code or some witty hacks, you're out of luck.

Creating a transparent canvas with GD

I am trying to create a transparent image canvas and then place other random images on top of this canvas. I then finally save the final image as a gif. I have tried the below:
$canvas = imagecreatetruecolor($this->canvas_width, $this->canvas_height);
imagesavealpha($canvas, true);
imagealphablending($canvas, false);
$trans_colour = imagecolorallocatealpha($canvas, 0, 0, 0, 127);
imagefill($canvas, 0, 0, $trans_colour);
However, if there is some unused space left on the canvas then this part is black. I thought this area should be transparent?
Am I applying transparency correctly with the above?
imagesavealpha can not be used for images you eventually intend to save as GIF because GIF images do not have alpha channels. From the docs:
imagesavealpha — Set the flag to save full alpha channel
information (as opposed to single-color transparency) when saving PNG
images
So it only works if you are going to save the image as PNG. GIF images can do transparency, but not with an alpha channel; they can only be "transparent" or "not transparent" by defining a particular color as transparent. In PHP you can do that using imagecolortransparent. For example, to make all black transparent, you could do:
$black_color = imagecolorallocate($canvas, 0, 0, 0);
imagecolortransparent($canvas, $black_color);

Opacity effect using PHP GD extension

I wonder if it is possible to have "opacity" effect when drawing images on top of other images with the PHP GD extension? Are there any built-in functions that can get the results I want or do I have to go for my own implementation using imagesetpixel way?
A pseudo-code to illustrate what I am trying to do right now:
// Background image
$image_bg = imagecreatetruecolor(100, 100);
imagesavealpha($image_bg, true);
// Making background image fully transparent
imagefill($image_bg, 0, 0, imagecolorallocatealpha($image_bg, 0, 0, 0, 127));
// Now the actual image I want to draw with opacity (true color PNG)
$image = imagecreatefrompng(...);
// Drawing with 50 "merge" value
imagecopymerge($image_bg, $image, ..., 50);
The trouble with above code is that imagecopymerge will not respect background image alpha value and will merge the image with the background as if it was opaque black color (the resulting image will not be 50% transparent).
Edit: I ended up implementing my own function using imagecolorat and imagesetpixel way.
Take a look at imagecolortransparent() and imagealphablending() (or this question).

PHP/GD ImageSaveAlpha and ImageAlphaBlending

I'm using GD to resize and convert images, however during my tests I found a weird behavior when converting transparent PNG's to JPEG's. According to the manual ImageAlphaBlending() is on by default but in order to preserve the transparency I must set ImageSaveAlpha() to true (which in turn requires that I set ImageAlphaBlending() to false). So the correct way should be:
$result = ImageCreateFromPNG(...);
ImageAlphaBlending($result, false);
ImageSaveAlpha($result, true);
ImageFill($result, 0, 0, IMG_COLOR_TRANSPARENT);
ImageJPEG($result);
ImageDestroy($result);
However if I do it the "correct" way all the transparency area comes up black in the JPEG. This seems to work (JPEG with white background on transparent areas) on my tests:
$result = ImageCreateFromPNG(...);
ImageAlphaBlending($result, true); // true by default, but still...
ImageSaveAlpha($result, true);
ImageFill($result, 0, 0, IMG_COLOR_TRANSPARENT);
ImageJPEG($result);
ImageDestroy($result);
Can someone please enlighten me on this subject?
It probably depends on your PNG. A PNG file can contain a background color, which can be used when transparency doesn't work. Your PNG probably has a white background. When you set imageaplhablending to true it picks up the background color from your PNG and uses that when writing the JPEG. When you set it to false it picks the default for GD which is black.
You can try it for yourself. Create a transparent PNG and save it with an orange or pink background color. Your second example should show that color.
By the way, the PNG background color trick is a nice one for IE6 images. IE6 does not support transparent PNGs so it will display them with whatever background color you saved them with. When saving transparent PNGs, save them with the same background color as your website. It will look better than white or black boxes around your PNG images in IE6.
If you are converting from PNG (or GIF) to JPG, you should probably copy the final image to another image that is filled with white, using imagecopy ($image is any image already created with GD):
// Create a new background
$bg = imagecreatetruecolor(imagesx($image), imagesy($image));
// Allocate the color
$color = imagecolorallocate($bg, 255, 255, 255);
// Fill the background with white
imagefill($bg, 0, 0, $color);
// Alpha blending must be enabled on the background!
imagealphablending($bg, TRUE);
// Copy the current image onto the opaque background
if (imagecopy($bg, $image, 0, 0, 0, 0, imagesx($image), imagesy($image)))
{
// Replace the image with the background copy
imagedestroy($image);
$image = $bg;
}
Hope that helps.

Categories