通过CSS更改PNG图像的颜色?


464

给定透明的PNG以白色显示简单形状,是否有可能通过CSS更改其颜色?某种覆盖还是什么?


4
您可以设置background-colorCSS属性。您可以创建固定的非透明部分,以及图像的透明部分,该部分将通过CSS用您喜欢的任何颜色填充。这就是您想要实现的目标吗?
jakub.g 2011年

2
@qbk,这值得一个答案,而不仅仅是一个评论。从技术上讲,您击败了我1秒。
Kirill G

2
您可以将psuedo元素与混合模式一起使用,以为100%黑色或100%白色(背景保持透明)的任何图标重新着色。在这里查看我的答案:stackoverflow.com/a/39796437/1472114
chrscblls

Answers:


568

您可以将筛选器与-webkit-filter和一起使用filter:筛选器相对于浏览器而言是较新的,但根据以下CanIUse表,超过90%的浏览器均支持它们:https ://caniuse.com/#feat=css-filters

您可以将图像更改为灰度,棕褐色等(请看示例)。

因此,您现在可以使用滤镜更改PNG文件的颜色。

body {
    background-color:#03030a;
    min-width: 800px;
    min-height: 400px
}
img {
    width:20%;
    float:left; 
     margin:0;
}
/*Filter styles*/
.saturate { filter: saturate(3); }
.grayscale { filter: grayscale(100%); }
.contrast { filter: contrast(160%); }
.brightness { filter: brightness(0.25); }
.blur { filter: blur(3px); }
.invert { filter: invert(100%); }
.sepia { filter: sepia(100%); }
.huerotate { filter: hue-rotate(180deg); }
.rss.opacity { filter: opacity(50%); }
<!--- img src http://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/500px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg -->
<img alt="Mona Lisa" src="https://www.pexels.com/photo/photo-of-a-green-leaf-2563743/?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="original">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="saturate" class="saturate">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="grayscale" class="grayscale">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="contrast" class="contrast">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="brightness" class="brightness">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="blur" class="blur">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="invert" class="invert">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="sepia" class="sepia">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="huerotate" class="huerotate">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="opacity" class="rss opacity">

资源


12
如此简短的答案是,对于大多数浏览器而言,没有任何通用的解决方案。
Trilarion 2014年

18
但是,变色或饱和实际上会对白色图像产生影响吗?
基思

6
2016年更新:该版本现在适用于除IE之外的几乎所有浏览器:caniuse.com/#feat=css-filters
Stan

4
@datatype_void有时您自己无法控制起始图像。因此,似乎您同意我的观点是正确的,您无法获得从黑色或白色开始的任何颜色。哦,我玩了5分钟多才得出结论。
AsGoodAsItGet's

5
还指定您可以执行以下操作:.gifcorrect{ filter: invert(28%) sepia(100%) hue-rotate(-180deg) saturate(3); }这意味着您可以从黑色,透明或灰度到彩色,甚至可以用于动画gif
tatsu

139

我发现了这个很棒的Codepen示例,您插入了十六进制颜色值,它返回了将这种颜色应用于png所需的过滤器

CSS过滤器生成器,可从黑色转换为目标十六进制颜色

例如我需要我的png具有以下颜色#1a9790

那么您必须将以下过滤器应用于png

filter: invert(48%) sepia(13%) saturate(3207%) hue-rotate(130deg) brightness(95%) contrast(80%);

12
<3 <3 <3 <3 <3 <3
dwjohnston '18年

2
我使用此代码将颜色从蓝色更改为白色:filter: invert(1%) sepia(1%) saturate(1%) hue-rotate(1deg) brightness(1000%) contrast(80%);
Anjan Biswas

这很棒!!
Thiago Pires,

