自学内容网 自学内容网

PHP保存base64编码图片,图片有一部分是灰色块儿,原因和解决办法

场景

我有个需求,移动端h5上传多张的图片。用input file可以上传多张,但是现在照片体积越来越大,同时上传多张会因为体积过大,导致上传失败。如果是小程序会好很多,可以直接先压缩在上传,已经提供的功能。h5上没提供,只能自己解决了。

原因

自己用js canvas先压缩图片再上传,这时候上传的就是图片的base64编码。php接受后存储为图片。但是有的图片保存没问题,有的图片一部分成了灰色块。如下图
在这里插入图片描述

经过查找,有的说是因为base64的头部信息,不是这个问题,因为我保存的时候已经去掉了。

再找,发现ajax在传输过程中加号会变成空格而base64里是有加号的,所以在ajax传输前先要对base64进行编码,把加号替换成%2B的url编码。也就是说,ajax在传输过程中修改了图片的base64编码,导致图片解析失败,解析不出来就变成灰色了。

解决方案

先用js对图片的base64编码进行url编码

imgBase64_2=encodeURIComponent(imgBase64);

php接受后先解码,然后再保存为图片

$base64_image_content=$_POST['image'];
$base64_image_content=urldecode($base64_image_content);

完整的代码

前端代码

前端代码没有做提交功能,数据已经存放在隐藏域 image[]里了。用form表单或者ajax提交都可以。这个可以自己实现。


<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport"
        content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
  <title></title>
  <style>

    .upload-file {
      position: relative;
       width: 100px;
      height: 100px;
      order: 9;
      background-color: grey;
    }
    #file {
      width: 100%;
      height: 100%;
      opacity: 0;
    }
    .upload_Picitem{width: 150px;height: 150px;}
    .upload_Picitem img{width: 150px;height: 150px;}
  </style>

</head>
<body>
<section class="upload-section">
  <article class="upload-piclist" id="upload-piclist">
    <div id="image_container"></div>
    <div class="upload-file">
      <input type="file" id="file" accept="image/*" multiple onchange="imgChange()" />
    </div>
  </article>
</section>
<button id='subBtn'>提交</button>
<script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script>
<script>
  function imgChange() {
    let file =document.getElementById('file').files;
    let filelist = file.length  ;
    for (let i = 0; i < filelist; i++) {
      readerfile(file[i]).then(e => {
        // 对生成的base64照片进行压缩
        //  第一个参数就是需要压缩的base64
        // 第二个是压缩系数 0-1,
        // 第三个压缩后的回调 用来获取压缩处理后的 base64
        compressImg(e,buildImgDiv);
      })
    }
  }

  function compressImg (base64,callback) {
    // 第一个参数就是需要加密的base64,
    // 第二个是压缩系数 0-1,
    // 第三个压缩后的回调 用来获取处理后的 base64
    if (!base64) {
      return
    }
    // 压缩方法
    let newImage = new Image()
    let quality = 0.9    // 压缩系数0-1之间
    newImage.src = base64
    //newImage.setAttribute('crossOrigin', 'Anonymous') // url为外域时需要
    let imgWidth, imgHeight
    let w = undefined
    newImage.onload = function () {
      // 这里面的 this 指向 newImage
      // 通过改变图片宽高来实现压缩
      w = 800
      imgWidth = this.width
      imgHeight = this.height
      let canvas = document.createElement('canvas')
      let ctx = canvas.getContext('2d')
      if (imgWidth > w) {
        canvas.width = w
        // 等比例缩小
        canvas.height = w * (imgHeight / imgWidth)
      } else {
        canvas.width = imgWidth
        canvas.height = imgHeight
      }
      ctx.clearRect(0, 0, canvas.width, canvas.height)
      ctx.drawImage(this, 0, 0, canvas.width, canvas.height) //  // 这里面的 this 指向 newImage
      let smallBase64 = canvas.toDataURL('image/jpeg', quality) // 压缩语句

      callback(smallBase64)
    }
  }
  // 压缩完成后的回调函数,接收压缩后的base64
  function buildImgDiv(imgBase64){
    var it='<div class="upload_Picitem"><img src=' + imgBase64 + ' /><input type="hidden" name="image[]" value="'+imgBase64+'" /><span class="closeClass"></span></div>'
    $('#image_container').append(it)

  }
  function readerfile(file) {
    return new Promise((resolve, reject) => {
      let reader = new FileReader();
      reader.addEventListener("load", function() {
        resolve(reader.result);
      }, false)
      if (file) {
        reader.readAsDataURL(file)
      }
    })
  }
</script>

</body>
</html>

php代码


function saveBase64($base64_image_content){
    $base64_image_content=urldecode($base64_image_content);
    if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)){
        //图片后缀
        $type = $result[2];
        //保存位置--图片名
        $image_name=date('YmdHis').str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT).".".$type;
        $imge_web_url='/Uploads/chuchai/'.$image_name;
        $imge_real_url = ROOT_PATH.$imge_web_url;
        //解码
        $decode=base64_decode(str_replace($result[1], '', $base64_image_content));
        if (file_put_contents($imge_real_url, $decode)){
            $data['code']=200;
            $data['url']=$imge_web_url;
            $data['msg']='保存成功!';
            return $data;
        }else{
            $data['code']=0;
            $data['url']='';
            $data['msg']='图片保存失败!';
            return $data;
        }
    }else{
        $data['code']=2;
        $data['imgageName']='';
        $data['url']='';
        $data['msg']='base64图片格式有误!';
        return $data;
    }
}

原文地址:https://blog.csdn.net/Clarkbrave/article/details/144306643

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!