如何使图像变暗以保持透明度不受 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 影响?的主要内容,如果未能解决你的问题,请参考以下文章