2
作者当之无愧的雕像!(请注意:亮度(0)饱和(100%)可选前置选项可
消除

1
如果有人需要,这是此代码的TS转换gist.github.com/dwjohnston/7e60bf5d4b6c071cd869f9f346241c08
dwjohnston

56

您可能想看看图标字体。http://css-tricks.com/examples/IconFont/

编辑:我在最新的项目上使用Font-Awesome。您甚至可以引导它。只需将其放入您的<head>

<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.min.css" rel="stylesheet">

<!-- And if you want to support IE7, add this aswell -->
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome-ie7.min.css" rel="stylesheet">

然后继续添加一些像这样的图标链接:

<a class="icon-thumbs-up"></a>

这是完整的备忘单

- 编辑 -

Font-Awesome在新版本中使用了不同的类名,可能是因为这使CSS文件大大缩小了,并且避免了模棱两可的CSS类。所以现在您应该使用:

<a class="fa fa-thumbs-up"></a>

编辑2:

刚刚发现github也使用它自己的图标字体:Octicons 可以免费下载。他们还提供了一些有关如何创建自己的图标字体的提示


字体真棒不辜负它的名字。
HerrimanCoder 2015年

开箱即用的+1。如今,有易于使用的在线应用程序可帮助您从(svg)图像创建网络字体。
伊万·范德·桑顿(Yvan Vander Sanden)2015年

如果<a class="icon-thumbs-up"> </a>是旧的类名,而<a class="fa fa-thumbs-up"> </a>是新的类名,我不认为使CSS变小,我可以在fa和fa-thumbs-up之间看到一个额外的空格,如果我没记错的话,请在该CSS文件上至少增加1个字节?
布兰迪托

Font Awesome在当时是很棒的,不幸的是它的渲染阻止,这使Google及其用户不满意。首先,我们从CSS和二进制字体文件中删除了未使用的字体,从而将数据减少了一半,从而解决了这一问题。现在,我们正在完全删除并替换为一个简单的sprite,该sprite不会阻止渲染(DOM和CSSOM处理更快,使页面上的元素显示得更快),并且还将减少75%的数据,减少到6KB。FA大约为100KB。CSS掩码可能对我们有帮助,但可能不必要。
YK

25

我已经能够使用SVG过滤器执行此操作。您可以编写一个滤镜,将源图像的颜色与您要更改的颜色相乘。在下面的代码片段中,泛色是我们想要将图像颜色更改为的颜色(在这种情况下为红色)。feComposite告诉滤镜我们如何处理颜色。feComposite的算术公式为(k1 * i1 * i2 + k2 * i1 + k3 * i2 + k4)其中,i1和i2是in / in2的输入颜色。因此,仅指定k1 = 1意味着它将仅执行i1 * i2,这意味着将两种输入颜色相乘。

注意:这仅适用于HTML5,因为它使用了嵌入式SVG。但是我认为您可以通过将SVG放在单独的文件中,从而在较旧的浏览器上实现此功能。我还没有尝试过这种方法。

这是代码段:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="60" height="90" style="float:left">
  <defs>
    <filter id="colorMask1">
      <feFlood flood-color="#ff0000" result="flood" />
      <feComposite in="SourceGraphic" in2="flood" operator="arithmetic" k1="1" k2="0" k3="0" k4="0" />
    </filter>
  </defs>
  <image width="100%" height="100%" xlink:href="http://i.stack.imgur.com/OyP0g.jpg" filter="url(#colorMask1)" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="60" height="90" style="float:left">
  <defs>
    <filter id="colorMask2">
      <feFlood flood-color="#00ff00" result="flood" />
      <feComposite in="SourceGraphic" in2="flood" operator="arithmetic" k1="1" k2="0" k3="0" k4="0" />
    </filter>
  </defs>
  <image width="100%" height="100%" xlink:href="http://i.stack.imgur.com/OyP0g.jpg" filter="url(#colorMask2)" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="60" height="90" style="float:left">
  <defs>
    <filter id="colorMask3">
      <feFlood flood-color="#0000ff" result="flood" />
      <feComposite in="SourceGraphic" in2="flood" operator="arithmetic" k1="1" k2="0" k3="0" k4="0" />
    </filter>
  </defs>
  <image width="100%" height="100%" xlink:href="http://i.stack.imgur.com/OyP0g.jpg" filter="url(#colorMask3)" />
</svg>


4
伙计,您在这个答案上被抢劫了。希望使图像着色超出滤镜范围的任何人:hue-rotate可以做到-这就是做到这一点的方法。
MaxPRafferty

23

img标签与其他标签一样具有background属性。如果您使用的是透明形状的白色PNG(例如模版),则可以执行以下操作:

<img src= 'stencil.png' style= 'background-color: red'>

147
我希望白色部分具有不同的颜色,而不是透明部分。
韦斯利

2
到目前为止我找到的最佳解决方案。太糟糕了,只有在您的网站上使用纯色背景色时,它才有效
Jules Colle

8
@Wesley,您需要将图像反转(这样白位变成透明的,其余的变为白色),您可以使用自己喜欢的图像编辑器和蒙版来进行此操作。
Charles Goodwin

5
@CharlesGoodwin只有将图像放置在白色背景中才能起作用。
亚历克斯(Alex)

21

是的

Surfin'Safari-博客存档»CSS Masks

WebKit现在支持CSS中的Alpha蒙版。遮罩使您可以用一种图案覆盖框的内容,该图案可用于在最终显示中剔除该框的某些部分。换句话说,您可以根据图像的Alpha裁剪为复杂的形状。
[...]
我们引入了新的属性,为Web设计人员提供了对这些掩码及其应用方式的大量控制。新属性类似于已经存在的背景和边框图像属性。

-webkit-mask (background)
-webkit-mask-attachment (background-attachment)
-webkit-mask-clip (background-clip)
-webkit-mask-origin (background-origin)
-webkit-mask-image (background-image)
-webkit-mask-repeat (background-repeat)
-webkit-mask-composite (background-composite)
-webkit-mask-box-image (border-image)

1
我没有发现任何与Webkit无关的信息,所以这是任何(尚未出现)标准的一部分,还是仅仅是Apple风格?W3似乎建议针对此类用例使用SVG:w3.org/TR/SVG/masking.html
Feeela 2011年

3
可悲的是,这似乎仅是Webkit,博客使用合成图像而不是实际示例来作弊。这个答案有点红鲱鱼。
Charles Goodwin

17

大多数浏览器中,您可以使用过滤器:

  • <img>元素和其他元素的背景图像上

  • 并在CSS中静态设置它们,或使用JavaScript动态设置它们

请参阅下面的演示。


<img> 元素

您可以将此技术应用于<img>元素:

#original, #changed {
    width: 45%;
    padding: 2.5%;
    float: left;
}

