PHP ImageMagick positioning center aligned text - php

I am using PHP ImageMagick (Imagick) for creating images consisting of multiple images and texts, uploaded and added by visitors of my website. It's actually a kind of canvas where a user can upload their images, position them, optionally add some text and after a click on the button, all the images and texts will be bundled to one image.
Everything works fine, but right now I want to add another feature: text-align: center. I want my user to be abled to add text aligned in the center.
For adding normal (left aligned) text is use this code:
$text_temp = new ImagickDraw();
$text_temp->setGravity(Imagick::GRAVITY_NORTHWEST);
...
$image->annotateImage($text_temp, $new_left, $new_top, $angle, html_entity_decode($item->text));
$new_left, $new_top, $angle are calculated in between and are correct. When I left align the text, this are the results:
Input and output as they should be
But, here comes the problem. I want the text to be centered. So I changed my code to this:
$text_temp = new ImagickDraw();
if($item->textalign == 'center') {
$text_temp->setGravity(Imagick::GRAVITY_NORTHWEST);
$text_temp->setTextAlignment(Imagick::ALIGN_CENTER);
}
...
$image->annotateImage($text_temp, $new_left, $new_top, $angle, html_entity_decode($item->text));
The text is indeed centered, but the position is not correct anymore.
See the input and output results: Strange positions when text is aligned in the center
The reason I use setGravity is because I can position the text from the top left. But right now it looks like it's positioning from the center again and I have no idea what I'm doing wrong.
The $new_left and $new_top variables are positive numbers, multiplied by a positive factor, so there is no way the x- or the y-positions are negative.
Does anyone have an idea?
UPDATE:
#MarkSetchell Thanks for your reply, it putted me in the right direction. I didn't do it exactly like you, but I fixed the problem by adding a wrapper (span) around the user text. I already saved the width and height of images, so it was easy to do the same with texts. With these information I can determine the center of the text, and thus position it from center. This worked for horizontal positioning:
$text_temp->setTextAlignment(Imagick::ALIGN_CENTER);
$new_left = $new_left + ($new_width / 2);
//$new_top = $new_top + ($new_height / 2);
$new_top = $new_top + ($new_fontsize);
But it didn't for vertical positioning. Still don't know why, but I handle it now as if I position from top (not center). Then add one time the font size of the text. I can't explain why this is working, but it works. Can somebody tell me?

Related

imagettftext() always gray even with black defined

A client of mine is trying to place text on a background image using imagettftext(). The code was working previously and suddenly went from displaying black text to displaying gray text. The code is properly set to black and changing it to any other color also has no effect.
$im = imagecreatefrompng("/path/to/background.png");
$text = imagecolorallocate($im, 0, 0, 0);
imagettftext($im, 10, 0,96, 201,$text, "vera", $thiscardnumber);
imagepng($im, "/path/to/new/".$imagefilename.".png");
imagedestroy($im);
Any help would be appreciated as nothing was changed in the code or on the server that I am aware of to suddenly stop this from generating proper black text.
You can see the text generated here:
The black text is part of the background image, the gray text is generated by the code above.
EDIT: From comments below
Ah, OK. If you just recreate a the few lines of code separately, do you still get the grey text? Because I get black text with your code. What about if you try a different font, or a different base image just to eliminate them as the culprit? Have you verified what the value of $text is?
ORIGINAL Answer:
There's something amiss here. Your "x" and "y" coordinates are larger than the background image, so the text you are generating is off of the image canvas.
Is there any chance that your background image just has the grey text in it already, and the text you are generating is happening outside of the image?

FPDF right margin values have no effect

