写在前面
需要做一个海报分享的功能,不过觉得海报预览区域太丑了,想到做一个根据海报主题色变更的背景色功能。
功能实现了,但是性能太差,不过代码删了可惜,留存一下。
最后的方案是用生成的base64图片做背景(当然是高斯模糊了,25px这样)
需求
代码
const bgCtx = uni.createCanvasContext('bgCanvas')
const currenTmplInfo = this.tmplList[this.currentTmplIdx]
const {wrap} = currenTmplInfo
const imgWidth = wrap.width
const imgHeight = wrap.height
bgCtx.setFillStyle('red')
bgCtx.fillRect(0, 0, imgWidth, imgHeight)
bgCtx.drawImage(this.currentImgPath, 0, 0,imgWidth, imgHeight)
console.log({imgWidth,imgHeight})
// console.log(e.detail)
// let imgData = (bgCtx.getImageData(0, 0, e.detail.width, e.detail.height)).data
// //x开始复制的左上角位置的 x 坐标。 y 开始复制的左上角位置的 y 坐标。 width 将要复制的矩形区域的宽度。 height 将要复制的矩形区域的高度。
// // ImageData.data 类型为Uint8ClampedArray的一维数组,每四个数组元素代表了一个像素点的RGBA信息,每个元素数值介于0~255
// var b = '(' + imgData[0] + ',' + imgData[1] + ',' + imgData[2] + ',' + imgData[3] + ')'
// var c = '(' + imgData[4] + ',' + imgData[5] + ',' + imgData[6] + ',' + imgData[7] + ')'
// var d = '(' + 255 + ',' + 255 + ',' + 255 + ',' + 255 + ')'
// this.bgColorStr = `linear-gradient(rgb${b},rgb${c},rgb${d})`;
await new Promise(resolve => {
bgCtx.draw(false, function () {
console.log('draw done bg')
resolve()
})
})
console.log({
x: 0,
y: 0,
canvasId: bgCtx.id,
width: imgWidth,
height: imgHeight,
})
// const tempFilePath = await new Promise((resolve, reject) => {
// uni.canvasToTempFilePath({
// canvasId: 'bgCanvas',
// width: imgWidth,
// height:imgHeight,
// success: function(res) {
// // 在H5平台下,tempFilePath 为 base64
// resolve(res.tempFilePath)
// },
// fail:function (err){
// throw Error(err.errMsg)
// }
// })
// })
//console.log(tempFilePath)
uni.canvasGetImageData({
x: 0,
y: 0,
canvasId: bgCtx.id,
width: imgWidth,
height: imgHeight,
success: (res) => {
console.log(res)
let imgData = res.data;
console.log(imgData)
var r = 1,
g = 1,
b = 1,
a = 1;
const arr = Array.prototype.slice.call(imgData, 0)
for (var i = 0; i < arr.length; i += 4) {
r += arr[i];
g += arr[i+1];
b += arr[i+2];
a += arr[i+3];
}
// 求取平均值
r /= (imgWidth * imgHeight);
g /= (imgWidth * imgHeight);
b /= (imgWidth * imgHeight);
a /= (imgWidth * imgHeight);
// 将最终的值取整
r = Math.round(r);
g = Math.round(g);
b = Math.round(b);
a = Math.round(a);
let obj = {
r,
g,
b,a
}
console.log(obj)
const linearGradientColor1 = `rgba(${r},${g},${b},${a})`
const linearGradientColor2 = `rgba(${r},${g},${b},${a*.2})`
this.bgColorStr = `linear-gradient(${linearGradientColor1},${linearGradientColor2})`;
//x开始复制的左上角位置的 x 坐标。 y 开始复制的左上角位置的 y 坐标。 width 将要复制的矩形区域的宽度。 height 将要复制的矩形区域的高度。
// ImageData.data 类型为Uint8ClampedArray的一维数组,每四个数组元素代表了一个像素点的RGBA信息,每个元素数值介于0~255
// var b = '(' + imgData[0] + ',' + imgData[1] + ',' + imgData[2] + ',' + imgData[3] + ')'
// var c = '(' + imgData[4] + ',' + imgData[5] + ',' + imgData[6] + ',' + imgData[7] + ')'
// var d = '(' + 255 + ',' + 255 + ',' + 255 + ',' + 255 + ')'
// this.bgColorStr = `linear-gradient(rgba${b},rgba${c},rgba${d})`;
},
fail: (fail) => {
console.log(fail)
}
});
可扩展
- 获取前五或者任意个排名靠前的色
- 想办法优化下性能