【发布时间】:2021-10-09 16:01:09
【问题描述】:
【问题讨论】:
-
将图像加载到画布中,抓取像素数据,分析 HSL 值?
-
你能给我解释一下吗
-
这是获得图像平均亮度的方法。您的问题可能与此问题重复:stackoverflow.com/questions/51253752/…
标签: javascript html css vue.js
【问题讨论】:
标签: javascript html css vue.js
我将所有像素数据(忽略 alpha=0 颜色)收集到一个直方图中,并抓取了最流行的颜色。然后我反转该颜色并将其设置为图像包装背景。
我必须将 Imgur 图像源 URL 转换为 Base64,以便我可以操作画布数据。这是为了绕过影响ctx.getImageData 的 CORS 政策。抢最流行的颜色可能不是最好的,因为有些颜色只是相差几位。使用平均计算或阈值在直方图中捆绑相似颜色可能会更好。
警告:这是一个幼稚的解决方案,但有一些库,如 Vibrant.js 和 Color Thief,它们经过优化可以从图像中提取色样/调色板信息。
const ctx = document.querySelector('#hidden-canvas').getContext('2d');
const toHex = (...components) =>
`#${components.map(v => v.toString(16).padStart(2, '0')).join('')}`;
const invertHex = (hex) => {
if (hex.startsWith('#')) hex = hex.slice(1);
const
r = (255 - parseInt(hex.slice(0, 2), 16)).toString(16),
g = (255 - parseInt(hex.slice(2, 4), 16)).toString(16),
b = (255 - parseInt(hex.slice(4, 6), 16)).toString(16);
return toHex(r, g, b);
}
const extractPixels = (img, ignoreAlpha = true) => {
ctx.canvas.width = img.width;
ctx.canvas.height = img.height;
ctx.clearRect(0, 0, img.width, img.height);
ctx.drawImage(img, 0, 0);
const data = ctx.getImageData(0, 0, img.width, img.height).data, pixels = [];
for (let i = 0, n = data.length; i < n; i += 4) {
if (!ignoreAlpha || (ignoreAlpha && data[i+3] !== 0)) {
pixels.push(toHex(data[i], data[i+1], data[i+2], data[i+3]));
}
}
return pixels;
};
const pixelsToHistogram = (pixels) => {
return Object
.entries(pixels.reduce((acc, pixel) =>
({ ...acc, [pixel]: (acc[pixel] || 0) + 1 }), {}))
.map(([hex, count]) => ({ hex, count }))
.sort(({ hex: ha, count: ca }, { hex: hb, count: cb }) =>
(cb - ca) || (ha - hb));
};
const processImage = (wrapper) => {
const img = wrapper.querySelector('img');
img.addEventListener('load', function() {
const histogram = pixelsToHistogram(extractPixels(this, true));
const [{ hex }] = histogram;
Object.assign(wrapper.style, {
backgroundColor: invertHex(hex),
width: `${this.width}px`,
height: `${this.height}px`
});
});
};
document.querySelectorAll('.dynamic-image-background')
.forEach(processImage);
body {
background: #222;
}
.dynamic-image-background {
padding: 1em;
}
#hidden-canvas {
display: none;
}
<script src="https://cdn.rawgit.com/jariz/vibrant.js/master/dist/Vibrant.js"></script>
<div class="dynamic-image-background">
<img src="data:image/png;base64,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" />
</div>
<div class="dynamic-image-background">
<img src="data:image/png;base64,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" />
</div>
<canvas id="hidden-canvas"></canvas>
【讨论】: