Experiencing weird top margin when using fpdf Write() - php

I'm trying to write text to a PDF and there seems to be a weird margin on the top of my page.
This is my following code:
require_once('fpdf.php');
require_once('fpdi/fpdi.php');
//Start the FPDI
$pdf = new FPDI('P', 'pt');
//Set the source PDF file
$source_file = $pdf->setSourceFile("template.pdf");
//Import the first page of the file
$tppl = $pdf->importPage(1);
$pdf->AddPage();
//get size of pdf page
$size = $pdf->getTemplateSize($tppl);
$pdf->useTemplate($tppl, null, null, $size['w'], $size['h'], true);
$pdf->SetMargins(0, 0, 0);
$pdf->SetTextColor(0, 0, 0);
When I use a font-size pt 12, and write text I get this:
$pdf->SetFont('Arial', '', 12);
$pdf->SetXY(0, 0);
$pdf->Write(0, "Hi");
When I do $pdf->SetXY(0, 7.5) I get this
The above looks like I can easily add 7.5 points to the Y and be fine.
However, if I changed the font-size, the distance between the top and the text grows a little greater.
$pdf->SetFont('Arial', '', 8);
Could anyone help me figure out how to neutralize this to at least make it so if I set my XY to a number, it will put it on the some location regardless of the font-size? I've tried different pdf's and it works all the same.
EDIT:
I did $pdf->GetY() and I get 28.35

You simply define a line height of zero. Because of this the text is "centered" vertically around 0.
A common line height is:
$pdf->Write($pdf->FontSize * 1.2, "Hi");

I solved this by instead of doing Write() I used Cell().
I think the main issue was not having a solid width and height. All I know is it works perfectly now so anyone encountering the same problems should try this.
$pdf->Cell(WIDTH,HEIGHT,TEXT);
I also did the following, not sure if this helped or not but I have it in my script.
$pdf->SetMargins(0, 0);
$pdf->cMargin = 0;

Related

Why am I getting an "Empty Response" when changing source files in setasign?

I'm using setasign V1 as our servers are yet to be updated past 5.5.9 and am trying to import the first page from 3 different pdf's to create a new pdf. But if I use any more than one file, I get an error.
I am also running this using the Slim framework and have had to add namespaces to each of the setasign files to get them to read in.
It works perfectly with single files, but not when trying to get a page out of multiple files.
In my below code, the loop goes through each file to get the first page and then add some text. This is a function where I pass in an array of "jobs" and also the $savedFile path to save to.
If I put the line "$pdf->setSourceFile($file)" before the loop and define $file as any of the files in the $inputFiles array, it works fine but obviously has just the first page of the first file on each of the 3 pages created. It also works if I make it bring in just the second file or just the third. But if I put this line inside the loop I get an Empty Response error.
I have also tried to unset the parser at the end of each loop but that didn't make any difference.
At the moment, I can't figure out where it's going wrong as no error details are thrown.
$pdf = new FPDI();
$inputFolder = $_SERVER["DOCUMENT_ROOT"] . '/' . $app->config->get('saveLocations.COC') . '/';
$inputFiles = [];
foreach($jobs as $job){
$coc = $app->coc_approval->getCOC($app, $job);
$cocFile = $coc->file;
array_push($inputFiles, $inputFolder . $cocFile);
}
foreach($inputFiles as $file){
$pdf->setSourceFile($file);
$pdf->AddPage();
$tpl = $pdf->importPage(1);
$pdf->useTemplate($tpl, 0, 0, null, null);
// Set font and color
$pdf->SetFont('Helvetica');
$pdf->SetFontSize('10');
$pdf->SetTextColor(0, 0, 0); // RGB
// Add Customer and PO details
$x = 75.5;
$pdf->SetXY($x,67);
$pdf->Cell(0, 15, $customer);
$pdf->SetXY($x, 73);
$pdf->Cell(0, 15, $PO);
//unset($pdf->parsers[$file]);
}
$pdf->Output($savedFile, 'F');
I am expecting the first page of each file listed in the $inputFiles array to be saved in the final output pdf.
Any advice would be very much appreciated thanks!

