Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Image uploaded causes error in PDF library

I'm using the ckeditor to do the HTML text. When I paste an image in it, the ckeditor do the upload of image. I have used like pdf library the TCPDF and MPDF, I got two distinct errors, one in each library.

mPDF error: IMAGE Error (SOURCE-IMAGE): Error parsing temporary file image object created with GD library to parse PNG image

TCPDF ERROR: [Image] Unable to get the size of the image: (SOURCE-IMAGE)

My code for upload image when paste in 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: the ajax code is part of ckeditor code, the part is here, the image comes like the 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);
        }
  }
 
like image 891
alexandre9865 Avatar asked Jan 29 '17 02:01

alexandre9865


2 Answers

Before sending the data you need to encode some characters of the base64. For example + and = will cause the code to behave differently. Or use hex values intead of base64 encode.

EDIT: Depending on the form. But you can set a button to convert the textarea 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 sending.

In php, revert 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 the value.

like image 180
sadlyblue Avatar answered Oct 21 '22 04:10

sadlyblue


If the image is uploaded to server successfully and pdf library is throwing the error.

The possible reason here could be that the pdf library is unable to read the image file, make sure the path to image file is correct.

As the pdf library converts html to pdf it must be expecting a relative path eg:-

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

I have tested tcpdf library and found the same issue and same error if the library was unable to find the image.

like image 1
mandar Avatar answered Oct 21 '22 04:10

mandar