图像暗/光检测客户端脚本

时间:2012-12-07 12:11:51

标签: javascript image canvas client-side

是否有人知道是否有可用于使用客户端脚本检测图像(包含html)中的暗度/亮度的脚本?

我基本上希望能够检测背景中使用的图像类型(黑暗/光线),并让CSS / HTML / Jquery / JS根据光线暗淡的变量调整页面(true of false) )。

我知道有服务器端脚本可用但不能用于此特定开发。

提前致谢。

5 个答案:

答案 0 :(得分:46)

此功能会将每种颜色转换为灰度并返回所有像素的平均值,因此最终值将介于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:

http://jsfiddle.net/s7Wx2/

答案 1 :(得分:25)

我的回答重用了@ 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/,非常简单,不要让我的标记吓到你。

答案 2 :(得分:5)

名为Background Check的脚本可以检测图像中的暗度/亮度。它使用JavaScript来实现。

以下是指向它的链接:

http://www.kennethcachia.com/background-check/

我希望这有助于任何想要在其中制作具有此类检测功能的滑块。

答案 3 :(得分:1)

MarvinJ提供方法 averageColor(image)以获取给定图像的平均颜色。使用平均颜色,您可以创建规则来定义图像上标签的颜色。

加载图片

var image = new MarvinImage();
image.load("https://i.imgur.com/oOZmCas.jpg", imageLoaded);

获取平均颜色

var averageColor = Marvin.averageColor(image2); // [R,G,B]

此帖子的片段输出:

enter image description here

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>

答案 4 :(得分:0)

在我的情况下,我正在处理具有透明背景的图像,因此需要对这些像素进行不同的处理。

有关代码,请参见this fiddle。有两个具有透明背景的图像。带有浅色前景的图像以前被认为是带有@mmgp中代码的深色图像,但现在可以正确地解释为浅色图像。

我的答案基于this answer from 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,然后...?