将BASE64编码图像打印到FPDF文档中

时间:2013-08-28 09:51:49

标签: php base64 fpdf

我在数据库中存储了一些base64存储的图像。是否可以使用FPDF直接在PDF文档中打印这些数据?

图像的数据结构

data:image/png;base64,iVBORw0KGgoAAAANSUhEUg7AAAfQAAACWCAYAAAAonXpvAAAfgUlEQVR4Ae2dC9BuVVnHuSN3QaBENA9h5A2IcJxMj8hUkymoQDfClIkmrQZr1EydMqapnKRMc8JmHLBBHadJJaV0lKQDZCmCQiqQ2KERUFARDhcFDpx /33W tznPe/ 3ttaa9/ a2Z9/32Xvt5nvVbl2evtdfee9dtS27bt4mACJmACJm8ACJtBvArv123xbbwImYAImYAImIAJ26K4HJmACJmACJjAAAnboAyhEZ8EETMAETMAE7NBdB0zABEzABExgAATs0AdQiM6CCZiACZiACdihuw6YgAmYgAmYwAAI2KEPoBCdBRMwARMwAROwQ3cdMAETMAETMIEBELBDH0AhOgsmYAImYAImYIfuOmACJm

我认为$pdf->imagepng()应该是FPDF中的正确功能。

7 个答案:

答案 0 :(得分:20)

虽然评论提出了TCPDF解决方案,但我确实想说明有一种方法可以完全用FPDF完成。思考过程是这样的:

  1. 使用explode
  2. 从URI中删除data:image/png;base64,
  3. 使用base64_decode
  4. 解码URI
  5. 使用file_put_contents
  6. 将解码数据保存到PNG文件
  7. 生成PDF并使用Image
  8. 添加PNG文件
  9. 使用unlink
  10. 删除PNG文件

    始终记住错误检查。如果图像无法保存到服务器,您显然不想继续执行。确保始终严格检查函数是否返回false!

    这是我的解决方案。在这个例子中,我使用了一个小图片作为一个小URI。

    const TEMPIMGLOC = 'tempimg.png';
    
    $dataURI    = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAMAAADarb8dAAAABlBMVEUAAADtHCTeKUOwAAAAF0lEQVR4AWOgAWBE4zISkMbDZQRyaQkABl4ADHmgWUYAAAAASUVORK5CYII=";
    $dataPieces = explode(',',$dataURI);
    $encodedImg = $dataPieces[1];
    $decodedImg = base64_decode($encodedImg);
    
    //  Check if image was properly decoded
    if( $decodedImg!==false )
    {
        //  Save image to a temporary location
        if( file_put_contents(TEMPIMGLOC,$decodedImg)!==false )
        {
            //  Open new PDF document and print image
            $pdf = new FPDF();
            $pdf->AddPage();
            $pdf->Image(TEMPIMGLOC);
            $pdf->Output();
    
            //  Delete image from server
            unlink(TEMPIMGLOC);
        }
    }
    

答案 1 :(得分:3)

我知道这是一个古老的话题,但有一种更简单的方法可以解决这个问题。试试这个简单的步骤:

  1. 使用 explode
  2. 从URI中删除数据:image / png; base64
  3. Concatenate data://text/plain;base64,,其中包含已删除的URI
  4. 使用结果字符串(base64)作为FPDF Image()
  5. 的参数

    示例:

    $dataURI= "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAMAAADarb8dAAAABlBMVEUAAADtHCTeKUOwAAAAF0lEQVR4AWOgAWBE4zISkMbDZQRyaQkABl4ADHmgWUYAAAAASUVORK5CYII=";
    
    $img = explode(',',$logo,2);
    $pic = 'data://text/plain;base64,'. $img;
    
    $pdf = new FPDF();
    $pdf->AddPage();
    $pdf->Image($pic, 10,30,0,0,'png');
    $pdf->Output();
    

    请记住在Image()功能上选择正确的图像类型。

答案 2 :(得分:3)

为了确保图像与FPDF一起使用并避免错误,这里是@ pedro-soares'的修改版本。代码:

function getImage($dataURI){
  $img = explode(',',$dataURI,2);
  $pic = 'data://text/plain;base64,'.$img[1];
  $type = explode("/", explode(':', substr($dataURI, 0, strpos($dataURI, ';')))[1])[1]; // get the image type
  if ($type=="png"||$type=="jpeg"||$type=="gif") return array($pic, $type);
  return false;
}

