PHP: creating a smooth edged circle, image or font? - php

I'm making a PHP image script that will create circles at a given radius.
I used:
<?php
imagefilledellipse ( $image, $cx, $cy, $w, $h, $color );
?>
but hate the rough edges it produces. So I was thinking of making or using a circle font that I will output using:
<?php
imagettftext ( $image, $size, $angle, $x, $y, $color, 'fontfile.ttf', $text );
?>
So that the font will produce a circle that has a smooth edge. My problem is making the "font size" match the "radius size".
Any ideas? Or maybe a PHP class that will produce a smooth edge on a circle would be great!
Thank you.

for quick and dirty anti-aliasing, make the image twice the desired size, then down-sample to the desired size.
$circleSize=90;
$canvasSize=100;
$imageX2 = imagecreatetruecolor($canvasSize*2, $canvasSize*2);
$bg = imagecolorallocate($imageX2, 255, 255, 255);
$col_ellipse = imagecolorallocate($imageX2, 204, 0, 0);
imagefilledellipse($imageX2, $canvasSize, $canvasSize, $circleSize*2, $circleSize*2, $col_ellipse);
$imageOut = imagecreatetruecolor($canvasSize, $canvasSize);
imagecopyresampled($imageOut, $imageX2, 0, 0, 0, 0, $canvasSize, $canvasSize, $canvasSize*2, $canvasSize*2);
header("Content-type: image/png");
imagepng($imageOut);

Clever idea, I like that!
But maybe this PHP class already does the trick: Antialiased filled Arcs/Ellipses for PHP (GD)
In many cases websites need dynamically created images: pie charts, rounded corners, menu buttons, etc. This list is endless. PHP, or more precisely the GD library, provides filled elliptical arcs and ellipses, but they are not antialiased. Therefore I have written a PHP function to render filled antialiased elliptical arcs or filled antialiased ellipses (as well as circles..) with PHP easily. Drawing these filled arcs is now a one-liner.

Cairo does antialiasing well.

Related

PHP GD image merge changing my image to black