PHP set the attribute for an image with matrix values

as the topic,I need to set the attribute for an image or create an image with the attribute what I get from a client as the matrix values.
I found a function named imageconvolution,but it doesn't work out.Maybe I used it incorrectly.
here is the code:
<?php
$image = imagecreatefromgif('http://www.php.net/images/php.gif');
$emboss = array(array(0, 0, 100), array(0, 0, 200), array(0, 0, 1));
imageconvolution($image, $emboss, 1, 0);
header('Content-Type: image/png');
imagepng($image, null, null);
?>
the matrix values are used to scale or rotate or move the image.Is these code right?
I hope to find out someone to teach me.
Thanks a lot.
Scaling, rotation and moving are affine transforms. You cannot use convolution for this matrixes.
I think the easiest way to use the php Imagick extension. It has an affineTransformImage function which you can use: http://php.net/manual/en/imagick.affinetransformimage.php

PHP ImagickDraw with outlined text issues

I'm learning and practicing my Imagick skills.
I have issues with outlined text using Imagick stroke. I would like to achieve an effect visible on this image: a popular Internet meme:
Here's the code I have so far:
$draw = new \ImagickDraw();
$outputImage = new \Imagick('meme.jpg');
$draw->setFillColor('#fff');
$draw->setFont('impact.ttf');
$draw->setFontSize(40);
$draw->setGravity(\Imagick::GRAVITY_NORTH);
$draw->setStrokeColor('#000');
$draw->setStrokeWidth(1);
$draw->setStrokeAntialias(true);
$draw->setTextAntialias(true);
$outputImage->annotateImage($draw, 0, 5, 0, 'Sample text');
$outputImage->setFormat('png');
$outputImage->writeimage('tmp/meme.png');
The issue: text stroke does not look nice. I've found a tip on Imagick discussion board about annotating image second time, but without stroke. Does not work.
Before writing image:
$draw->setStrokeColor('transparent');
$outputImage->annotateImage($draw, 0, 5, 0, 'Sample text');
Can anybody give me a clue?
Update
To conclude, my generated image looks as following:
As you can see, I have some issues with 2px stroke while using different font size. On big fonts, it looks nice but with smaller font there are some issues with the stroke and font.
Version1: resizing
Version 2: composite over and resizing
Version 2 gives a much better result. See code below. Depending on the final size, you need to play around with font and stroke size, as the resizing may give unwanted effects. You may also try version 2 without resizing.
Version 1: resizing
$draw = new ImagickDraw();
$draw->setFillColor('#fff');
$draw->setFont('impact.ttf');
$draw->setFontSize(100); //use a large font-size
$draw->setStrokeColor('#000');
$draw->setStrokeWidth(4);
$draw->setStrokeAntialias(true); //try with and without
$draw->setTextAntialias(true); //try with and without
$outputImage = new Imagick();
$outputImage->newImage(1400,400, "transparent"); //transparent canvas
$outputImage->annotateImage($draw, 20, 100, 0, 'STOP ME FROM MEMEING');
$outputImage->trimImage(0); //Cut off transparent border
$outputImage->resizeImage(300,0, imagick::FILTER_CATROM, 0.9, false); //resize to final size
/*
Now you can compositve over the image
*/
//Clean up
$draw->clear();
$draw->destroy();
$outputImage->clear();
$outputImage->destroy();
Version 2: composite over and resizing
$draw = new ImagickDraw();
$draw->setFont('impact.ttf');
$draw->setFontSize(100); //use a large font-size
$draw->setStrokeAntialias(true); //try with and without
$draw->setTextAntialias(true); //try with and without
//Create text
$draw->setFillColor('#fff');
$textOnly = new Imagick();
$textOnly->newImage(1400,400, "transparent"); /transparent canvas
$textOnly->annotateImage($draw, 21, 101, 0, 'STOP ME FROM MEMEING'); //parameters depend of stroke and text size
//Create stroke
$draw->setFillColor('#000'); //same as stroke color
$draw->setStrokeColor('#000');
$draw->setStrokeWidth(8);
$strokeImage = new Imagick();
$strokeImage->newImage(1400,400, "transparent");
$strokeImage->annotateImage($draw, 20, 100, 0, 'STOP ME FROM MEMEING');
//Composite text over stroke
$strokeImage->compositeImage($textOnly, imagick::COMPOSITE_OVER, 0, 0, Imagick::CHANNEL_ALPHA );
$strokeImage->trimImage(0); //cut transparent border
$strokeImage->resizeImage(300,0, imagick::FILTER_CATROM, 0.9, false); //resize to final size
/*
Now you can compositve over the image
*/
//Clean up
$draw->clear();
$draw->destroy();
$strokeImage->clear();
$strokeImage->destroy();
$textOnly->clear();
$textOnly->destroy();
Can you post your result or be more specific what doesn't look fine to you?
A solution could be to create the text (with stroke) first on a transaprent background and then composite it over the image. You could create the text in bigger font size and resize to make it look smoother on the final image.