#changed {
    -webkit-filter : hue-rotate(180deg);
    filter : hue-rotate(180deg);
}
<img id="original" src="http://i.stack.imgur.com/rfar2.jpg" />

<img id="changed" src="http://i.stack.imgur.com/rfar2.jpg" />

背景图片

您可以将此技术应用于背景图片:

#original, #changed {
    background: url('http://i.stack.imgur.com/kaKzj.jpg');
    background-size: cover;
    width: 30%;
    margin: 0 10% 0 10%;
    padding-bottom: 28%;
    float: left;
}

#changed {
    -webkit-filter : hue-rotate(180deg);
    filter : hue-rotate(180deg);
}
<div id="original"></div>

<div id="changed"></div>

的JavaScript

您可以使用JavaScript在运行时设置过滤器:

var element = document.getElementById("changed");
var filter = 'hue-rotate(120deg) saturate(2.4)';
element.style['-webkit-filter'] = filter;
element.style['filter'] = filter;
#original, #changed {
    margin: 0 10%;
    width: 30%;
    float: left;
    background: url('http://i.stack.imgur.com/856IQ.png');
    background-size: cover;
    padding-bottom: 25%;
}
<div id="original"></div>

<div id="changed"></div>


6
问题是要为具有透明背景的白色图像着色。hue-rotate不适用于白色。
Synetech

17

认为我对此有一个解决方案,它是a)恰好是您五年前所寻找的,并且b)比这里的其他代码选项更简单。

使用任何白色png(例如,透明背景上的白色图标),您可以添加:: after选择器以重新着色。

.icon {
    background: url(img/icon.png); /* Your icon */
    position: relative; /* Allows an absolute positioned psuedo element */
}

.icon::after{
    position: absolute; /* Positions psuedo element relative to .icon */
    width: 100%; /* Same dimensions as .icon */
    height: 100%;
    content: ""; /* Allows psuedo element to show */
    background: #EC008C; /* The color you want the icon to change to */
    mix-blend-mode: multiply; /* Only apply color on top of white, use screen if icon is black */
}

