Javascript 图像暗/亮检测客户端脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13762864/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Image Dark/Light Detection Client Sided Script
提问by Redox
Does anyone know if there is a script available to detect darkness/lightness in an image (html included) using a client sided script?
有谁知道是否有脚本可用于使用客户端脚本检测图像(包括 html)中的暗度/明度?
I basically want to be able to detect the type of image (dark/light) used in the background and have CSS/HTML/Jquery/JS adapt the page based on a variable that is either dark of light (true of false).
我基本上希望能够检测背景中使用的图像类型(暗/亮),并让 CSS/HTML/Jquery/JS 根据一个变量调整页面,该变量要么是暗的,要么是亮的(真或假)。
I know there are server sided script available but cannot use that for this particular development.
我知道有可用的服务器端脚本,但不能将其用于此特定开发。
Thanks in advance.
提前致谢。
回答by lostsource
This function will convert each color to gray scale and return average of all pixels, so final value will be between 0 (darkest) and 255 (brightest)
此函数会将每种颜色转换为灰度并返回所有像素的平均值,因此最终值将介于 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);
}
}
Usage:
用法:
getImageLightness("image.jpg",function(brightness){
console.log(brightness);
});
JSFiddle:
JSFiddle:
回答by mmgp
My answer reuses most of the code in @lostsource's answer but it uses a different method to attempt to distinguish between dark and light images.
我的答案重用了@lostsource 答案中的大部分代码,但它使用不同的方法来尝试区分暗图像和亮图像。
First we need to (briefly) analyze what is the result of the average value of the sum of the RGB channels. For humans, it is meaningless. Is pink brighter than green? I.e., why would you want (0, 255, 0) to give a lower brightness value than (255, 0, 255)? Also, is a mid gray (128, 128, 128) bright just like a mid green (128, 255, 0)? To take this into consideration, I only deal with the color brightness of the channel as is done in the HSV color space. This is simply the maximum value of a given RGB triplet.
首先我们需要(简要地)分析一下RGB通道总和的平均值的结果是什么。对人来说,意义不大。粉色比绿色更亮吗?即,为什么要 (0, 255, 0) 给出比 (255, 0, 255) 更低的亮度值?另外,中灰 (128, 128, 128) 是否和中绿 (128, 255, 0) 一样明亮?考虑到这一点,我只处理通道的颜色亮度,就像在 HSV 颜色空间中所做的那样。这只是给定 RGB 三元组的最大值。
The rest is heuristics. Let max_rgb = max(RGB_i)for some point i. If max_rgbis lower than 128 (assuming a 8bpp image), then we found a new point ithat is dark, otherwise it is light. Doing this for every point i, we get Apoints that are light and Bpoints that are dark. If (A - B)/(A + B) >= 0then we say the image is light. Note that if every point is dark, then you get a value of -1, conversely if every point is light you get +1. The previous formula can be tweaked so you can accept images barely dark. In the code I named the variable as fuzzy, but it does no justice to the fuzzyfield in Image Processing. So, we say the image is light if (A - B)/(A + B) + fuzzy >= 0.
剩下的就是启发式。让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。
The code is at http://jsfiddle.net/s7Wx2/328/, it is very straightforward, don't let my notations scare you.
代码在http://jsfiddle.net/s7Wx2/328/,它非常简单,不要让我的符号吓到你。
回答by dan wright
A script called Background Check can detect the darkness/lightness in an image. It uses JavaScript to do so.
称为背景检查的脚本可以检测图像中的暗度/明度。它使用 JavaScript 来做到这一点。
Here is a link to it:
这是它的链接:
http://www.kennethcachia.com/background-check/
http://www.kennethcachia.com/background-check/
I hope that helps anyone wanting to make a slider with this type of detection within it.
我希望可以帮助任何想要制作带有此类检测的滑块的人。
回答by Gabriel Ambrósio Archanjo
MarvinJprovides the method averageColor(image)to get the average color of a given image. Having the average color, you can create rules to define the color of the label over the image.
MarvinJ提供了averageColor(image)方法来获取给定图像的平均颜色。有了平均颜色,您可以创建规则来定义图像上标签的颜色。
Loading an image:
加载图像:
var image = new MarvinImage();
image.load("https://i.imgur.com/oOZmCas.jpg", imageLoaded);
Getting the average color:
获取平均颜色:
var averageColor = Marvin.averageColor(image2); // [R,G,B]
The output of the snippet of this post:
这篇文章的片段的输出:
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>


