使用FPDF将数据库中的图像转换为PDF

时间:2015-11-10 12:59:00

标签: php pdf fpdf

我有一张从iPad应用程序发送到SQL数据库的图像。我可以使用以下php

检索此图像并在网页中显示
$img = base64_encode($row['photoData']);
echo "<img src=\"data:image/jpg;charset=utf8;base64, $img\"/>";

这显示正常。我现在要做的是使用PDF将此图像放入FPDF文档中,但我正在努力做到这一点。

这:

$img = base64_encode($row['photoData']);
$pdf->Image($img);

发出此错误:

  

FPDF错误:图像文件没有扩展名,也没有指定类型:

所以我尝试了这个(虽然我意识到我将不得不看看如何对图像的大小进行排序):

$pdf->Image($img, 20, 20, 20, 20 'JPG');

给我:

  

FPDF错误:图像文件丢失或不正确:

这样做的正确方法是什么?

或者将图像暂时保存到服务器然后将保存的图像放入PDF文档会更容易吗?

4 个答案:

答案 0 :(得分:4)

如上面的评论所述,可以使用流(“数据网址”)将图像数据移交给fpdf库而无需将物理文件写入磁盘:

<?php
// load the 'fpdf' extension
require('fpdf.php');

// just for demonstration purpose, the OP gets the content from a database instead
$h_img = fopen('img.jpg', "rb");
$img = fread($h_img, filesize('img.jpg'));
fclose($h_img);

// prepare a base64 encoded "data url"
$pic = 'data://text/plain;base64,' . base64_encode($img);
// extract dimensions from image
$info = getimagesize($pic);

// create a simple pdf document to prove this is very well possible: 
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','B',16);
$pdf->Cell(40,10,'Hello Image!');
$pdf->Image($pic, 10, 30, $info[0], $info[1], 'jpg');
$pdf->Output();

如果这是一个好建议是另一个问题,这仅仅是为了证明这是可能的......

答案 1 :(得分:1)

根据Docs FPDF::Image接受文件名作为第一个参数,而不是二进制blob。

如果您想特别使用FPDF,请先将图像保存到临时文件,然后将其传递给FPDF::Image

要做到这一点,这样的事情应该有效:

$tmpFile = tempnam(sys_get_temp_dir(), 'fpdfimg');
if (file_put_contents($tmpFile, $row['photoData'])) {
    $fpdf->Image($tmpFile);
    // save/display image
    unlink($tmpFile);
}

或者,如果您只想将图像作为PDF提供(没有其他内容),可以使用Imagick

$im = new \Imagick();
$im->readImageBlob($row['photoData']);
$im->setImageFormat('pdf');
header('Content-Type: application/pdf');
echo $im;

答案 2 :(得分:0)

由于FPDF无法使用base64数据在PDF上生成图像,我建议永久保存文件到磁盘,而不是为每个PDF操作写一个临时文件。

这将为您节省大量的I / O开销。

假设您的表格与photo_id一致photo_namephotoData,那么您可以使用此类内容来创建图片并在FPDF中使用它们。

我还假设您有一个last_updatephoto_extension列。

<?php

$path = '/path/to/fpdf/images/';

$filename = $row['photo_id'].'.'.$row['photo_extension'];

$filepath = $path.$filename;

// If a physical file is not available then create it
// If the DB data is fresher than the file then make a new file
if(!is_file($filepath) || strtotime($row['last_update']) > filemtime($filepath))
{
    $result = file_put_contents($filepath, $row['photoData']);

    if($result === FALSE)
    {
        die(__FILE__.'<br>Error - Line #'.__LINE__.': Could not create '.$filepath);
    }
}

$pdf->Image($filepath);

如果您计划更新存储在数据库中的photoData,那么您必须确保还有一个时间戳列,并将该时间戳与磁盘上图像的filemtime($filepath)进行比较

答案 3 :(得分:-1)

另一个解决方案;)

通过复制和粘贴(编辑fpdf的代码片段)制作一个新的PHP:

require('fpdf.php');
class DATAIMAGE extends FPDF
{
protected function _parsedata($file)
{
    // Extract info from a JPEG file
    $a = getimagesizefromstring($file);
    if(!$a)
        $this->Error('Missing or incorrect image file: '.$file);
    if($a[2]!=2)
        $this->Error('Not a JPEG file: '.$file);
    if(!isset($a['channels']) || $a['channels']==3)
        $colspace = 'DeviceRGB';
    elseif($a['channels']==4)
        $colspace = 'DeviceCMYK';
    else
        $colspace = 'DeviceGray';
    $bpc = isset($a['bits']) ? $a['bits'] : 8;
    return array('w'=>$a[0], 'h'=>$a[1], 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'DCTDecode', 'data'=>$file);
}
}

然后在主php中调用此php而不是fpdf.php。

您现在只需添加“数据”即可显示图片。到功能结束:

$pdf->Image($mysqlrow["blob"],0,0,40,0,'data');