【问题标题】:How to dim an image keeping transparency untouched with CSS or JS?如何使图像变暗以保持透明度不受 CSS 或 JS 影响?
【发布时间】:2014-09-25 09:00:02
【问题描述】:

通常建议在任何地方使图像变暗的方法是更改​​其不透明度属性并在其下方显示一些暗色。但是,我的图像具有透明度并且在白色背景上。所以我想将背景保持在图像白色的透明部分下,只会使有颜色的像素变暗。这可以在 CSS(最好)或 JS 中实现吗?

编辑:示例图片http://imgur.com/a/Tat9f

示例图片:

【问题讨论】:

  • 制作另一张本质上是您的剪影的图像,将所有不透明像素设为黑色,将其放置在原始图像的正下方,然后更改原始图像的不透明度。
  • @PitaJ 好吧,我也可以只制作暗淡的图像并显示它,但我有 50 张这样的图像,它们可能会发生变化,所以这会很耗时,但是如果没有更好的解决方案,我想我将不得不这样做。
  • 您可以将其转换为画布并在画布中调暗。
  • 我认为canvas 元素很有可能实现这一点,但由于我对此了解不多,因此我宁愿不尝试为此提出答案。使用drawing an image on html canvas with opacity 之类的术语浏览网络。
  • 或许您可以先分享图片,以便我们查看正在处理的内容,但 filter 属性可能会提供一些选项?

标签: javascript html css opacity


【解决方案1】:

有一个相对较新的 CSS 属性 filter 可能会实现您的目标。

brightness 选项似乎正是您所追求的。

编辑 - 通过 URL 添加对 FF 的临时支持

JSFiddle Demo (with brightness and contrast options)

CSS

img {
width:250px;
}
#one:hover {
    -webkit-filter:brightness(50%);
    -moz-filter:brightness(50%);
    filter: url(#brightness); /* required for FF */
    filter:brightness(50%);
}
#two:hover {
    -webkit-filter:contrast(50%);    
    -moz-filter:contrast(50%);
     filter: url(#contrast);
    filter:contrast(50%);
}

MDN on Filter

支持非 IE 见 CanIUse.com

FF 支持(在撰写本文时)需要定义 SVG 过滤器

亮度@50%

<svg height="0" xmlns="http://www.w3.org/2000/svg">

    <filter id="brightness">
        <feComponentTransfer>
            <feFuncR type="linear" slope=".5" />
            <feFuncG type="linear" slope=".5" />
            <feFuncB type="linear" slope=".5" />
        </feComponentTransfer>
    </filter>

</svg>

对比度@200%

<svg height="0" xmlns="http://www.w3.org/2000/svg">
    <filter id="contrast">
        <feComponentTransfer>
            <feFuncR type="linear" slope="2" intercept="-(0.5 * 2) + 0.5" />
            <feFuncG type="linear" slope="2" intercept="-(0.5 * 2) + 0.5" />
            <feFuncB type="linear" slope="2" intercept="-(0.5 * 2) + 0.5" />
        </feComponentTransfer>
    </filter>
</svg>

【讨论】:

  • 谢谢,这可能是我正在寻找的,但你的小提琴在最新的 Firefox 中不起作用。
  • 有趣,它在 FF30 中可以工作,但当我更新到 FF31 时就不行了。
  • @KonstantinPereyaslov 添加了基于 MDN 文章的 FF 支持
【解决方案2】:

如果您想使用 javascript 而不是 css,使用 HTML 画布做到这一点并不是特别困难。您只需将图像对象交给画布,然后获取上下文,这将允许您循环并操作各个颜色通道。当然没有JS就完全崩溃了。

function darkenImage(imageObj, percentage) {
    var canvas = document.getElementById('aCanvas');
    var context = canvas.getContext('2d');
    var x =0;
    var y =0;

    context.drawImage(imageObj, x, y);

    var imageData = context.getImageData(x, y, imageObj.width, imageObj.height);
    var data = imageData.data;

    for(var i = 0; i < data.length; i += 4) {
       // red
       data[i] = percentage * data[i];
       // green
       data[i + 1] = percentage * data[i + 1];
       // blue
       data[i + 2] =  percentage * data[i + 2] ;
    }

    // overwrite original image
    context.putImageData(imageData, x, y);
  }
var anImage = new Image();
anImage.onload = function() {
    darkenImage(this, .5);
  };
anImage.crossOrigin = 'http://api.imgur.com/crossdomain.xml'
anImage.src = 'http://i.imgur.com/GnMumrk.png';

这是一个简单的计算,但正如您所见,将其更改为更高级的东西并不难。由于我们不接触 Alpha 通道,因此透明度保持不变。

这是一个小提琴:http://jsfiddle.net/markm/kwsogrdt/
(浏览器至少在 safari 中抱怨跨源图像,这就是倒数第二行存在的原因。)

【讨论】:

  • 我是这个的粉丝,因为它将是这种行为最跨浏览器的。
【解决方案3】:

另一种方法是在带有变暗的 div 上使用新的 CSS mask 属性(目前只有 webkit 完全支持)。

.dim {
  display: none;
  /*Also position it above the image*/
 }

.dim:hover {
 background-color: black;
 opacity: 0.5;
 -webkit-mask: url(image.png) top left / cover;
}

【讨论】:

    【解决方案4】:

    你有没有想过不改变图像的不透明度,比如在图像顶部放置一个与图像大小相同、不透明度为 0.3、背景颜色为黑色的 div。

    这可能不是您想要的,尽管它值得深思。

    加布

    【讨论】:

    • 这将如何解决任何问题?图像的透明像素仍然会变暗。
    猜你喜欢
    • 1970-01-01
    • 2012-02-05
    • 2013-07-03
    • 1970-01-01
    • 1970-01-01
    • 2014-02-20
    • 2014-12-31
    • 2013-05-31
    • 2020-07-14
    相关资源
    最近更新 更多