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

news2024/12/23 14:17:45

文章目录

  • 场景
  • 原因
  • 解决方案
  • 完整的代码
    • 前端代码
    • php代码

场景

我有个需求,移动端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;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2257846.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue图片之放大、缩小、1:1、刷新、左切换、全屏、右切换、左旋咋、右旋转、x轴翻转、y轴翻转

先上效果&#xff0c;代码在下面 <template><!-- 图片列表 --><div class"image-list"><img:src"imageSrc"v-for"(imageSrc, index) in images":key"index"click"openImage(index)"error"handleI…

Oracle EBS FA 如何打开关闭的资产会计期间?

用户“运行折旧”,误勾选为“关闭期间”,还有一部分资产还需要操作报废和调整,希望后台打开关闭的资产会计期 系统环境 RDBMS : 12.1.0.2.0 Oracle Applications : 12.2.9 解决方案 由官方提供SQL脚本代码如下: /*rollback120.sql - for Release 12.X only(based on r…

Hash、HASHTABLE底层原理【Redis对象篇】

&#x1f3c6; 作者简介&#xff1a;席万里 ⚡ 个人网站&#xff1a;https://dahua.bloggo.chat/ ✍️ 一名后端开发小趴菜&#xff0c;同时略懂Vue与React前端技术&#xff0c;也了解一点微信小程序开发。 &#x1f37b; 对计算机充满兴趣&#xff0c;愿意并且希望学习更多的技…

CentOS 二进制安装部署MongoDB 4.0

一、安装MongoDB 1. 下载 MongoDB 二进制文件 前往 MongoDB 官方下载页面(https://www.mongodb.com/try/download/community) 选择对应版本的 tar 包。 wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.28.tgz 2. 解压并移动至目标目录 解压文件&#xff…

Redis篇-5--原理篇4--Lua脚本

1、概述 Redis 支持使用 Lua 脚本来执行复杂的操作&#xff0c;这为 Redis 提供了更强的灵活性和性能优化能力。通过 Lua 脚本&#xff0c;你可以在服务器端执行一系列命令&#xff0c;而不需要多次往返客户端与服务器之间&#xff0c;从而减少了网络延迟并提高了效率。此外&a…

新手上路,学Go还是Python

对于新手来说&#xff0c;Go和Python都是很好的编程语言&#xff0c;它们各有特点&#xff0c;以下是详细的对比来帮助你决定先学哪一个&#xff1a; 一、语法和学习难度 Python 语法简洁易懂&#xff1a;Python以其简洁、优雅的语法而闻名&#xff0c;代码的可读性很高。例如…

OceanBase 社区版 4.0 离线方式升级bp1至bp2 指南(含避坑总结)

注&#xff1a;目前社区版对 4.0 升级 bp1至 bp2也未有完善的文档&#xff0c;本次升级中也是遇到不少坑&#xff0c;写本文也希望对OB感兴趣的可以尝试少些遇坑。 也希望对升级有更好方式建议方式的朋友一起切磋交流&#xff0c;以便再进一步完善升级方案。 第一次做OB的升级&…

python学opencv|读取图像(六)读取图像像素RGB值

【1】引言 前序已经掌握了如何获取灰度图像的像素&#xff0c;文章链接为&#xff1a; python学opencv|读取图像&#xff08;五&#xff09;读取灰度图像像素-CSDN博客 实际上像素就像一个坐标轴&#xff0c;约束了图像的大小。 但实际上我们在学习过程中&#xff0c;对于同…

Linux kill、killall、pkill 命令区别

注&#xff1a;本文为 “Linux kill、killall、pkill” 相关几篇文章合辑。 未整理去重。 kill、killall、pkill、kill -9 区别 区别 进程 ID 唯一&#xff0c;所以 kill 一次只能杀死 1 个进程&#xff0c;其他相同名称的进程仍然存在&#xff0c;而 pkill 和 killall&#…

1139: Coin-row problem

解法&#xff1a; #include <bits/stdc.h> using namespace std; const int N 1e53; int dp[N]; int main() {int n;cin>>n;for (int i1;i<n;i) cin>>dp[i];for (int i2;i<n;i) {dp[i]max(dp[i-1],dp[i-2]dp[i]);}cout<<dp[n]<<endl;retur…

Ubuntu压缩打包解压

ubuntu压缩打包 上图&#xff0c;压缩当前目录svn 为svn.tar.gaz&#xff0c;解压后再当前解压目录生成svn文件 在Ubuntu中&#xff0c;你可以使用tar命令来创建一个压缩包&#xff0c;或者使用zip命令来创建一个.zip压缩文件。以下是两种常见的压缩方法&#xff1a; 下图&am…

Excel 合并工具 将文件复制到目标工作表中与操作日志记录

指定文件夹中读取符合条件的 Excel 文件&#xff0c;将其中的数据按照一定规则复制到目标工作表中&#xff0c;并进行相关的日志记录和工作簿保存操作。 先看下 excel 的结构 合并的结果 log 记录 vba 代码 Sub DeltaCheck()作者和创建时间的注释 定义工作表变量Dim ws As Wor…

Github----提交人不是自己

账号用户名都设置对的,但是提交人不是自己 解决 发现是用户名和账号都夹了"号导致 git config --global user.name "Your Name" git config --global user.email "your.emailexample.com"不用引号 git config --global user.name Your Name git …

ZZCMS2023存在跨站脚本漏洞(CNVD-2024-44822、CVE-2024-44818)

ZZCMS是一款用于搭建招商网站的CMS系统&#xff0c;由PHP语言开发&#xff0c;可快速搭建&#xff1a;医药招商、保健品招商、化妆品招商、农资招商、孕婴童招商、酒类副食类等招商网站。 国家信息安全漏洞共享平台于2024-11-14公布其存在跨站脚本漏洞。 漏洞编号&#xff1a…

[免费]SpringBoot+Vue企业OA自动化办公管理系统【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringBootVue企业OA自动化办公管理系统&#xff0c;分享下哈。 项目视频演示 【免费】SpringBootVue企业OA自动化办公管理系统 Java毕业设计_哔哩哔哩_bilibili 项目介绍 随着信息技术在管理上越来越深入…

【MySQL】表的基本查询(下)

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由 JohnKi 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f4e2;未来很长&#…

目前Java后端就业前景到底怎么样?

很多人都说今年对于IT行业根本没有所谓的“金三银四”“金九银十”。在各大招聘网站或者软件上不管是大厂还是中小公司大多都是挂个招聘需求&#xff0c;实际并不招人&#xff1b;在行业内的程序员基本都已经感受到了任老前段时间口中所谓的“寒气”。 虽然事实确实是如此&…

机器学习--张量

机器学习–张量 机器学习的数据结构–张量 张量是机器学习程序中的数字容器&#xff0c;本质上就是各种不同维度的数组&#xff0c;如下图所示。 张量的维度称为轴&#xff08;axis&#xff09;&#xff0c;轴的个数称为阶&#xff08;rank&#xff09; 标量–0D张量 impor…

3D 视觉定位技术:汽车零部件制造的智能变革引擎

在汽车零部件制造领域&#xff0c;传统工艺正面临着前所未有的挑战。市场对于零部件精度与生产效率近乎苛刻的要求&#xff0c;促使企业寻求突破之道。而 3D 视觉定位技术&#xff0c;为汽车零部件制造开启了精准定位与智能化生产的新纪元。 3D 视觉定位系统的核心技术原理 3…

uni-app之web-view组件 postMessage 通信【跨端开发系列】

&#x1f517; uniapp 跨端开发系列文章&#xff1a;&#x1f380;&#x1f380;&#x1f380; uni-app 组成和跨端原理 【跨端开发系列】 uni-app 各端差异注意事项 【跨端开发系列】uni-app 离线本地存储方案 【跨端开发系列】uni-app UI库、框架、组件选型指南 【跨端开…