Transparent background with GD in PHP - 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.

Related

resizing image with gd or imagick so that it cover its transparent part

I have an image customizing plugin having stage of 1000x700 where user can upload his/her pic and design it with in stage area.
Now if user doesn't use full staging area and use only some part of stage let say 800x400. My final image will be of 1000x700 with transparent background having user's design in middle of it.
Now question is, I want to stretch user design on full canvas with out white background.
How can I do this using php GD or imagick (not manually)?
$dstImage = imagecreatetruecolor(1000, 700);
$black = imagecolorallocate($dstImage, 0, 0, 0);
// Make the background transparent
imagecolortransparent($dstImage, $black);
$srcImage = imagecreatefrompng('srcImg.png');
imagecopymerge($dstImage, $srcImage, 0, 0, 0, 800, 400, 1000, 700);
imagepng($dstImage, 'outputNewImg.png');

PHP convert to transparent doesn't literally make it transparent

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 )

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.

Image Randomization using GD library

I have been tasked with a problem where i need to pickup one image froma set of 1000 and serve it to the user based on the parameters passed in the get query.
This was simple.
Adiditonally, i have been asked to serve the image in such a way that even if the same file is server everytime, the sha1 hash of the image file should come different.
To achieve this,We could just add random pixels in the image background at random places.
Can somebody tell me how i can acheive this using the GD library
Use Imagesetpixel.
$img = imagecreatefrompng('your_image.png');
$red = imagecolorallocate($img, 255, 0, 0);
imagesetpixel($img, $x, $y, $red);
........
........
On the other hand why would you want to change the sha1 hash of the image on every request?
Edit: Since you want a transparent pixel, you are going to need imagealphablending and something like this:
$img = imagecreatefrompng('your_image.png');
imagealphablending($img, false);
$transparent = imagecolorallocatealpha($img, 255, 255, 255, 127);
imagesetpixel($img, $x, $y, $transparent);
imagesavealpha($img, true);
imagepng($img, 'my_saved_file.png');

Merging multiple transparent PNGs into one

I am framing ads with a curved border.
Here is a sample ad: http://imageshack.us/f/20/4e5f5fe94b327new60seciq.png/
I am trying to replicate what would be done in Photoshop, place one on top of the other. Here is the code I'm using:
// create destination canvas
$dest_img = imagecreatetruecolor(176, 75);
// Make the background transparent
$black = imagecolorallocate($dest_img, 0, 0, 0);
imagecolortransparent($dest_img, $black);
imageAlphaBlending($dest_img, false);
imageSaveAlpha($dest_img, true);
// copy ad into destination
imagecopy($dest_img, $ad_image, 0, 0, 0, 0, 176, 75);
// copy frame onto first half of image
imagecopy($dest_img, $curve_image, 0, 0, 0, 0, 88, 75);
What is happening is that the last copy to take place (the frame) is taking priority and instead of seeing the ad, im getting a transparent block. Here is a blown up image of what GD is doing:
http://imageshack.us/f/684/unled1to.png/
I'm hoping there is a simple solution to get the lower layer to remain visible - if not I think I will have to write a function and go pixel by pixel and compare...
if (bottom_px == trans && top_px == trans) {
dest_px = trans;
}
else {
dest_px = top_px;
}
Set imagealphablending to true. From the manual, emphasis added:
In blending mode, the alpha channel component of the color supplied to all drawing function, such as imagesetpixel() determines how much of the underlying color should be allowed to shine through. As a result, gd automatically blends the existing color at that point with the drawing color, and stores the result in the image. The resulting pixel is opaque. In non-blending mode, the drawing color is copied literally with its alpha channel information, replacing the destination pixel. Blending mode is not available when drawing on palette images.
Also, you are not actually coloring the background transparent. You are just telling that $black is transparent. Instead, use imagefill with imagecolorallocatealpha:
imagefill($dest_img, 0, 0, imagecolorallocatealpha($dest_img, 0, 0, 0, 127));

Categories