需求:根据当前网页中的几张图片,在手机上长按,保存图片到相册或者发送给好友。
1. Canvas合成图片
drawCanvas(){
var self = this;
var imgsrcArray = [
require('@/page/agent/agentexpand/img/bg.jpg'),
'data:image/jpeg;base64,'+this.codeUrl
];
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = 750;
canvas.height = 1333;
var imglen = imgsrcArray.length;
var drawimg = (function f(n){
if(n < imglen){
var img = new Image();
img.crossOrigin = 'Anonymous'; //解决跨域问题
img.onload = function(){
//ctx.save();
if(n == 0){
ctx.drawImage(img,0,0,750,1333);
}else{
ctx.drawImage(img,466,574,210,210);
}
f(n+1);
}
img.src = imgsrcArray[n];
}else{
self.downloadUrl = canvas.toDataURL("image/jpeg");
self.downloadUrl = self.downloadUrl.replace("data:image/jpeg;base64,", "");
}
})(0);
}
vue语法调用方式:<img :src="'data:image/jpeg;base64,' + downloadUrl"/>
2. Canvas合成图片
HTML5给我们提供了一个很好的图像处理神器Canvas,想要合成图片,我们首先得将图片按照一定顺序、大小和位置一张张绘制到Canvas画布中去,最后再将整个Canvas导出为图片。
// 图片合成插件
class ImgMerge {
constructor(imgs = [], options){
// 图片数组默认配置项
let defaultImgsItem = { url: '', x: 0, y: 0 };
// 导出图片的格式与压缩程度默认配置项
let defaultOpts = { type: 'image/jpeg', compress: 1 };
try {
imgs.forEach((item,i,arr) => {
arr[i] = Object.assign({},defaultImgsItem,item)
}); }catch (e) { throw '请传入一个正确的对象数组作为参数'; }
this.imgs = imgs; // 图片数组配置项
this.opts = Object.assign({},defaultOpts,options); // 其他配置项
this.imgObjs = []; // 图片对象数组
this.createCanvas(); // 创建画布
return this.outputImg(); // 导出图片
}
// 创建画布
createCanvas(){
let canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
let w = this.imgs[0].width, h = this.imgs[0].height;
if(!w){ throw '第一张图片宽度未设置'; }
if(!h){ throw '第一张图片高度未设置'; }
canvas.width = w;
canvas.height = h;
this.ctx = ctx;
}
// 绘制图片
drawImg(i){
let img = new Image();
img.src = this.imgs[i].url;
this.imgObjs.push(img);
return new Promise((resolve)=>{ img.onload = resolve; });
}
// 导出图片
outputImg(){
let imgArr = [];
// 将单张图片的Promise对象存入数组
this.imgs.forEach((item,i) => { imgArr.push(this.drawImg(i)); });
// 所有图片加载成功后将图片绘制于Canvas中,后将Canvas导出为图片
return Promise.all(imgArr).then(()=>{
this.imgs.forEach((item,i) => {
let drawPara = [this.imgObjs[i], this.imgs[i].x, this.imgs[i].y];
// 此处判断参数中图片是否设置了宽高,若宽高均设置,则绘制已设置的宽高,否则按照图片默认宽高绘制
if(this.imgs[i].width && this.imgs[i].height){
drawPara.push(this.imgs[i].width, this.imgs[i].height);
}
this.ctx.drawImage(...drawPara);
});
// 以base64格式导出图片
return Promise.resolve(this.ctx.canvas.toDataURL(this.opts.type),this.opts.compress);
});
}
}
window.ImgMerge = ImgMerge; // 可用于全局引用
export default ImgMerge; // 可用于模块化引用
使用
import ImgMerge from './imgMerge.js';
window.onload = function () {
let imgMerge = new ImgMerge([
{ url: require('../images/bg.jpg'), width: 640, height: 1169 },
{ url: require('../images/1.jpg'), width: 200, height: 200 }
]);
imgMerge.then(img => {
let mergeImg = new Image();
mergeImg.src = img;
mergeImg.onload = () => {
document.body.appendChild(mergeImg);
};
});
};