请参阅此代码笔(在悬停时应用颜色交换):http ://codepen.io/chrscblls/pen/bwAXZO


我从imgur重新托管了图像,加载时遇到了一些麻烦。
chrscblls 16-10-7

在最新版本的Chrome中,看起来(透明)背景也已设置为颜色。在链接的示例中,当我将鼠标悬停时,我只会看到一个不透明的粉红色方块...在Firefox中效果很好。
logidelic

1
@chrscblls链接已死。
史蒂文·卢

15

对我有用的最简单的一行:

filter: opacity(0.5) drop-shadow(0 0 0 blue);

您可以将不透明度从0调整为1,以使颜色更浅或更深。


真好 这避免了此处其他解决方案的所有限制。
cdonner '19

3
重复2-3次阴影以使其更强
djdance

1
GENIUS SOLUTION,在CSS中看起来有些混乱,但是带有注释,这是完全可以理解的。谢谢!
理查德·凯米卡勒·吉尼尔·丹顿

不能获得确切的颜色,它总是原始颜色和新颜色之间的某种混合。
swisswiss

这种方法会稍微扭曲图像,并且每次应用阴影都会使图像变得更糟。就像制作副本一样,结果与原始结果有所不同。
SMAG

8

我在谷歌搜索时发现了这个问题,发现对我最有效。

的HTML

<div class="img"></div>

的CSS

.img {
  background-color: red;
  width: 60px;
  height: 60px;
   -webkit-mask-image: url('http://i.stack.imgur.com/gZvK4.png');
}

http://jsfiddle.net/a63b0exm/


这有效,我投票赞成。但是仅出于记录目的,它确实存在一些问题,例如无法调整背景图像的尺寸,无法定位图像并重复。
丹尼尔(Daniel)

哦,我真的没有尝试过...尝试以下链接。developer.mozilla.org/zh-CN/docs/Web/CSS/-webkit-mask-box-image感谢Daniel
Muthukumar Anbalagan

7

我需要特定的颜色,因此滤镜对我不起作用。

