最近公司項目在用uni-app做小程序商城,其中商品和個人需要生成圖片海報,經過摸索記錄后將一些重點記錄下來。這里有兩種方式來生成
1、后台控制生成
2、前端用canvas合成圖片
這里我們只講使用canvas合成圖片的方法,canvas包括繪制文字、圖片、圖形以及圖片顯示處理。
一、初始化canvas畫布
通過createCanvasContext方法來創建畫布
var _this = this;
_this.ctx = uni.createCanvasContext('canvasid', this);
const C_W = 650; //canvas寬度,使用的手機屏幕
_this.canvasW = C_W; //
_this.canvasH = 420; // 設置畫布高度
_this.ctx.setFillStyle('#545a7a'); //canvas背景顏色
_this.ctx.fillRect(0, 0, _this.canvasW, _this.canvasH); //canvas畫布大小
二、畫布繪制文字
畫布繪制完成后就需要我們把海報需要的元素繪制到畫布上,第一步:添加店鋪名稱,ShopName為定義的店鋪名稱或者說推廣人名稱,店鋪名稱,店鋪名稱顯示使用文字處理:
文字排列方式包含:
1、textAlign = 'start'
2、textAlign = 'end'
3、textAlign = 'left'
4、textAlign = 'right'
5、textAlign = 'center'
在通過setFillStyle設置文字顏色,setFontSize設置字體大小
let _strlineW = 0; //文本寬度
let _strHeight = C_P * 2 + 10; //繪制字體距離canvas頂部的初始高度
if (_this.ShopName != '') {
//店鋪名
_this.ctx.textAlign = 'center';
_this.ctx.setFillStyle(_this.TitleColor);
_this.ctx.setFontSize(uni.upx2px(40));
_this.ctx.fillText(_this.ShopName, _this.canvasW / 2, _strHeight);
_strlineW += _this.ctx.measureText(_this.ShopName).width + uni.upx2px(10);
}
超長文字換行處理
//設置文本 _this.ctx.setFontSize(uni.upx2px(28)); //設置標題字體大小 _this.ctx.setFillStyle(_this.TitleColor); //設置標題文本顏色 let _strLastIndex = 0; //每次開始截取的字符串的索引 let _strHeight = r[1] + C_P * 2 + 10; //繪制字體距離canvas頂部的初始高度 let _num=1; for (let i = 0; i < _this.Title.length; i++) { _strlineW += _this.ctx.measureText(_this.Title[i]).width; if (_strlineW > r[0]) { if(_num == 2&&_this.LineType){ //文字換行數量大於二進行省略號處理 _this.ctx.fillText(_this.Title.substring(_strLastIndex, i-8)+'...', C_P, _strHeight); _strlineW = 0; _strLastIndex = i; _num++; break; }else{ _this.ctx.fillText(_this.Title.substring(_strLastIndex, i), C_P, _strHeight); _strlineW = 0; _strHeight += 20; _strLastIndex = i; _num++; } }else if (i == _this.Title.length - 1) { _this.ctx.fillText(_this.Title.substring(_strLastIndex, i + 1), C_P, _strHeight); _strlineW = 0; } } //設置文本 end
三、繪制圖片
微信里面繪制圖片需要先將圖片地址轉為臨時圖片地址使用方法如下:
async getImageInfo({ imgSrc }) {
return new Promise((resolve, errs) => {
uni.getImageInfo({
src: imgSrc,
success: function(image) {
resolve(image);
},
fail(err) {
errs(err);
}
});
});
}
// 調用方法
let _imgInfo = await _this.getImageInfo({ imgSrc: _this.HeadImg }); //頭像圖
// 參數1 圖片地址, 參數2 繪圖x坐標, 參數3 繪圖 y坐標 ,參數4 圖片寬度, 參數5 圖片高度
_this.ctx.drawImage(_imgInfo.path, (C_W - q[1])/2, _strHeight+5, q[1], q[1]);
有時候我們的圖片需要處理下在顯示,比如把頭像做成圓形。
drawCircular(ctx, url, x, y, width, height) {
//畫圓形頭像
var avatarurl_width = width;
var avatarurl_heigth = height;
var avatarurl_x = x;
var avatarurl_y = y;
ctx.save();
ctx.beginPath();
ctx.arc(avatarurl_width / 2 + avatarurl_x, avatarurl_heigth / 2 + avatarurl_y, avatarurl_width / 2, 0, Math.PI * 2, false);
ctx.clip();
ctx.drawImage(url, avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth);
ctx.restore();
}
ctx為畫布對象,url為圖片地址,x為畫布x軸位置,y為畫布y軸位置,width為圖像寬度,height為圖像高度。
四、繪制圓角矩形/線條
fillRoundRect(cxt, x, y, width, height, radius, /*optional*/ fillColor) {
//圓的直徑必然要小於矩形的寬高
if (2 * radius > width || 2 * radius > height) {
return false;
}
cxt.save();
cxt.translate(x, y);
//繪制圓角矩形的各個邊
_this.drawRoundRectPath(cxt, width, height, radius);
cxt.fillStyle = fillColor || '#000'; //若是給定了值就用給定的值否則給予默認值
cxt.fill();
cxt.restore();
},
drawRoundRectPath(cxt, width, height, radius) {
cxt.beginPath(0);
//從右下角順時針繪制,弧度從0到1/2PI
cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2);
//矩形下邊線
cxt.lineTo(radius, height);
//左下角圓弧,弧度從1/2PI到PI
cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);
//矩形左邊線
cxt.lineTo(0, radius);
//左上角圓弧,弧度從PI到3/2PI
cxt.arc(radius, radius, radius, Math.PI, (Math.PI * 3) / 2);
//上邊線
cxt.lineTo(width - radius, 0);
//右上角圓弧
cxt.arc(width - radius, radius, radius, (Math.PI * 3) / 2, Math.PI * 2);
//右邊線
cxt.lineTo(width, height - radius);
cxt.closePath();
}