如何使图像变暗以保持透明度不受 CSS 或 JS 影响?

Posted

技术标签:

【中文标题】如何使图像变暗以保持透明度不受 CSS 或 JS 影响?【英文标题】:How to dim an image keeping transparency untouched with CSS or 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 属性可能会提供一些选项? 【参考方案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  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  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。

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

加布

【讨论】:

这将如何解决任何问题?图像的透明像素仍然会变暗。

以上是关于如何使图像变暗以保持透明度不受 CSS 或 JS 影响?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 CSS 使元素的背景颜色变暗一点

如何让网页渐渐变暗?

如何在 CSS 中使背景图像变暗? [复制]

如何在 iPhone 上使形状不规则的透明 CALayer 变暗?

使 CSS 背景图像变暗? [复制]

如何在不使用滤镜的情况下使图像变暗? [复制]