I am using the PHP extension FPDF to create PDF documents. I believe I have the margins set to 1" all the way around with justified text, but when I create a PDF document, download it and open it in Acrobat, I see the left margin is 1" but the right margin is about 1.2". I've gone through fpdf.php looking for the issue and cannot find it.
$oPdf = new myPDF('P', 'mm', 'letter');
$oPdf->Open();
$oPdf->SetMargins(25.4,25.4,25.4,25.4);
//set default font/colors
$oPdf->SetFont('Times', '', 12);
$oPdf->SetTextColor(0,0,0);
$oPdf->SetFillColor(255, 255, 255);
//add the page
$oPdf->AddPage();
$oPdf->AliasNbPages();
If I change the top and left margin values, the document reflects the changes. If I change the bottom or right, there is no change. I've seen how the bottom can be changed wth set auto default page break, answered elsewhere. My question is how can I change the right margin and it actually take effect in my document? I have a feeling that this has to do with the measurement of the text when FPDF calculates whether the justified text will fit on the line. I've checked the width of the line and it outputs 165.1 (which is 6.5 inches x 25.4mm) Completely stumped.
Ok, I feel kind of dumb, but hopefully this will help others. I use the FpdfMulticell (See http://www.interpid.eu/fpdf-multicell) for more control over cells and other parts of displaying the content on the PDF document. This is great and all, except for the redundancies that are created. The components of this function require width and height for the cell to be created. This is where the problem was. For some reason I was passing 160 to it rather than 165.1. 6.5" x 25.4 = 165.1. When I go through the references to create the multiCell function within the class, it fixes my problem.
If you're going to use the multicell, I suggest declaring a variable at the beginning of your page such as $pw (i.e., page width) and then instead of passing a constant value, pass the variable. That way your values are uniform and if you want to change it up, then you only have 1 value to change. Make sure you comment so you know what the purpose of that variable is.
$oMulticell = new FpdfMulticell($oPdf);
$pw = 165.1
//Make sure that the content is long enough to go to another line or you won't
//notice the difference with the justified text
$content = "Write some text here Write some text here Write some text here Write some text here Write some text here Write some text here Write some text here Write some text here ";
$oMulticell->multiCell($pw,10,$content,0,"J",1,0,0,0,0);
This works!

How to anti-alias an image with PHP? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Remove white background from an image and make it transparent
I currently have a code that removes the white background from an image, it looks like this:
function transparent_background($filename, $color)
{
$img = imagecreatefrompng($_SERVER['DOCUMENT_ROOT'].'/'.$filename);
$colors = explode(',', $color);
$remove = imagecolorallocate($img, $colors[0], $colors[1], $colors[2]);
imagecolortransparent($img, $remove);
imagepng($img, $_SERVER['DOCUMENT_ROOT'].'/'.$filename);
}
transparent_background('test.png', '255,255,255');
However, once it exports, the edge is very rough. This is what it looks like (note that this is just part of my image):
http://img211.imageshack.us/img211/97/2125c773e32c432b91e1127.png
I added a black background behind that image to show the edge better. So is there a way that I can add a line to the function or edit the function so the edges are smoother/anti-aliased? Thanks!
There is no easy way to do this. The edge of the original image was anti-aliased to the white background. When you remove the pure white, you're left with a lot of pixels near the edge that are close to white. When you see those pixels against a dark color, they're going to stand out and look "rough". You won't get a smooth edge against a transparent background if it's not in the source image.
The final result of the output is being determined by the initial image quality of the image you are importing. PHP can only anti-alias elements that are drawn on an image.
One solution, a total sledgehammer approach, would be to resample the image up, and then down again. Your results will vary depending on the image in question, and it will almost always be not good.
The best solution for your particular problem is to use better quality imported images in the first place.

php imagick setGravity function doesn't work with compositeImage() function

I'm using php Imagick class for a project
I try to composite an image changing the gravity of the image
What I mean is, I want to composite the target image to middle or to the top center
I use
....
$imageOrg->setGravity(imagick::GRAVITY_CENTER); //I wrote this for an example, position will be set by the visitor
$imageOrg->compositeImage($over, Imagick::COMPOSITE_DEFAULT, 0, 0);
....
But either setGravity() or setImageGravity() functions don't work.
Please help!
$imageOrg->compositeImage($over, Imagick::COMPOSITE_DEFAULT, (((($imageOrg->getImageWidth()) - ($over->getImageWidth())))/2), (((($imageOrg->getImageHeight()) - ($over->getImageHeight())))/2));
Basically what you're doing is setting the left offset of your image to your Container's width, minus your composite image's width, divided by two, this will offset it enough to center horizontally. Then you do the exact same thing for the height, and it's centered vertically.
I had the same type of problem, best I can figure Gravity settings only apply to Drawing contexts, ie: Text, annotations

save image after some data written on that image

Hi all
i am displaying an image in a div and content in another div.using jquery draggable method, i placed the content in that div on the image. Now i want to save that image with content as an image. Is it possible? please answer this as it is important
It's perfectly possible to do this, but it's not trivial and I won't post all the code necessary to do it. Instead, I'll give you some pointers:
You can't save the added text "as is" client-side. That's not possible. You could take a screenshot of it, but that's probably not what you want.
Instead, you need to save the text value and the position and size of where the text is placed relative to the image.
Use relative values, e.g. x = 0.3242, y = 0.5123, width = 0.5123, height = 0.12, where x = 0, y = 0 is the top left corner of the image and x = 1, y = 1 the bottom right corner, width and height similarily representing a fraction of the image size.
POST this information to the server and recreate the same effect by baking the text into the image using, for example, gd.
For finding the right font size to use, futz around with imagettfbbox until you have found the closest equivalent in size to the target coordinates.
Use imagettftext for writing the text into the image.

Categories