The uploaded photo causes an error in the PDF library

I use ckeditor to create HTML text. When I paste the image into it, ckeditor loads the image. I used TCPDF and MPDF as a PDF library, I got two different errors: one in each library.

MPDF error: IMAGE error ( SOURCE-IMAGE ): error while analyzing temporary image object created using the GD library to analyze PNG image

TCPDF ERROR: [Image] Cannot get image size: ( SOURCE SOURCE )

My code for loading the image when pasting into ckeditor is as follows:

<?php session_start(); class image{ private $save_path = 'uploads/'; private $image_string = ''; private $image_name = ''; private $image; private $response = array(); public $loaded = false; public function __construct(){ $this->response = array( 'error' => 1, 'message' => 'unknown error.' ); $this->image_string = filter_input(INPUT_POST, 'image'); $ext = substr($this->image_string,11,3); $randomLetters = $rand = substr(md5(microtime()),rand(0,26),6); $imgnumber = count(scandir($this->save_path)); $this->image_name = "$imgnumber$randomLetters.$ext"; if(!empty($this->image_name) && !empty($this->image_string)){ $this->loaded = true; } } public function save(){ if(!empty($this->image_name) && !empty($this->image_string)){ return $this->progress(); } else{ $this->response['message'] = 'Error. Not all required infor is given.'; $this->response['error'] = 1; return $this->response; } } private function progress(){ $imgarr = explode(',', $this->image_string); if(!isset($imgarr[1])){ $this->response['message'] = 'Error on post data image. String is not the expected string.'; $this->response['error'] = 1; return $this->response; } $this->image = base64_decode($imgarr[1]); if(!is_null($this->image)){ $file = $this->save_path . $this->image_name; if(file_exists($file)){ $this->response['message'] = 'Image already exists on server.'; $this->response['error'] = 1; return $this->response; } if(file_put_contents($file, $this->image) !== false){ $this->response['message'] = 'Image saved to server'; $this->response['error'] = 0; $this->response['source'] = '../plugins/imageuploader/'.$file; return $this->response; } else{ $this->response['error'] = 1; $this->response['message'] = 'Error writing file to disk'; return $this->response; } } else{ $this->response['message'] = 'Error decoding base64 string.'; return $this->response; } } } $img = new image(); if($img->loaded){ $result = $img->save(); echo json_encode($result); } else{ $result = array( 'error' => 1, 'message' => 'Not all post data given' ); echo json_encode($result); } ?> 

What can cause this error?

Edit: ajax code is part of ckeditor code, part is here, the image comes as base64 code:

 function h(a, d) { if (a && "function" === typeof a.getAsFile) { var b = a.getAsFile(), c = new FileReader; c.onload = function (a) { var fd = new FormData(); fd.append('image', a.target.result); //the base64 of image with format equals in src of tag img in html $.ajax({ type: 'POST', url: '../plugins/imageuploader/ajaxupload.php', data: fd, processData: false, contentType: false, dataType: 'json' }).done(function(data) { if((data.error == 0) && (typeof data.source != 'undefined')){ //alert(data.source); var b = d.document.createElement("img", {attributes: {src: data.source}}); setTimeout(function () { d.insertElement(b) }, 10) }else{ alert('Não foi possível carregar a imagem:\nErro - '+data.message); // show the message error if it can't be uploaded. } }); }; c.readAsDataURL(b); } } 
+5
source share
2 answers

If the image was uploaded to the server successfully, and the pdf library throws an error.

The possible reason here is that the PDF library cannot read the image file; make sure that the path to the image file is correct.

Since the PDF library converts html to pdf, it should expect a relative path for example: -

  <img src="http://yourdomain/image_path"> 

I tested the tcpdf library and found the same error and the same error if the library could not find the image.

+1
source

Before sending data you need to encode some base64 characters. For example, + and = will cause the code to behave differently. Or use hexadecimal values ​​for base64 encoding.

EDIT: Depending on the form. But you can set a button to convert a text field using this function:

 function escapeChars(){ var value = document.getElementById("myTextarea").value; value = value.replace("+", "%2b"); value = value.replace("/", "%2f"); value = value.replace("=", "%3d"); document.getElementById("myTextarea").value = value; } 

or if you use ajax, just use the function before submitting.

In php, undo the changes:

 $this->image_string = str_replace(array("%2b", "%2f", "%3d"), array("+", "/", "="), $_POST['image']); 

instead of $this->image_string = filter_input(INPUT_POST, 'image');

EDIT2 In php:

 <?php session_start(); class image{ private $save_path = 'uploads/'; private $image_string = ''; private $image_name = ''; private $image; private $response = array(); public $loaded = false; public function __construct(){ $this->response = array( 'error' => 1, 'message' => 'unknown error.' ); $this->image_string = str_replace(array("%2b", "%2f", "%3d"), array("+", "/", "="), $_POST['image']); $imgarr = explode(',', $this->image_string); if(!isset($imgarr[1])){ return; } $this->image_string = $imgarr[1]; $namearray = explode('.', $imgarr[0]); $ext = end($namearray); if(!in_array($ext, array('jpg','png'))) return false; $randomLetters = $rand = substr(md5(microtime()),rand(0,26),6); $imgnumber = count(scandir($this->save_path)); $this->image_name = "$imgnumber$randomLetters.$ext"; if(!empty($this->image_name) && !empty($this->image_string)){ $this->loaded = true; } } public function save(){ if(!empty($this->image_name) && !empty($this->image_string)){ return $this->progress(); } else{ $this->response['message'] = 'Error. Not all required infor is given.'; $this->response['error'] = 1; return $this->response; } } private function progress(){ $this->image = base64_decode($this->image); if(!is_null($this->image)){ $file = $this->save_path . $this->image_name; if(file_exists($file)){ $this->response['message'] = 'Image already exists on server.'; $this->response['error'] = 1; return $this->response; } if(file_put_contents($file, $this->image) !== false){ $this->response['message'] = 'Image saved to server'; $this->response['error'] = 0; $this->response['source'] = '../plugins/imageuploader/'.$file; return $this->response; } else{ $this->response['error'] = 1; $this->response['message'] = 'Error writing file to disk'; return $this->response; } } else{ $this->response['message'] = 'Error decoding base64 string.'; return $this->response; } } } $img = new image(); if($img->loaded){ $result = $img->save(); echo json_encode($result); } else{ $result = array( 'error' => 1, 'message' => 'Not all post data given' ); echo json_encode($result); } ?> 

in javascript before sending ajax:

 function escapeChars(value){ value = value.replace("+", "%2b"); value = value.replace("/", "%2f"); value = value.replace("=", "%3d"); return value; } 

Then you can use escapeChars in value.

+4
source

Source: https://habr.com/ru/post/1263525/


All Articles