【问题标题】:How to add a tint to a background image with transparency in CSS如何在 CSS 中为具有透明度的背景图像添加色调
【发布时间】:2021-02-26 06:52:12
【问题描述】:

我在用作全局背景的页面上有一些内容。 我在上面使用position: absolute 放置了一个精灵(divbackground-image: url(...),通过修改background-position 来改变帧)。精灵是带有 alpha 通道的 PNG。

现在我正在尝试为该图像添加一些色调(绿色或蓝色或其他)。

我研究了类似的问题,显然唯一可能的解决方案是:

  1. 在精灵顶部创建一个div,所需颜色为background-color,所需色调强度为opacity,原始精灵图像为mask-image(并设置mask-type: alpha)。虽然它应该在纸上工作,但实际上并没有——这个新的div 只是不可见的:(
  2. 使用mix-blend-mode 覆盖颜色div 并指定类似multiplyoverlay 的内容。只要全局背景为黑色,它就会产生完美的效果。如果是其他东西 - 它会包含在计算中,并且覆盖层 div 也会对其进行修改,生成一个着色矩形而不是着色精灵...
  3. 使用此处回答中所述的 SVG 过滤器:https://stackoverflow.com/a/30949302/306470。 我还没有尝试过这个,但是对于这项任务来说感觉不必要的复杂。我也担心这里的性能,如果屏幕上同时有多个着色精灵会减慢很多吗?如果有人对此有经验-请在此处发表评论:)
  4. 使用不可见的canvas 准备一个着色版本的精灵。听起来更复杂,缺点是必须花时间准备精灵的着色版本,但是一旦准备好就应该像原始精灵一样快吗?不过,实现应该相当复杂。纯 CSS 解决方案会好得多...

我错过了什么吗?还有其他选择吗?或者我应该选择#3 还是#4?

【问题讨论】:

  • 尝试filter: hue-rotate(Xdeg)更改X的值以满足您的要求
  • 谢谢!我已经考虑过了,但它只适用于或多或少的单色调图像,我应该在应用过滤器之前知道该色调。
  • 如果您的图像不是动态的,您可以为每个图像找到所需的色调旋转,将它们添加到对象中,然后使用 js 动态应用过滤器。但如果您有很多图像或图像是用户生成的,则可能不适用
  • 图像不是用户生成的,但我可能会有很多图像,手动查找正确的色调并不是一个真正的选择。不过还是谢谢你的建议!
  • 您可以使用 JS 获取图像的位置 getBoundingClientRect() 然后将覆盖元素的位置设置为具有更高 zindex 的绝对位置,然后使用 rect.top、rect.left您的图像设置将它们设置为叠加层,以便它们位于顶部。使用 this.width 和 this.height 获取图像的宽度和高度,并将覆盖元素设置为这些宽度和高度。将覆盖元素的 backgroundColor 设置为所需的 RGB,不透明度为 (0, 255, 0, 0.5) => 绿色覆盖或随机化 RGB,不透明度设置为 0.5,使其起到过滤器的作用。

标签: html css sprite transparency tint


【解决方案1】:

这是我留下的概述评论的工作示例,希望对您有所帮助。我使用创建的 div 元素覆盖在图像之上。使用在图像元素上循环的 for 循环中的 boundingClientRect 和 this.width/this.height 获取图像元素的位置。将覆盖元素的位置设置为被循环的图像元素的位置,并使用 rgb 将 alpha 设置为 0.5 的函数随机化颜色。

let fgrp = document.getElementById("group");
let images = document.querySelectorAll(".imgs");
//function to randomize the RGB overlay color
function random() {
  var o = Math.round,
    r = Math.random,
    s = 255;
  return o(r() * s);
}
//function to randomize a margin for each image to show the overlay will snap to the image 
function randomWidth() {
  var n = Math.round,
    ran = Math.random,
    max = 400;
  return n(ran() * max);
}
// loop through the img elements and create an overlay div element for each img element
for (let i = 0; i < images.length; i++) {
  // load the images and get their wisth and height
  images[i].onload = function() {
    let width = this.width;
    let height = this.height;
    this.style.marginLeft = randomWidth() + "px";
    // create the overlay element
    let overlay = document.createElement("DIV");
    // append the overlay element
    fgrp.append(overlay);
    // get the image elements top, left positions using `getBoundingClientRect()`
    let rect = this.getBoundingClientRect();
    // set the css for the overlay using the images height, width, left and top positions
    // set position to absolute incase scrolling page, zindex to 2 
    overlay.style.cssText = "width: " + this.offsetWidth + "px; height: " + this.offsetHeight + "px; background-color: rgba(" + random() + ", " + random() + ", " + random() + ", 0.5); left: " + rect.left + "px; top: " + rect.top + "px; position: absolute; display: block; z-index: 2; cursor pointer;";
  }
}
img {
  margin: 50px 0;
  display: block;
}
<div id="group">
  <image src="https://artbreeder.b-cdn.net/imgs/275c7c05efca3a40e3178208.jpeg?width=256" class="imgs"></image>
  <image src="https://artbreeder.b-cdn.net/imgs/275c7c05efca3a40e3178208.jpeg?width=256" class="imgs"></image>
  <image src="https://artbreeder.b-cdn.net/imgs/275c7c05efca3a40e3178208.jpeg?width=256" class="imgs"></image>
</div>

【讨论】:

  • 它不适用于具有透明度的图像:它会为整个矩形添加色调,包括在图像的透明部分可见的图像下方的背景。
【解决方案2】:

按照下面的指南,可以只使用 CSS 在 div/图像上设置彩色,如下所示:

<html>

<head>
    <style>
        .hero-image {
            position: relative;
            width: 100%;
        }

        .hero-image:after {
            position: absolute;
            height: 100%;
            width: 100%;
            background-color: rgba(0, 0, 0, .5);
            top: 0;
            left: 0;
            display: block;
            content: "";
        }
    </style>
</head>

<body>
    <div class="hero-image">
        <img src="https://cdn.jpegmini.com/user/images/slider_puffin_before_mobile.jpg" alt="after tint" />
    </div>
    <div>
        <img src="https://cdn.jpegmini.com/user/images/slider_puffin_before_mobile.jpg" alt="before tint" />
    </div>
</body>

</html>

由于您试图将其放置在绝对位置图像的顶部,如指南所述,请将 z-index 为 1(例如)添加到 :after 块中。

编辑:可能需要对宽度的百分比进行一些调整!

来源:https://ideabasekent.com/wiki/adding-image-overlay-tint-using-css

【讨论】:

  • 不幸的是,这不适用于具有透明部分的图像,正如我在问题中解释的那样:(
猜你喜欢
  • 2013-12-08
  • 2020-09-13
  • 2017-08-11
  • 2015-01-20
  • 2017-04-24
  • 2012-07-26
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
相关资源
最近更新 更多