Base64(canvas)到blob,blob到php

时间:2018-01-01 10:13:48

标签: javascript php ajax canvas blob

我有问题通过使用AJAX POST请求将base64图像从canvas发送到PHP。在我对谷歌进行一些研究之后,我发现人们建议在php.ini等memory_limit上增加PHP服务器的替代方案。也许是因为base64长度太长而且post方法没有用。

然后,我用第二种方法是使用BLOB。我遵循其他stackoverflow作者的指令是添加函数dataURItoBlob()。看起来像是在工作。但是,问题是,我想如何从PHP中提取blob文件到base64?我尝试了几种方法,但没有显示任何结果。

phpinfo.php的

post_max_size = 999M;
memory_limit = 128M;
upload_max_filesize = 999M;

HTML

<button class="btn btn-secondary btn-done" title="Save Image" type="button" id="saveimg" data="<?php echo $product_id; ?>"><i class="fa fa-shopping-cart"></i></button>

JAVASCRIPT

$(document).delegate('#saveimg','click', function(event) {
   var outputType = '<?php echo $type ?>';
   var product = $(this).attr('data');

   myCanvas.deactivateAll().renderAll();

   var dataURL = myCanvas.toDataURL({
        format: 'jpg',
        quality:1,
        multiplier: canvas_multiply
   });

   var blob = dataURItoBlob(dataURL);
   var fi = new FormData();
   fi.append('imgBase64_0', blob, 'test.jpg');

   $.ajax({
      url: 'index.php?load=product/storeimg&p_id=' + product,
      type: 'post',
      dataType: 'json',
      cache: false,
      contentType: false,
      processData: false,
      data: fi,
      success: function (json){
          // SOME CODE HERE //
      },
   });
});

function dataURItoBlob(dataURI) {
  var byteString = atob(dataURI.split(',')[1]);
  var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
  var ab = new ArrayBuffer(byteString.length);
  var ia = new Uint8Array(ab);

  for (var i = 0; i < byteString.length; i++) {
    ia[i] = byteString.charCodeAt(i);
  }

  var blob = new Blob([ab], {type: mimeString});
  return blob;
}

来自print_r的BLOB数组($ _FILES)

[files] => Array(
   [imgBase64_0] => Array
       (
           [name] => test.jpg
           [type] => image/jpeg
           [tmp_name] => /tmp/phpDpBZ0F
           [error] => 0
           [size] => 667026
        )
 )

PHP

if (isset($_FILES)) {
    foreach ($_FILES as $name => $value) {
         ${$name} = array(
              'name' => $value['name'],
              'type' => $value['type'],
              'tmp_name' => $value['tmp_name'],
              'error' => $value['error'],
              'size' => $value['size']
         );
    }

    if (is_dir($_FILES[$name]['tmp_name']) && is_writable($_FILES[$name]['tmp_name'])) {
        $log = 'Writable and exist.'."\n";
    } else {
        $log = 'Not writable, or does not exist.'."\n";
    }

    if (move_uploaded_file($_FILES[$name]['tmp_name'], DIR_IMAGE)) {
        $txt .= "Successfully move.\n";
    } else {
        $txt .= "Fail to move.\n";
    }
}

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

通过ajax保存canvas生成的图像非常简单,所以希望我能正确理解您的问题。如果不知道画面是如何在代码中生成的,也不知道图像的大小,很难说是否简单地增加PHP中的文件上传限制就可以解决问题,但是如果你查看下面的代码(保存并以简短的方式运行)编辑以保存位置)你应该发现你的解决方案非常简单 - 希望如此!

对于演示,使用的图像如下所示并保存在本地以避免使用url本身导致警告

  

无法执行&#39; toDataURL&#39; on&#39; HTMLCanvasElement&#39;:受污染的画布   可能不会被出口。

enter image description here

<?php
    if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['image'],$_POST['filename'] ) ){

        $image=$_POST['image'];
        $filename=$_POST['filename'];

        /* edit to suit own environment */
        $savepath='c:/temp/fileuploads/1/';

        $target=$savepath . $filename;
        $result=file_put_contents( $target, base64_decode( $image ) );


        header('HTTP/1.1 200 OK',true,200);
        header('Content-Type: text/plain');
        exit( $result ? sprintf( 'File uploaded & saved as %s', $target ) : sprintf( 'Unable to save %s',$filename ) );
    }
?>
<!doctype html>
<html>
    <head>
        <meta charset='utf-8' />
        <title>HTML Canvas Image to PHP</title>
        <script>
        (function(options){
            document.addEventListener('DOMContentLoaded',function(e){
                /*
                    generate a canvas with some sort of image - 
                    in this example a promo picture from the classic 
                    B-Horror film "The Blob"
                */
                var canvas=document.getElementById('canvas');
                var ctx=canvas.getContext('2d');
                var img=new Image();
                    img.src='/images/tmp/TheBlob.jpg';
                    img.onload=function(){
                        canvas.width=img.width;
                        canvas.height=img.height;
                        ctx.drawImage( img, 0, 0, canvas.width, canvas.height );
                    }


                /* 
                    Button click event handler
                    create FormData Object and read the canvas data
                    then send via ajax to a PHP script ( in this case the same page )
                    to process the uploaded image.
                */
                function bindEvents(event){

                    var fd=new FormData();
                        fd.append('action','save');
                        fd.append('image', canvas.toDataURL('image/jpg').replace( /^data:image\/(png|jpg);base64,/, '' ) );
                        fd.append('filename',img.src.split('/').pop() )

                    var ajax=function(url,data,callback){
                        var xhr=new XMLHttpRequest();
                        xhr.onreadystatechange=function(){
                            if( this.readyState==4 && this.status==200 )callback.call( this, this.response );
                        };
                        xhr.open( 'POST', url, true );
                        xhr.send( data );
                    };

                    var callback=function(r){
                        alert(r)
                    }

                    ajax.call( this, location.href, fd, callback );
                }


                document.getElementById('bttn').addEventListener( 'click', bindEvents, options );

            }, options );
        })({ passive:true, capture:false, once:false });
        </script>
    </head>
    <body>
        <canvas id='canvas'></canvas>
        <input type='button' id='bttn' value='Upload & Save Image' />
    </body>
</html>