待解决的问题
如上图所示,横幅是由绿色框中的图片放大后作为背景图的。这里的background-size和background-position该如何获取呢?目前还没有答案,有知道的小伙伴吗?
研究过程中的一些收获
ColorThief
const getImgColor = () => {
const colorThief = new ColorThief();
const image = new Image();
image.src = 'https://fdn2.gsmarena.com/vv/bigpic/motorola-edge30-ultra.jpg';
image.crossOrigin = 'anonymous';
image.onload = () => {
const colors = colorThief.getPalette(image, 5, 40);
const rgbs = getRGBAGradientValues(colors);
console.log(rgbs)
}
const getRGBAGradientValues = (top) => {
return top.map((color, index) => {
return `rgb(${color.slice(0, 3).join(',')})`
})
}
Grade
下面代码是grade插件库里面的一部分实现代码
const getImageData = () => {
const ctx = canvasRef.value.getContext('2d')
const image = new Image();
image.src = imgRef.value.src;
image.crossOrigin = 'anonymous';
image.onload = () => {
let width = image.width;
let height = image.height;
ctx.drawImage(image, 0, 0, width, height);
const imageData = Array.from(ctx.getImageData(0, 0, width, height).data);
console.log(imageData)
const chunked = getChunkedImageData(imageData);
const uniqChunked = getUniqValues(chunked);
console.log(uniqChunked)
let sorted = getSortedValues(uniqChunked);
console.log(sorted)
// const top = getTopValues(uniqChunked);
const lastArr = getBrightness192(sorted);
console.log(lastArr)
const rgbs = getRGBAGradientValues(lastArr);
color.value = rgbs[0];
color2.value = rgbs[rgbs.length - 1];
}
}
const getBrightness192 = (arr) => {
const newArr = [];
arr.forEach(row => {
if(newArr.length > 100) return;
if(row.brightness >= 170){
newArr.push(row);
}
});
return newArr.sort((a, b) => a.brightness - b.brightness).reverse();;
}
const getChunkedImageData = (imageData) => {
const perChunk = 4;
let chunked = imageData.reduce((ar, it, i) => {
const ix = Math.floor(i / perChunk)
if (!ar[ix]) {
ar[ix] = []
}
ar[ix].push(it);
return ar
}, []);
let filtered = chunked.filter(rgba => {
return rgba.slice(0, 2).every(val => val < 250) && rgba.slice(0, 2).every(val => val > 0)
});
return filtered
}
const getUniqValues = (chunked) => {
return chunked.reduce((accum, current) => {
let key = current.join('|');
if (!accum[key]) {
accum[key] = 1;
return accum
}
accum[key] = ++(accum[key]);
return accum
}, {})
}
const getTopValues = (sorted) => {
return [sorted[0], sorted[sorted.length - 1]]
}
const getSortedValues = (uniq) => {
const occurs = Object.keys(uniq).map(key => {
const rgbaKey = key;
let components = key.split('|'),
brightness = ((components[0] * 299) + (components[1] * 587) + (components[2] * 114)) / 1000
return {
rgba: rgbaKey.split('|'),
occurs: uniq[key],
brightness
}
}).sort((a, b) => a.occurs - b.occurs).reverse();
// return occurs.sort((a, b) => a.brightness - b.brightness).reverse();
return occurs;
}