相反,我创建了一个div,利用CSS多个背景图像和线性渐变函数(该函数本身会创建一个图像)。如果使用叠加混合模式,则实际图像将与包含所需颜色的生成的“渐变”图像混合(此处为#BADA55)

.colored-image {
        background-image: linear-gradient(to right, #BADA55, #BADA55), url("https://i.imgur.com/lYXT8R6.png");
        background-blend-mode: overlay;
        background-size: contain;
        width: 200px;
        height: 200px;        
    }
<div class="colored-image"></div>


没为我工作。我不知道为什么,我完全复制了粘贴内容
Vic Seedoubleyew

@VicSeedoubleyew片段工作正常。使用开发人员工具检查div,以确保您的CSS已被实际应用。另外,如果您未使用我提供的图像,请确保图像的URL有效。编辑:如果该代码段对您不起作用,则您可能使用的浏览器过时或不支持线性渐变功能。
rolznz

5

回答是因为我正在寻找解决方案。

如果背景为白色或黑色,则@chrscblls答案中的笔效果很好,但是我的却不是。另外,图片是使用ng-repeat生成的,因此我无法在CSS中添加其url,也不能在img标签上使用:: after。

因此,我想出了一个解决方案,并认为如果他们在这里太迷路,可能会有所帮助。

所以我所做的几乎相同,但有三个主要区别:

  • 该网址位于我的img标签中,我将其(和一个标签)放在:: after可以工作的另一个div中。
  • “混合混合模式”设置为“差异”,而不是“乘”或“屏幕”。
  • 我添加了一个:: before,其值完全相同,因此:: after将执行:: before产生的“ difference”的“ difference”,并自行取消它。

要将其从黑色更改为白色或从白色更改为黑色,背景颜色必须为白色。从黑色到颜色,您可以选择任何颜色。从白色到颜色,您需要选择所需的相反颜色。

.divClass{
   position: relative;
   width: 100%;
   height: 100%;
   text-align: left;
}
.divClass:hover::after, .divClass:hover::before{
   position: absolute;
   width: 100%;
   height: 100%;
   background: #FFF;
   mix-blend-mode: difference;
   content: "";
}

https://codepen.io/spaceplant/pen/oZyMYG


3

如果只需要一个图标,就不需要整个字体集,而且我觉得它作为一个单独的元素更“干净”。因此,为此,您可以在HTML5中将SVG直接放置在文档流中。然后,您可以在.CSS样式表中定义一个类,并使用fill属性访问其背景色:

工作提琴:http : //jsfiddle.net/qmsj0ez1/

请注意,在该示例中,我已经:hover说明了这种行为。如果只想为“正常”状态更改颜色,则应删除伪类。


1

要从字面上更改颜色,可以将CSS过渡与-webkit-filter合并,在发生某些情况时,您将调用所选的-webkit-filter。例如:

img {
    -webkit-filter:grayscale(0%);
    transition: -webkit-filter .3s linear;
    }
img:hover 
    {
    -webkit-filter:grayscale(75%);
    }

1

将图片从黑色更改为白色或从白色更改为黑色时,色相旋转滤镜不起作用,因为从技术上讲黑色和白色不是彩色。相反,必须使用反转滤镜属性完成黑白颜色的更改(从黑色到白色,反之亦然)。

.img1 { filter: invert(100%); }


0

body{
  background: #333 url(/images/classy_fabric.png);
  width: 430px;
  margin: 0 auto;
  padding: 30px;
}
.preview{
  background: #ccc;
  width: 415px;
  height: 430px;
  border: solid 10px #fff;
}

input[type='radio'] {
  -webkit-appearance: none;
  -moz-appearance: none;
  width: 25px;
  height: 25px;
  margin: 5px 0 5px 5px;
  background-size: 225px 70px;
  position: relative;
  float: left;
  display: inline;
  top: 0;
  border-radius: 3px;
  z-index: 99999;
  cursor: pointer;
  box-shadow: 1px 1px 1px #000;
}

input[type='radio']:hover{
  -webkit-filter: opacity(.4);
  filter: opacity(.4);    
}

.red{
  background: red;
}

.red:checked{
  background: linear-gradient(brown, red)
}

.green{
  background: green;
}

.green:checked{
  background: linear-gradient(green, lime);
}

.yellow{
  background: yellow;
}

.yellow:checked{
  background: linear-gradient(orange, yellow);
}

.purple{
  background: purple;
}

.pink{
  background: pink;
}

.purple:checked{
  background: linear-gradient(purple, violet);
}

.red:checked ~ img{
  -webkit-filter: opacity(.5) drop-shadow(0 0 0 red);
  filter: opacity(.5) drop-shadow(0 0 0 red);
}

.green:checked ~ img{
  -webkit-filter: opacity(.5) drop-shadow(0 0 0 green);
  filter: opacity(.5) drop-shadow(0 0 0 green);
}

.yellow:checked ~ img{
  -webkit-filter: opacity(.5) drop-shadow(0 0 0 yellow);
  filter: opacity(.5) drop-shadow(0 0 0 yellow);
}

.purple:checked ~ img{
  -webkit-filter: opacity(.5) drop-shadow(0 0 0 purple);
  filter: opacity(.5) drop-shadow(0 0 0 purple);
}

.pink:checked ~ img{
  -webkit-filter: opacity(.5) drop-shadow(0 0 0 pink);
  filter: opacity(.5) drop-shadow(0 0 0 pink);
}


img{
  width: 394px;
  height: 375px;
  position: relative;
}

.label{
  width: 150px;
  height: 75px;
  position: absolute;
  top: 170px;
  margin-left: 130px;
}

::selection{
  background: #000;
}
<div class="preview">
  <input class='red' name='color' type='radio' />
  <input class='green' name='color' type='radio' />
    <input class='pink' name='color' type='radio' />
  <input checked class='yellow' name='color' type='radio' />
  <input class='purple' name='color' type='radio' />  
  <img src="https://i.stack.imgur.com/bd7VJ.png"/>
</div>

资料来源:https : //codepen.io/taryaoui/pen/EKkcu

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.