有谁知道是否有脚本可用于使用客户端脚本检测图像(包括 HTML)中的暗度/明度?
我基本上希望能够检测背景中使用的图像(暗/亮)的亮度,并让 CSS/HTML/jQuery/JS 根据暗或亮(真或假)的变量调整页面。
我知道有可用的服务器端脚本,但不能用于这个特定的开发项目。
有谁知道是否有脚本可用于使用客户端脚本检测图像(包括 HTML)中的暗度/明度?
我基本上希望能够检测背景中使用的图像(暗/亮)的亮度,并让 CSS/HTML/jQuery/JS 根据暗或亮(真或假)的变量调整页面。
我知道有可用的服务器端脚本,但不能用于这个特定的开发项目。
此函数会将每种颜色转换为灰度并返回所有像素的平均值,因此最终值将介于 0(最暗)和 255(最亮)之间
function getImageLightness(imageSrc,callback) {
var img = document.createElement("img");
img.src = imageSrc;
img.style.display = "none";
document.body.appendChild(img);
var colorSum = 0;
img.onload = function() {
// create canvas
var canvas = document.createElement("canvas");
canvas.width = this.width;
canvas.height = this.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(this,0,0);
var imageData = ctx.getImageData(0,0,canvas.width,canvas.height);
var data = imageData.data;
var r,g,b,avg;
for(var x = 0, len = data.length; x < len; x+=4) {
r = data[x];
g = data[x+1];
b = data[x+2];
avg = Math.floor((r+g+b)/3);
colorSum += avg;
}
var brightness = Math.floor(colorSum / (this.width*this.height));
callback(brightness);
}
}
用法:
getImageLightness("image.jpg",function(brightness){
console.log(brightness);
});
JSFiddle:
我的答案重用了@lostsource 答案中的大部分代码,但它使用不同的方法来尝试区分暗图像和亮图像。
首先我们需要(简要地)分析一下RGB通道总和的平均值的结果是什么。对人来说,意义不大。粉色比绿色更亮吗?即,为什么要 (0, 255, 0) 给出比 (255, 0, 255) 更低的亮度值?另外,中灰 (128, 128, 128) 是否和中绿 (128, 255, 0) 一样明亮?考虑到这一点,我只处理通道的颜色亮度,就像在 HSV 颜色空间中所做的那样。这只是给定 RGB 三元组的最大值。
剩下的就是启发式。让max_rgb = max(RGB_i)
一些点i
。如果max_rgb
低于 128(假设是 8bpp 的图像),那么我们发现一个新的点i
是暗的,否则是亮的。对每个点都这样做i
,我们得到A
亮点和B
暗点。如果(A - B)/(A + B) >= 0
那么我们说图像是光。请注意,如果每个点都是暗的,那么您会得到 -1 的值,相反,如果每个点都是亮的,则您会得到 +1。可以调整之前的公式,以便您可以接受几乎不暗的图像。在代码中,我将变量命名为fuzzy
,但它对fuzzy
图像处理中的领域并不公平。所以,如果 ,我们说图像是轻的(A - B)/(A + B) + fuzzy >= 0
。
代码在http://jsfiddle.net/s7Wx2/328/,它非常简单,不要让我的符号吓到你。
称为背景检查的脚本可以检测图像中的暗度/明度。它使用 JavaScript 来做到这一点。
这是它的链接:
http://www.kennethcachia.com/background-check/
我希望可以帮助任何想要制作带有此类检测的滑块的人。
MarvinJ提供了averageColor(image)方法来获取给定图像的平均颜色。有了平均颜色,您可以创建规则来定义图像上标签的颜色。
加载图像:
var image = new MarvinImage();
image.load("https://i.imgur.com/oOZmCas.jpg", imageLoaded);
获取平均颜色:
var averageColor = Marvin.averageColor(image2); // [R,G,B]
这篇文章的片段的输出:
var canvas = document.getElementById("canvas");
var image1 = new MarvinImage();
image1.load("https://i.imgur.com/oOZmCas.jpg", imageLoaded);
var image2 = new MarvinImage();
image2.load("https://i.imgur.com/1bZlwv9.jpg", imageLoaded);
var loaded=0;
function imageLoaded(){
if(++loaded == 2){
var averageColor;
averageColor = Marvin.averageColor(image1);
setText("LION", averageColor, "text1");
averageColor = Marvin.averageColor(image2);
setText("LION", averageColor, "text2");
}
}
function setText(text, averageColor, id){
if(averageColor[0] <= 80 && averageColor[1] <= 80 && averageColor[2] <= 80){
document.getElementById(id).innerHTML = "<font color='#ffffff'>"+text+"</font>";
}
else if(averageColor[0] >= 150 && averageColor[1] >= 150 && averageColor[2] >= 150){
document.getElementById(id).innerHTML = "<font color='#000000'>"+text+"</font>";
}
}
.divImage{
width:400px;
height:268px;
display:grid;
}
.divText{
font-family:Verdana;
font-size:56px;
font-weight:bold;
margin:auto;
display:table-cell;
}
<script src="https://www.marvinj.org/releases/marvinj-0.8.js"></script>
<div id="result"></div>
<div style="background-image:url(https://i.imgur.com/oOZmCas.jpg);" class="divImage">
<div id="text1", class="divText"></div>
</div>
<div style="background-image:url(https://i.imgur.com/1bZlwv9.jpg);" class="divImage">
<div id="text2", class="divText"></div>
</div>
在我的场景中,我正在处理具有透明背景的图像,因此我需要以不同的方式处理这些像素。
有关代码,请参阅此小提琴。有两个具有透明背景的图像。具有浅色前景的图像以前被认为是带有来自@mmgp 的代码的深色图像,但现在它被正确地解释为浅色。
我的答案基于 mmgp 的这个答案的 jsfiddle。区别在于完全透明的像素不计为亮或暗。此外,暗光比仅考虑像素之一,而不是透明的。
// Ignore transparent pixels
if (data[x+3] === 0) {
continue;
}
// Calculate the dark to light ratio
var dl_diff = ((light - dark) / (light + dark));
希望对 alpha 通道有更多了解的人可以改进它。我觉得只将完全透明(0?)的像素视为透明而不处理其他值(1 到 255)是错误的。可能需要做一些数学运算,例如将 alpha 值除以 255 然后……?