javascript 根据背景图片动态调整文字颜色

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17195738/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 07:26:07  来源:igfitidea点击:

Dynamically adjust text color based on background image

javascriptimagetext

提问by NetOperator Wibby

I am working on a product that outputs images from users and the image information is overlayed on top of the aforementioned images. As you might imagine, the images require different text colors due to lightness/darkness. Is there a way to achieve this with JavaScript?

我正在开发一种从用户输出图像的产品,图像信息叠加在上述图像之上。正如您想象的那样,由于明/暗,图像需要不同的文本颜色。有没有办法用 JavaScript 实现这一点?

EDIT: I found a similar question to mine and there was a solution given in a jsfiddle (http://jsfiddle.net/xLF38/818). I am using jQuery for my site though. How would I convert the vanilla JavaScript to jQuery?

编辑:我发现了一个与我类似的问题,并且在 jsfiddle ( http://jsfiddle.net/xLF38/818) 中给出了一个解决方案。我在我的网站上使用 jQuery。我将如何将 vanilla JavaScript 转换为 jQuery?

var rgb = getAverageRGB(document.getElementById('i'));
document.body.style.backgroundColor = 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')';

function getAverageRGB(imgEl) {

    var blockSize = 5, // only visit every 5 pixels
        defaultRGB = {
            r: 0,
            g: 0,
            b: 0
        }, // for non-supporting envs
        canvas = document.createElement('canvas'),
        context = canvas.getContext && canvas.getContext('2d'),
        data, width, height,
        i = -4,
        length,
        rgb = {
            r: 0,
            g: 0,
            b: 0
        },
        count = 0;

    if (!context) {
        return defaultRGB;
    }

    height = canvas.height = imgEl.naturalHeight || imgEl.offsetHeight || imgEl.height;
    width = canvas.width = imgEl.naturalWidth || imgEl.offsetWidth || imgEl.width;

    context.drawImage(imgEl, 0, 0);

    try {
        data = context.getImageData(0, 0, width, height);
    } catch (e) {
        /* security error, img on diff domain */
        alert('x');
        return defaultRGB;
    }

    length = data.data.length;

    while ((i += blockSize * 4) < length) {
        ++count;
        rgb.r += data.data[i];
        rgb.g += data.data[i + 1];
        rgb.b += data.data[i + 2];
    }

    // ~~ used to floor values
    rgb.r = ~~ (rgb.r / count);
    rgb.g = ~~ (rgb.g / count);
    rgb.b = ~~ (rgb.b / count);

    return rgb;

}

采纳答案by NetOperator Wibby

I finally found something to do precisely what I want it to do! Enter Brian Gonzalez's jquery.adaptive-backgrounds.js. Check this out:

我终于找到了可以做我想要做的事情!输入 Brian Gonzalez 的 jquery.adaptive-backgrounds.js。看一下这个:

$parent.css({
        // backgroundColor: data.color
        color: data.color
});

I just commented out the backgroundColor rule and made a new one for color. For white text, a text-shadow like:

我刚刚注释掉了 backgroundColor 规则并为颜色创建了一个新规则。对于白色文本,文本阴影如下:

text-shadow: 0 0 1px rgba($black, 0.3); // using Sass

should be enough. Thank you to everyone for your answers!

应该够了。感谢大家的回答!

回答by rvighne

This is possible using the canvas element. You would have to create a canvaselement, draw the image element into the canvas, get the canvas's image data, look at the portion where the text is, convert those values to grayscale, average them, then compare them with a halfway point. Some example code:

这可以使用 canvas 元素实现。您必须创建一个canvas元素,将图像元素绘制到画布中,获取画布的图像数据,查看文本所在的部分,将这些值转换为灰度,对它们求平均值,然后将它们与中间点进行比较。一些示例代码:

var img = document.getElementById('myImage');
var c = document.createElement('canvas');
var ctx = c.getContext('2d');
var w = img.width, h = img.height;
c.width = w; c.height = h;
ctx.drawImage(img, 0, 0);
var data = ctx.getImageData(0, 0, w, h).data;
var brightness = 0;
var sX = 0, sY = 0, eX = w, eY = h;
var start = (w * sY + sX) * 4, end = (w * eY + eX) * 4;
for (var i = start, n = end; i < n; i += 4) {
      var r = data[i],
          g = data[i + 1],
          b = data[i + 2];
      brightness += 0.34 * r + 0.5 * g + 0.16 * b;
      if (brightness !== 0) brightness /= 2;
}
if (brightness > 0.5) var textColor = "#FFFFFF";
else var textColor = "#000000";

I haven't tested this code, though it should work. Make sure to change the sX, sY, eX, eY values to only the area where your text is, otherwise you will get unsatisfactory results (it will still work). Good luck!

我还没有测试过这段代码,但它应该可以工作。确保将 sX、sY、eX、eY 值更改为仅文本所在的区域,否则您会得到不满意的结果(它仍然可以工作)。祝你好运!

EDIT: You will not have to display your image in any special way. Just make sure that the color of the overlay text is the variable textColor.

编辑:您不必以任何特殊方式显示您的图像。只需确保覆盖文本的颜色是变量 textColor。

回答by jappple

you could check the background-image attribute with jQuery then adjust the text color dynamically.

您可以使用 jQuery 检查 background-image 属性,然后动态调整文本颜色。

var x = $(body).attr("background-image");
switch(x)
{
  case "something.png":
      // set color here
      break;
}