【寻求答案】根据图片颜色设定背景

93 阅读1分钟

待解决的问题

企业微信截图_1666948811115.png

企业微信截图_16669500225854.png

如上图所示,横幅是由绿色框中的图片放大后作为背景图的。这里的background-size和background-position该如何获取呢?目前还没有答案,有知道的小伙伴吗?

研究过程中的一些收获

ColorThief

lokeshdhakar.com/projects/co…

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

github.com/benhowdle89…

下面代码是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;
    }