PHP Imagick - setTextEncoding() function doesn't work

I'm trying to add some text on a Imagick object.
However I use setTextEncoding() function, it still doesn't work.
.......
$draw = new ImagickDraw();
$draw->setTextEncoding('utf-8');
$draw->setFont($fpath.'/process/ARIAL.TTF');
$draw->setFontSize(80);
$draw->setFillColor("#ffffff");
/*** annotate the text on the image ***/
$imageOrg->annotateImage($draw, 60, 100, 0, "onur küçükkeçe");
........
and as a result I get,
onur küçükkeçe
Any idea why it's not working?
Thanks in advance.
UPDATE
if I set a $text variable to something like chr(252) then I get a proper result
$text=chr(252);
$imageOrg->annotateImage($draw, 60, 100, 0, $text);
as a result I get
ü
UPDATE II
Finally I found what causing this.
The problem occurs because the charset of the document is not defined but if set a charset for the script then imagick doesn't work because the type of the document needs to be set to image/png.
But I don't know how can I fix it.
Ok. I found the solution.
php utf8_decode() function solves the problem
.......
$draw = new ImagickDraw();
$draw->setTextEncoding('utf-8');
$draw->setFont($fpath.'/process/ARIAL.TTF');
$draw->setFontSize(80);
$draw->setFillColor("#ffffff");
/*** annotate the text on the image ***/
$imageOrg->annotateImage($draw, 60, 100, 0, utf8_decode("onur küçükkeçe"));
........

PNG composition using GD and PHP

I am trying to take a rectangular png and add depth using GD by duplicating the background and moving it down 1 pixel and right 1 pixel. I am trying to preserve a transparent background as well.
I am having a bunch of trouble with preserving the transparency.
Any help would be greatly appreciated.
Thanks!
$obj = imagecreatefrompng('rectangle.png');
$depth = 5;
$obj_width = imagesx($obj);
$obj_height = imagesy($obj);
imagesavealpha($obj, true);
for($i=1;$i<=$depth;$i++){
$layer = imagecreatefrompng('rectangle.png');
imagealphablending( $layer, false );
imagesavealpha($layer, true);
$new_obj = imagecreatetruecolor($obj_width+$i,$obj_height+$i);
$new_obj_width = imagesx($new_obj);
$new_obj_height = imagesy($new_obj);
imagealphablending( $new_obj, false );
imagesavealpha($new_obj, true);
$trans_color = imagecolorallocatealpha($new_obj, 0, 0, 0, 127);
imagefill($new_obj, 0, 0, $trans_color);
imagecopyresampled($new_obj, $layer, $i, $i, 0, 0, $obj_width, $obj_height, $obj_width, $obj_height);
//imagesavealpha($new_obj, true);
//imagesavealpha($obj, true);
}
header ("Content-type: image/png");
imagepng($new_obj);
imagedestroy($new_obj);
The solution to virtually any related problem with PHP GD is using this small utility:
http://phpimageworkshop.com/
It´s a PHP Class based on GD... but it´s has two "insignificant" differences:
Extremely easy
Always get the work done
Two days ago I have a similar problem (Join multiple PNG Images into a single one PNG using PHP) but this Library saves the day!

Categories