JavaScript Canvas实现图片拼接与上传(全面且详细,解决图片跨域问题,已踩坑)

基本原理

计算好位置,把要拼接的图片绘制到画布上,然后再保存,没错就是这么简单。

第一步 加载图片

此处以加载网络图片为例,为了避免回调地狱 (callback hell),而且都到2021年了,还不会用Promise就有点说不过去了,首先封装一个函数,用于加载图片。可能有初学者对于此方式不太理解,建议先学习一下Promise。

function getImg(url) {
  return new Promise((resolve, reject) => {
    let img = new Image();
    img.src = url;
    // 图片跨域访问
    img.setAttribute('crossOrigin', 'anonymous');
    img.onload = () => {
      resolve(img);
    };
    img.onerror = () => {
      reject('image loading failed')
    }
  });
}

大部分情况下,用JavaScript动态加载图片时,会遇到跨域问题,如果对此不太了解可以参考你所需要的跨域问题的全套解决方案都在这里啦!(前后端都有)
在这里插入图片描述

blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

当加载的图片来自于阿里云OSS或其他云服务商的对象存储服务时,还需要去云服务商那里配置跨域,此处以阿里云OSS为例说明:
阿里云配置跨域
具体的操作方法可以参加阿里云的帮助文档,有个小细节提醒一下,设置好跨域后,要清空一下浏览器的缓存,不然看不到效果。

第二步 拼接图片

此处用到了 async 与 await 相关的知识,不懂的同学请自行百度。

// 获取图片
  let img1 = await getImg(url1).catch(err=>{
    console.log('图片加载出错')
  });
  let img2 = await getImg(url2).catch(err=>{
    console.log('图片加载出错')
  });
  // 创建画布 拼接图片 此处以横向拼接为例
  let canvas = document.createElement("canvas");
  // 设置画布宽高
  canvas.height = Math.max(img1.height, img2.height);
  canvas.width = img1.width + img2.width;
  // 获取画笔 绘制图片到画布上
  let context = canvas.getContext("2d");
  context.drawImage(img1, 0, 0, img1.width, img1.height);
  context.drawImage(img2, img1.width, 0, img2.width, img2.height);
  // 得到图片的base64编码
  let imgData = canvas.toDataURL();

第三步 上传到服务器

采用post方式,上传至服务器。需要吧base64编码,转化为二进制字节流,再上传。

// base64转二进制
  let bytes = window.atob(imgData.split(",")[1]);
  let arr = [];
  let bytesLength = bytes.length;
  for (let i = 0; i < bytesLength; i += 1) {
    arr.push(bytes.charCodeAt(i));
  }
  let blob = new Blob([new Uint8Array(arr)], {type: "image/jpeg"});
  let formData = new FormData();
  formData.append("file", blob, `mergeImg.jpg`);
  // 上传后端
  let url = `${Constant.apiPath}/file/upload/gymTrainerEducation`;
  // 此处是自己封装的ajax请求函数,用到的时候,换成你们项目中的就行啦,注意参数
  return request(url, {
    method: 'POST',
    body: formData,
  })

🥰如果您觉得写得还不错,记得 点赞 👍 + 关注👀 + 评论💋 三连,鼓励我写出更好的教程💪 谢谢您~(,´•ω•)ノ"(´っω•`。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值