отпечатайте BASE64 кодирано изображение в FPDF документ

Имам някои като base64 съхранени изображения в база данни. Възможно ли е да отпечатате тези данни директно в PDF документ, като използвате FPDF?

Структура на данните на изображението

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

Мисля, че $pdf->imagepng() трябва да е правилната функция в FPDF.


person Thomas1703    schedule 28.08.2013    source източник
comment
Аз също имам същия проблем. Намерихте ли отговора?   -  person Ronald Araújo    schedule 11.01.2014
comment
Да, промених на TCPDF библиотека. Можете да добавите знак @ преди своя base64 низ за конвертиране. Вижте: tcpdf.org/examples/example_009.phps   -  person Thomas1703    schedule 16.01.2014


Отговори (7)


Въпреки че коментарите предложиха TCPDF решение, аз исках да заявя, че има начин това да се направи изцяло с FPDF. Мисловният процес е следният:

  1. Отстранете data:image/png;base64, от URI с помощта на explode
  2. Декодирайте URI с base64_decode
  3. Запазете декодираните данни в PNG файл с file_put_contents
  4. Генерирайте PDF и добавете PNG файла с Image
  5. Изтрийте PNG файла с unlink

Винаги помнете да проверявате за грешки. Ако изображението не успее да се запише на сървъра, очевидно не искате да продължите изпълнението. Уверете се, че винаги стриктно проверявате дали функциите връщат 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);
    }
}
person Muhammad Abdul-Rahim    schedule 14.05.2015
comment
Може би един ден някой ще се натъкне на същия проблем и ще го намери за полезен. ^о^ - person Muhammad Abdul-Rahim; 14.05.2015
comment
@MariM Попаднах на това и го намирам за полезно +1. - person The Humble Rat; 22.03.2016

Знам, че това е стара тема, но има по-лесен начин за решаване на този проблем. Просто опитайте тези прости стъпки:

  1. Отстранете data:image/png;base64 от URI с помощта на explode
  2. Свържете data://text/plain;base64, с това, което е останало от оголеният URI адрес
  3. Използвайте резултатния низ (base64) като аргумент на FPDF Image()

Пример:

$dataURI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAMAAADarb8dAAAABlBMVEUAAADtHCTeKUOwAAAAF0lEQVR4AWOgAWBE4zISkMbDZQRyaQkABl4ADHmgWUYAAAAASUVORK5CYII=";

$img = explode(',',$dataURI,2)[1];
$pic = 'data://text/plain;base64,'. $img;

$pdf = new FPDF();
$pdf->AddPage();
$pdf->Image($pic, 10,30,0,0,'png');
$pdf->Output();

Не забравяйте да изберете правилния тип изображение за извикване на метод Image().

person Pedro Soares    schedule 16.06.2017
comment
Това е страхотно. Как разбра това? - person Gregory Bologna; 18.07.2019

За да гарантирате, че изображенията работят с 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]);
person Xavier Ruiz    schedule 22.10.2017

За да добавя малко повече към отговора на 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];

Сигурен съм, че има по-добър начин да направите това с регулярен израз, но честно казано, regexp не е моята чаша чай...

person 195436    schedule 05.05.2016

Добре, изгубих половин ден, правейки тест с този проблем. Трябва да кажа, че това решение е за отпечатване на изображения от db ред, директно, без да се съхраняват във временни файлове.

Ще напиша някои точки, които трябва да имате предвид:

  • Използвам тип blob в DB за съхраняване на човешки подпис за печат на pdf документ
  • Изпращам подписа за съхраняване в db чрез пощенски метод от платнен възел.
  • Когато отпечатам низа от db blob, той идва без знака плюс "+", който не ми позволява да отпечатам правилно подписа. За да реша този проблем, правя "str_replace", за да премахна празните интервали и да вмъкна знака плюс.

Тогава единственото нещо, което трябва да направите е:

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

Ако имате нужда, като мен, да отпечатате няколко изображения от db, трябва да видите дали идват или не, защото ако изображението дойде празно, ще имате грешка.

Просто добавям това към последния код:

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

ЗАБЕЛЕЖКА:

  • 160 -> X позиция на изображението
  • 150 -> Y позиция на изображението
  • 20 -> X мащаб на изображението
  • 10 -> Y Мащаб на изображението
  • 'png' -> Основният формат на моя тип изображение Base64.
person Antonio    schedule 24.04.2019

Ново решение с imagecreatefromstring() Лято 2019

  • изтрийте временен .png, ако съществува
  • създайте временен .png файл
  • използвайте $pdf->Изображение (fpdf)

Моят API ми връща Datamatrix от 1234 като байтов масив. Следният код ви показва как да използвате този байтов масив като Png във Fpdf.

Моят $response = "iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABJSURBVChTjYwBCgAgCAP9/6dNreVUgg7Gps3EUOfD5 Q4Au6YdAGcH8ygyVKrFnhmbc9FL7qRxWRxEkXWW4Q691UsGpZPzt7dEFyY47RMW+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);
person Ivan Rakitin    schedule 23.07.2019

Просто разширете 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");

Той ще създаде временен файл, ще запише/чете данни към/от и ще ги изтрие след това.

person snoarf    schedule 06.10.2020