-
-
Save benshimmin/4088493 to your computer and use it in GitHub Desktop.
<?php | |
/* Caveat: I'm not a PHP programmer, so this may or may | |
* not be the most idiomatic code... | |
* | |
* FPDF is a free PHP library for creating PDFs: | |
* http://www.fpdf.org/ | |
*/ | |
require("fpdf.php"); | |
class PDF extends FPDF { | |
const DPI = 96; | |
const MM_IN_INCH = 25.4; | |
const A4_HEIGHT = 297; | |
const A4_WIDTH = 210; | |
// tweak these values (in pixels) | |
const MAX_WIDTH = 800; | |
const MAX_HEIGHT = 500; | |
function pixelsToMM($val) { | |
return $val * self::MM_IN_INCH / self::DPI; | |
} | |
function resizeToFit($imgFilename) { | |
list($width, $height) = getimagesize($imgFilename); | |
$widthScale = self::MAX_WIDTH / $width; | |
$heightScale = self::MAX_HEIGHT / $height; | |
$scale = min($widthScale, $heightScale); | |
return array( | |
round($this->pixelsToMM($scale * $width)), | |
round($this->pixelsToMM($scale * $height)) | |
); | |
} | |
function centreImage($img) { | |
list($width, $height) = $this->resizeToFit($img); | |
// you will probably want to swap the width/height | |
// around depending on the page's orientation | |
$this->Image( | |
$img, (self::A4_HEIGHT - $width) / 2, | |
(self::A4_WIDTH - $height) / 2, | |
$width, | |
$height | |
); | |
} | |
} | |
// usage: | |
$pdf = new PDF(); | |
$pdf->AddPage("L"); | |
$pdf->centreImage("path/to/my/image.jpg"); | |
$pdf->Output(); | |
?> |
Thx, but this works only in landscape mode for me? In portrait mode the image is set to the right border.
@christophrumpel, for portrait, you probably need to switch width and height around between lines 44 and 47 (untested though!). Sorry, I only needed this for handling landscape pages. :-)
Sweet, this is exactly what I was looking for.
@christophrumpel If you want to change the orientation, change the following constants, I also change the DPI to make the image display as large as possible
const DPI = 64;
const MM_IN_INCH = 25.4;
const A4_WIDTH = 297;
const A4_HEIGHT = 210;
const MAX_HEIGHT = 800;
const MAX_WIDTH = 500;
This is brilliant. I'm having trouble getting text to overlay the top of it though. I don't suppose you have a solution?
...
const DPI = 300;
const MM_IN_INCH = 25.4;
const A4_HEIGHT = 297;
const A4_WIDTH = 210;
// tweak these values (in pixels)
const MAX_WIDTH = 3510;
const MAX_HEIGHT = 2481;
...
...
...
$pdf = new PDF();
$pdf->AddPage("L");
$pdf->centreImage("certificate.jpg");
$pdf->SetFont('Arial','B',300);
$pdf->Text(500, 500, 'Username');
$pdf->Output();
Nice 👍
Thx a lot!
Thanks for this! Lifesaver!
Thank you so so much!
PORTRAIT MODE
const DPI = 150;
const MM_IN_INCH = 25.4;
const A4_HEIGHT = 210;
const A4_WIDTH = 297;
// tweak these values (in pixels)
const MAX_WIDTH = 1150;
const MAX_HEIGHT = 1650;
$pdf->AddPage("P");
A4 @ 300 dpi - 3507x2480 pix
A4 @ 200 dpi - 2338 x 1653 pix
A4 @ 150 dpi - 1753x1240 pix
A4 @ 72 dpi - 841x595 pix
Just saved me the time to figure out the pixel -> mm conversion.
Hi,
I have a pdf and and I am converting that to images(in A4 size) and listing the pages for the user to drag and drop an image on the top of the page. Here I am getting the position x,y of the image in pixels. Using FPDI I am regenerating the existing PDF with the dropped image in the exact position user had dropped on the image in A4 size($pdf = new FPDI('P', 'pt', 'A4');). But in my new PDF the image is not showing in the correct position.
$wPdf = $customPdfClass->getWPt(); //PDF width through FPDF
$hPdf = $customPdfClass->getHPt(); //PDF height through FPDF
$xImage = $positionLeft;//left of the image from jquery
$yImage = $positionTop; // top of the image from jquery
$screenWidth = $screenWidth; //pdf images width from jquery
$screenHeight = $screenHeight; //pdf images height from jquery
$signImage = "uploads/img/".$imageFileName;//dropped image save in my folder
$size = getimagesize($signImage);
$signImageWidth = $size[0]; //Actual width of the image
$signImageHeight = $size[1]; //Actual height of the image
$scalex=$signImageWidth/$screenWidth * ($wPdf);
$scaley=$signImageHeight/$screenHeight * ($hPdf);
$xadj = 0;
$yadj=0;
//Converting pixel values to points and adjusting with the height and width of the PDF
$xImage = ($xImage/$screenWidth);
$yImage = ($yImage/$screenHeight);
$xpt = (($xImage_$wPdf)-$xadj);
$ypt = (($yImage_$hPdf)-$yadj);
// iterate through all pages
for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
// import a page
$templateId = $pdf->importPage($pageNo);
// get the size of the imported page
$size = $pdf->getTemplateSize($templateId);
// create a page (landscape or portrait depending on the imported page size)
if ($size['w'] > $size['h']) {
$pdf->AddPage('L', array($size['w'], $size['h']));
} else {
$pdf->AddPage('P', array($size['w'], $size['h']));
}
// use the imported page
$pdf->useTemplate($templateId);
if($pageNo==$page) {
$pdf->Image('uploads/img/'.$imageFileName,$xpt, $ypt, $scalex, $scaley, "png");
}
}
What should I do to position the image in PDF where the user dropped position? Please give me a solution for this? Thanks.
This is not scale-able in the least bit. Constants for file images?
<?php
require("fpdf.php");
class Pdf extends \FPDF
{
const DPI = 300;
const MM_IN_INCH = 25.4;
const A4_HEIGHT = 297;
const A4_WIDTH = 210;
/**
* Resize et fit une image image
*
* @param string $imgPath
* @param integer $x
* @param integer $y
* @param integer $containerWidth
* @param integer $containerHeight
* @param string $alignment
* @return void
*/
public function imageUniformToFill(string $imgPath, int $x = 0, int $y = 0, int $containerWidth = 210, int $containerHeight = 297, string $alignment = 'C')
{
list($width, $height) = $this->resizeToFit($imgPath, $containerWidth, $containerHeight);
if ($alignment === 'R')
{
$this->Image($imgPath, $x+$containerWidth-$width, $y+($containerHeight-$height)/2, $width, $height);
}
else if ($alignment === 'B')
{
$this->Image($imgPath, $x, $y+$containerHeight-$height, $width, $height);
}
else if ($alignment === 'C')
{
$this->Image($imgPath, $x+($containerWidth-$width)/2, $y+($containerHeight-$height)/2, $width, $height);
}
else
{
$this->Image($imgPath, $x, $y, $width, $height);
}
}
/**
* Convertit des pixels en mm
*
* @param integer $val
* @return integer
*/
protected function pixelsToMm(int $val) : int
{
return (int)(round($val * $this::MM_IN_INCH / $this::DPI));
}
/**
* Convertit des mm en pixels
*
* @param integer $val
* @return integer
*/
protected function mmToPixels(int $val) : int
{
return (int)(round($this::DPI * $val / $this::MM_IN_INCH));
}
/**
* Resize une image
*
* @param string $imgPath
* @param integer $maxWidth en mm
* @param integer $maxHeight en mm
* @return int[]
*/
protected function resizeToFit(string $imgPath, int $maxWidth = 210, int $maxHeight = 297) : array
{
list($width, $height) = getimagesize($imgPath);
$widthScale = $this->mmtopixels($maxWidth) / $width;
$heightScale = $this->mmToPixels($maxHeight) / $height;
$scale = min($widthScale, $heightScale);
return array(
$this->pixelsToMM($scale * $width),
$this->pixelsToMM($scale * $height)
);
}
}
// usage:
$pdf = new Pdf();
$pdf->AddPage();
$pdf->imageUniformToFill($imgPath, $x, $y ,$containerWidth, $containerHeight, $alignment) //$alignment "B", "T", "L", "R", "C"
$pdf->Output();
Merci à https://gist.github.com/benshimmin/4088493
https://gist.github.com/thomasdesmoulin/398886164ffd0566f6fa3b3171bb86f4
Amazing! Thank you so much!
Thank you so much for this!!! I'm finding this kind of solution for weeks now. Really made my day. Thank you
Thank you benshimmin and other contributors, great job !
Thanks a lot! Its works, but just one detail... if the image has a small width, with a long height, the image overflows from the top and bottom of the PDF sheet.
Thankyou thomasdesmoulin its works for me
Thanks this saved my day!