I have a very frustrating situation. I am using PHP GD for the first time, and it's been a bit of a rollercoaster relationship. Basically, I am trying to merge 2 images, a square one (with a height/width of x) onto a rectangle (with a width of x and a height of y).
The square needs to be centered vertically. But this isn't the issue - I've managed to position it correctly.
Whats happening is, my rectangle is white. My square has a white background, so when the images are merged, it should just look like my asset on a white rectangluar background.
When I merge the image though, GD is for some reason changing my background white rectangle to black - so you can see the white square in the middle, with black "bars" on top and bottom. Can anyone help?
Code is:
//create copy of original image to correct size
imagecopyresized($dst_image, $src_image, 0,0,0,0,$x_width,$x_height,$orig_img_x_width,$orig_img_x_height);
imagejpeg($dst_image, "resized_copy.jpg", 100);
$img = imagecreatetruecolor(1333, 2000);
$white = imagecolorallocate($img, 255, 255, 255);
imagefill ( $img, 0, 0, $white );
imagefilledrectangle($img,0,0,1333,2000, $white);
imagejpeg($img, "rectangle.jpg", 100);
//merge images
$dest2 = imagecreatefromjpeg("rectangle.jpg");
$src2 = imagecreatefromjpeg('resized_copy.jpg');
imagecopymerge($dest2, $src2, 0, 0, 0, -333.5, $x_width, $x_height, 100);
imagejpeg($dest2, "final_image.jpg", 100);
I've tried using imagecopy instead of imagecopymerge, but I get the same result. I'm sure there is a simple explanation, but I cant seem to find it trawling through the php manual.
I've read your question a few times but I'm not convinced I understand exactly what you are trying to achieve so I've made a few assumptions in producing the below code.
For the sake of simplicity I've created a 'square.jpg' test image file like so:
(Note that I've used small image sizes here so I can show them inline.)
// read in the square test image.
$square = imagecreatefromjpeg('square.jpg');
$square_x = imagesx($square); // 100px
$square_y = imagesy($square); // 100px
// create the rectangular image to merge with.
$rectangle = imagecreatetruecolor(100, 200);
$rectangle_x = imagesx($rectangle); // 100px
$rectangle_y = imagesy($rectangle); // 200px
// note that this isn't white, but rather a lovely shade of blue to better
// show the image on the white SO background!
$white = imagecolorallocate($rectangle, 128, 128, 255);
imagefill($rectangle, 0, 0, $white);
// merge the images.
imagecopymerge(
$rectangle,
$square,
0,
($rectangle_y / 2) - ($square_y / 2), // to vertically centre the square.
0,
0,
$square_x,
$square_y,
75 // Just to show the merge clearly; change back to 100 for your usage.
);
imagejpeg($rectangle, 'final_image.jpg', 100);
imagedestroy($rectangle);
imagedestroy($square);
This gives me the following image in final_image.jpg:

Drawing a curved line between two points in PHP

I want to draw a simple curved line between two points. More specifically, the top left and bottom right corner of an image of arbitrary size.
I tried using imagearc, but apparently that's not what I'm looking for.
To illustrate what I mean:
I can't find any function to help me along, so any help would be appreciated :)
You could use ImageMagick instead of image gd. Image gd has no build-in support for curves.
If you don't have the possibility to use ImageMagick, you could still use imagesetpixel and create your own curve with a simple de casteljau algorithm
I solved it using imagearc after all.
The trick is to set the bottom left corner as the center, -90° start angle, 0° end angle and double the size of the image:
//GET VARS
$width = $_GET['width'];
$height = $_GET['height'];
//CREATE IMGS
$image = imagecreatetruecolor($width, $height);
$color = imagecolorallocate($image, 255, 0, 0);
imagearc( $image,
0, 0, //center point = bottom-left corner
$width*2, $height*2, //size = image size * 2
-90, //top left
0, //bottom right
$color);
//OUTPUT IMAGE
header('Content-Type: image/png');
imagepng($image);
//DESTROY IMAGE
imagedestroy($image);
Looks like this:
http://www.schizosplayground.com/pers/curvedlinetest.php?width=132&height=163
I solved a similar problem by generating a vector with points ($polygon) via any convinient function and then drew a lines inbetween the points:
$numberofpoints=count($polygon)/2-1; // XY coordinates, so points is just half and subtracting the end point
for ($i=0; $i < $numberofpoints;$i++) {
imageline($image, $polygon[2*$i], $polygon[2*$i+1], $polygon[2*$i+2], $polygon[2*$i+3], $Color); // connect two consecutive points with a line
}

PHP: How to make a green area (background) in an image transparent?

I'm new here on Stackoverflow.
I would very much like figure out if it's possible to make a specific color of an image transparent using a PHP script. And if it is, how to go about doing it.
Let's say this is the image of which the background color (green) has to be completely transparent: French Hotdog w/ green background
I've got absolutely no idea what a script like this would look like or even where to begin.
I imagine that you'd propably have to set the unwanted RGB color and then "scan" every single pixel in image to determine which pixels have to be transparent. But other than that I'm clueless.
Seriously hope someone here is able to help me out on this one.
demo : http://so.devilmaycode.it/php-how-to-make-a-green-area-background-in-an-image-transparent
first of all the image should be png cause jpeg don't support transparency then the code is like this:
<?php
$image = 'test.png';
$im = imagecreatefrompng($image);
//if you exactly know the RGB color indexes
//$rgb = imagecolorexact($im, 0, 0, 0);
//or keep the rgb color by position so at top 0 left 0
$rgb = imagecolorat($im, 0, 0);
imagecolortransparent($im, $rgb);
header("Content-type: image/png");
//display the image directly
imagepng($im);
// or save it
// imagepng($im, 'test-to-transparent.png');
imagedestroy($im);
?>
imagecolortransparent() will help you:
...
$yourColor = imagecolorallocate($im, 0, 0, 0);
imagecolortransparent($im, $yourColor);
...

Merging Images using GD with PHP

i'm working on creating one PNG image from two others.
Image A and B have the same dimensions, they are both 200x400px. The final image the same.
I'm using the GD library with PHP.
So my idea was to create a PNG-24 from my original PNG-8, then use color transparency and finally copy the second image into
this new PNG-24. The problem appears in the first step anyway, when going from PNG-24 to PNG-8 with color transparency:
This is to get the original PNG-8 and it's dimensions:
$png8 = imagecreatefrompng($imageUrl);
$size = getimagesize($imageUrl);
Now i create a new PNG and fill it's background with a green color (not present in the images):
$png24 = imagecreatetruecolor($size[0], $size[1]);
$transparentIndex = imagecolorallocate($png24, 0x66, 0xff, 0x66);
imagefill($png24, 0, 0, $transparentIndex);
This is for making the green color transparent:
imagecolortransparent($png24, $transparentIndex);
Then i copy the png8 into the PNG-24:
imagecopy($png24, $png8, 0, 0, 0, 0, $size[0], $size[1]);
So here's the problem: the original PNG-8 looks good, but it has a green border surrounding the shape within the original image. It's difficult to explain really. Seems like some part of the green background is left in the remaining PNG.
What can i do?
thanks in advance
best regards,
Fernando
I had some problems with png transparency before and was able to solve them with this pattern:
// allocate original image to copy stuff to
$img = imagecreatetruecolor(200, 100);
// create second image
$bg = imagecreatefrompng('bg.png');
// copy image onto it using imagecopyresampled
imagecopyresampled($img, $bg, 0, 0, 0, 0, 200, 100, 200, 100);
imagedestroy($bg);
// create third image
// do same routine
$fg = imagecreatefrompng('fg.png');
imagecopyresampled($img, $fg, 50, 50, 0, 0, 50, 50, 50, 50);
imagedestroy($fg);
// output image
imagepng($img);
imagedestroy($img);
I think the only difference between mine and yours is imagecopy() vs. imagecopyresampled(). I seem to remember having problems with that though it was quite a while ago. You can see an example of an image I use this pattern on here: http://www.ipnow.org/images/1/bggrad/bg4/yes/TRANSIST.TTF/8B0000/custombrowserimage.jpg (I allocate a blank image, copy the background image in, copy the overlay with transparency in)

How can I tint transparent PNG files in PHP?

I have a transparent PNG image. The transparent areas need to remain completely transparent, but the other areas need tinting with a particular hue.
What's the best way to do this using GD?
Cheers,
James
The above solution didn't work for me.
You are filling alpha region here with red; that I believe is not the objective. Objective is to tint the rest of the image and leave the alpha unchanged.
(Also, wrong use of function imagecolorallocate, you should use imagecolorallocatealpha.)
I managed to use imagefilter and colorize as follows:
imagefilter($image, IMG_FILTER_COLORIZE, 0, 255, 0, 30);
to apply tinting.
The GD library does support alpha transparency so this should not be a problem. Here's how I'd put it together - you may need to tweak this, but the gist of it should be there.
Red/green/blue are 0-255. Alpha is 0-127 (127 being fully transparent). This code should apply a 50% red tint to the image "original.png" and output as "output.png".
<?php
$red = 255;
$green = 0;
$blue = 0;
$alpha = 63
$src_img = imagecreatefrompng("original.png");
$tint_img = imagecreatetruecolor(imagesx($im_src), imagesy($im_src));
$tintcolor = imagecolorallocate($tint_img, $red, $green, $blue, $alpha);
imagefill($tint_img, 0, 0, $tintcolor);
imagecopymerge($tint_img, $src_img, 0, 0, 0, 0, imagesx($im_src), imagesy($img_src), 100);
imagepng("output.png");
?>

Categories