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
}
Related
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:
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);
...
I'm adding annotation text to a newPseudoImage which works fine but I'd like to make the text scale to fit the image size.
Any ideas how I might do this?
$im = new Imagick();
$draw = new ImagickDraw();
$draw->setFillColor($color);
$draw->setFont($font);
$draw->setFontSize(($width, $height) / 100) * 15);
$draw->setGravity(Imagick::GRAVITY_CENTER);
$im->newPseudoImage($width, $height, "canvas:{$bg}");
$im->annotateImage($draw, 0, 0, 0, $text);
$draw->clear();
$draw->destroy();
$im->setImageFormat('gif');
header("Content-Type: image/gif");
echo $im;
I think you could use the imageftbbox function to help you out.
This will give you the bounding box for a text string, with the given ttf font, size, and angle.
You could create a loop to increase or decrease the font size as long as the text is not fitting the image properly.
<?php
$bbox = imageftbbox(12, 0, 'Arial.ttf', 'This is a test');
$width_of_text = $bbox[2] - $bbox[0];
You could look at the $width_of_text and adjust the font size as long as the font isn't scaled to your liking. Keep in mind, as you increase the font, the width and height will grow.
Depending on what you are trying to scale it to that may help.
I'm facing the same issue and although I've not tried this yet as I'm away from my machine, I'm going to give this a go.
Using the query font metrics function of the class I will be able to get the calculated width of the text and then compare it with the specified width of its container. I'll make adjustments to the font size and repeat until its near enough. You could get it quite accurate this way but bare in mind possible performance issues if you have multiple text items in the image.
On the other hand, if you weren't concerned about styling the text as much you could use caption.
This is a slightly naive solution (I could have used binary search to find the proper font size) , but it works for me.
In my example I want to place text on a box in the image, so I calculate the proper font size with imageftbbox.
$size = $MAX_FONT_SIZE;
while (true){
$bbox = imageftbbox($size, 0, $font, $text );
$width_of_text = $bbox[2] - $bbox[0];
if ($width_of_text > $MAX_TEXT_WIDTH) {
$size -= 1;
}
else {
break;
}
}
$height_of_text = ($bbox[3] - $bbox[1]);
$draw->setFontSize( $size );
$image->annotateImage($draw, $TEXT_WIDTH_CENTER - $width_of_text/2, $TEXT_HEIGHT_CENTER - $height_of_text/2, 0, $text);
I am writing to print text to an image using PHP. However, the function imagettftext() uses the baseline, whereas I need the text vertically centered.
So, I either need a method to print text with y not the distance from top to baseline, but from top to top of bounding box OR I need a method using which I could determine the distance between top of bounding box and baseline.
Apparently, I am confusing you. So, to make it clear: I am aware of the function imagettfbbox(). Using that function I can determine height and width of resulting text box. Its height, however, is utterly useless for vertical alignment when printing with imagettftext(), because the Y parameter is not the distance to the top of the box (or even the bottom, but at least something I could have used having the height) but the distance to the baseline of the text within.
EDIT: Why am I not accepting the latest answer?
See my latest comment below the answer, and use this image as a reference.
I do not know if the answer still interested.However, the imagettfbbox() function give you more information than simply the height and the width of the bounding box. It's designed exactly to return information needed by the imagettftext() to manage the text as you want.
The trick lies in the fact that the coordinates returned from imagettfbbox() are not related to the absolute top left corner, but to the baseline of the font for the particular text. This is the reason because the box is specified in point coordinates, and these are often negative.
In short:
$dims = imagettfbbox($fontsize, 0, $font, $text);
$ascent = abs($dims[7]);
$descent = abs($dims[1]);
$width = abs($dims[0])+abs($dims[2]);
$height = $ascent+$descent;
...
// In the example code, for the vertical centering of the text, consider
// the simple following formula
$y = (($imageHeight/2) - ($height/2)) + $ascent;
This works perfectly for my projects.
Hope this help.
Sorry for english.
Marco.
Not entirely sure what your asking...can you give an example? Perhaps imagettfbbox is what you need?
// get bounding box dims
$dims = imagettfbbox($fontsize, 0, $font, $quote);
// do some math to find out the actual width and height
$width = $dims[4] - $dims[6]; // upper-right x minus upper-left x
$height = $dims[3] - $dims[5]; // lower-right y minus upper-right y
edit: Here is an example of vertically centered text
<?php
$font = 'arial.ttf';
$fontsize = 100;
$imageX = 500;
$imageY = 500;
// text
$text = "FOOBAR";
// create a bounding box for the text
$dims = imagettfbbox($fontsize, 0, $font, $text);
// height of bounding box (your text)
$bbox_height = $dims[3] - $dims[5]; // lower-right y minus upper-right y
// Create image
$image = imagecreatetruecolor($imageX,$imageY);
// background color
$bgcolor = imagecolorallocate($image, 0, 0, 0);
// text color
$fontcolor = imagecolorallocate($image, 255, 255, 255);
// fill in the background with the background color
imagefilledrectangle($image, 0, 0, $imageX, $imageY, $bgcolor);
$x = 0;
$y = (($imageY/2) - ($bbox_height/2)) + $fontsize;
imagettftext($image, $fontsize, 0, $x, $y , $fontcolor, $font, $text);
// tell the browser that the content is an image
header('Content-type: image/png');
// output image to the browser
imagepng($image);
// delete the image resource
imagedestroy($image);
?>
This one is empty image before writing
Here is my code
<?php
function LoadJpeg($imgname)
{
$im = #imagecreatefromjpeg($imgname);
$grey = imagecolorallocate($im, 255, 255, 0);
// The text to draw
$text = 'http://www.stackoverflow.com';
// Replace path by your own font path
$font = 'CONSOLA.TTF';
list($width, $height) = getimagesize($imgname);
// wants to know how to use this width/height dynamically //
imagettftext($im, 20, 45, 200, 450, $grey, $font, $text);
return $im;
}
header('Content-Type: image/jpeg');
$img = LoadJpeg('Blue_hills.jpg');
imagejpeg($img);
imagedestroy($img);
?>
Image after writing text on it
What I want is vertically and horizontally center the text on 45 degree. Please help me on this. Thanks for you all.
Use the imagettfbbox function to retrieve the dimensions the text rendering would require. Then use that information to calculate the x,y coordinate you should target within the destination image for the text to be centered respective to the width/height.
I know very little about PHP (I'm making this up as I go along).
I'd recommend making a new square image, setting it to have a transparent background with imagecolortransparent(). Then write the text to the transparent image.
Next I'd try using imagecopyresized() to copy and scale the text to the new window. Use the minimum of the original's height and width for the destination size. The offset would be something like (max($width, $height)-min($width, $height))/2. Apply the offset to whichever dimension is greater.