Как затемнить изображение, сохраняя прозрачность нетронутой с помощью CSS или JS?

нормальный подход к затемнению изображения, предлагаемого везде, заключается в том, чтобы изменить его атрибут непрозрачности и отобразить что-то темное под ним. Тем не менее, мое изображение имеет прозрачность и находится на белом фоне. Поэтому я хочу сохранить фон под прозрачными частями белого изображения, только делая темнее пиксели, которые имеют цвет. Можно ли это сделать в CSS (желательно) или JS?

EDIT: примеры изображений http://imgur.com/a/Tat9f

пример изображение:

enter image description here

4 ответов


существует относительно новое свойство CSS filter который может достичь того, что вы после.

на brightness вариант, кажется, то, что вы после.

EDIT-добавлена временная поддержка FF через URL

jsfiddle Demo (с параметрами яркости и контрастности)

в 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 на фильтре

поддержка не-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>

Если вы хотите использовать 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';

это наивный расчет, чтобы сделать его, легко, но как видите это не трудно изменить его на что-то покрасивее. Так как мы не касаемся Альфы канал, прозрачность остается нетронутой.

вот скрипка:http://jsfiddle.net/markm/kwsogrdt/
(браузер жалуется на изображение cross origin, по крайней мере, в safari, поэтому вторая-последняя строка.)


вы думали, вместо того, чтобы изменять непрозрачность изображения, скажем, положить div поверх изображения с тем же размером, что и изображение, непрозрачность 0,3 и цвет фона черный.

Это может быть не то, что вы ищете, хотя его пища для размышлений.

Габ


другой способ сделать это - использовать новый CSS mask свойство (в настоящее время полностью поддерживается только webkit) на div с затемнением.

.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;
}