由于FPDF仅允许这三种文件类型,因此检查它是否有效非常重要。 使用:

$pic = getImage($Base64StringGoesHere);
if ($pic!==false) $pdf->Image($pic[0], 10,30,0,0, $pic[1]);

答案 3 :(得分:1)

为了向Mari M回答添加更多内容,我只添加了几行来处理任何类型的图像。 (至于我FPDF抱怨图像是jpeg并且我尝试加载tempimg.png)

$this->tempImgLoc = 'tempimg';    // Here I just remove the file extension
$dataPieces = explode(',',$dataURI);
$encodedImg = $dataPieces[1];
$decodedImg = base64_decode($encodedImg);

// extract the image type from data:image/png;base64
$extension = explode('/', $dataPieces[0]);
$extension = explode(';', $extension[1]);

$this->tempImgLoc .= '.' . $extension[0];

我确信有更好的方法可以用正则表达式做到这一点,但老实说,正则表达式不是我的一杯茶......

答案 4 :(得分:1)

好吧,我在这个问题上浪费了半天时间进行测试。我必须告诉这个解决方案是直接从数据库行打印图像,而不将其存储在临时文件中。

我要写一些要考虑的问题:

  • 我在数据库上使用blob类型存储人工签名,以便在pdf文档上打印
  • 我要通过邮寄方法将签名从画布节点发送到db。
  • 当我从db blob打印字符串时,它没有加号“ +”,这使我无法正确打印签名。为了解决这个问题,我做了一个“ str_replace”来删除空格并插入加号。

然后您唯一要做的是:

$pdf->Image(str_replace(' ','+',$dbRow['blobImage']),160,150,20,10,'png');

如果像我一样需要从数据库中打印几张图像,则必须查看它们是否来,因为如果图像为空,则会出现错误。

我只是将其添加到最后的代码中:

if( $dbRow['blobImage'] ){
                 $pdf->Image(str_replace(' ','+',$dbRow['blobImage']),160,150,20,10,'png');
            }

注意:

  • 160->图片的X位置
  • 150->图片的Y位置
  • 20->图片的X比例尺
  • 10->图像的Y比例
  • 'png'->我的Base64图像类型的基本格式。

答案 5 :(得分:1)

具有imagecreatefromstring()的新解决方案 2019年夏季

  • 删除临时.png(如果存在)
  • 创建临时的.png文件
  • 使用$ pdf->图片(fpdf)

我的Api向我返回了一个数据矩阵1234作为字节数组。以下代码向您展示了如何将字节数组用作Fpdf中的Png。

我$响应= “iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs + 9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABJSURBVChTjYwBCgAgCAP9 / 6dNreVUgg7Gps3EUOfD5Q4Au6YdAGcH8ygyVKrFnhmbc9FL7qRxWRxEkXWW4Q691UsGpZPzt7dEFyY47RMW + x2LAAAAAElFTkSuQmCC”

$filename = '/lk_Reptool/printing/tmp/tmppng.png';

if (file_exists($filename)) {
    unlink($filename);
}
$response = file_get_contents('https://myapi.com/TwoDCode/GetDatamatrixAsPngByteArray?datamatrixText=' . $RepID . '&pixelSize=100');
$response = base64_decode($response);
$img = imagecreatefromstring($response);
imagepng($img, $filename);

pdf代码

$pdf = new PDF('P', 'mm', 'A4');
$pdf->AddPage();
$pdf->Image('/lk_Reptool/printing/tmp/tmppng.png', 180, 20, 10, 10);

答案 6 :(得分:0)

只需使用以下功能扩展Fpdf(在1.8.1上进行测试):

protected function _parsepngdata($data) {
    $f = tmpfile();
    fwrite($f, base64_decode(substr($data, strpos($data,",")+1)));
    fseek($f, 0);
    $info = $this->_parsepngstream($f,"pngdata");
    fclose($f);
    return $info;
}

并以这种方式使用它:(提供base64数据而不是文件名,并将类型设置为“ pngdata”而不是“ png”)

$pdf->Image("data:image/png;base64,iVBORw0KGgo...", $x, $y, $w, $h, "pngdata");

它将创建一个临时文件,向/从中写入/读取数据,然后再将其删除。