【问题标题】:How do I fade a BufferedImage when manipulating it's pixel data?处理像素数据时如何淡化 BufferedImage?
【发布时间】:2020-08-20 16:00:08
【问题描述】:

我正在尝试做一些我以前从未做过的事情。 我的目标是能够操纵 BufferedImage 的不透明度。首先,我不使用图形。我正在开发一个简单的游戏引擎,我只使用来自 BufferedImages 的像素数据。

我尝试了什么?

我创建了自己的“Image”类,它接收一个 BufferedImage。

BufferedImage image = null;
    try {
        image = ImageIO.read(Image.class.getResourceAsStream(resourcePath));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
    width = image.getWidth();
    height = image.getHeight();
    hasAlpha = image.getColorModel().hasAlpha();
    
    pixels = image.getRGB(0, 0, width, height,null,0,width);

之后我继续我的渲染代码。我有一个名为“drawImage()”的函数,它获取图像及其数据,然后根据用户的意愿将其放在屏幕上的特定位置。但是,我希望用户也选择它的不透明度。

我从获取该像素的像素数据开始,然后创建了一个颜色。

Color c = new Color(image.getPixels()[value2],true);

据我所知,“真实”的说法是它应该“关心”Alpha。

之后我使用以下代码放置像素:

pixels[x + y * pWidth] = new Color(c.getRed(),c.getGreen(),c.getBlue(),alphaValue).getRGB();

这不起作用。它不会输出任何错误,我可以将 alphaValue 更改为 0 到无穷大之间的数字。然而,我发现的一个问题是,当我将 alpha 从 255 更改为 50 时,它根本不会影响图像。它保持不变。影响在 0-5 之间。我注意到的另一件事是,当我将 alphaValue 设置为 2 时,我得到的是动画而不是不透明度较低的图像。听起来很奇怪,这就是为什么我提供了这个问题的 .GIF:

我向您保证,没有任何代码会更改 alphaValue。在那个“动画”期间,它被设置为 2 而没有别的。

所以这里有些奇怪,不知道你们是否知道这个问题?

这可能与 Image 类有关,我没有将其设置为 BufferedImage.RGBA,但我不知道在加载图像时如何做到这一点?

如果您需要更多信息,请发表评论,我会提供更多信息!

提前致谢!

编辑 我通过操作背景像素(也是缓冲图像)每 1/60 秒清除一次屏幕:

public void clear() {
    for(int i = 0; i < pixels.length; i++) {
        pixels[i] = clearColor.getRGB();
    }
    
    
}

可能的问题

我做了一些故障排除,我发现正如@Joni 所说,它实际上以某种方式增加了每一帧的不透明度。不知何故,不透明度或 alpha 似乎增加了每一帧,但我正在清除绘图之间的屏幕。我会进一步排查问题。

更新

我做了这样我可以移动图像并发现这种奇怪的行为:

Link to Imgur

似乎“alpha”没有重置。我知道 RGB 正在重置,但在 Alpha 方面确实有些问题。

我把清除函数改成这样:

public void clear() {
    for(int i = 0; i < pixels.length; i++) {
        pixels[i] = new Color(clearColor.getRed(),clearColor.getGreen(),clearColor.getBlue(),255).getRGB();
    }
    
    
}

我将 clearColor 定义为:

Color clearColor = new Color(Color.black.getRGB(),true);

但这也不起作用。有人有解决办法吗?

【问题讨论】:

  • 该死的,如果它是 android,我有一个很好的答案。缩小图像并将其绘制在更大的尺寸上也会产生模糊效果。

标签: java alpha


【解决方案1】:

您的游戏引擎正在循环绘制图像。绘制足够多次后,效果与完全不使用透明度相同。 Alpha 值越低,所需的时间就越长:如果 Alpha 为 50%,则需要 7 帧才能获得 99% 的不透明度,而 Alpha 为 5% 则需要大约 90 帧。

例如,假设您在初始为 0(黑色)且不透明度为 50% 的屏幕上绘制像素值为 100。第一帧之后,输出像素值为 .5*100 + .5*0 = 50。第二帧绘制在第一帧之上,所以输出像素值为 .5*100 + .5*50 = 75. 在第二帧之上绘制的第三帧将显示 0.5*100 + .5*75 = 87.5。

为避免这种情况,您需要在每一帧的图像下方填充纯色背景色。

【讨论】:

  • 我将我的“透明颜色”更改为 Color.white,但没有任何区别。我不太明白你在说什么。当我将 alpha 设置为 2 并且不更改它时,不透明度如何达到 99%?如何使用相同的 Alpha 渲染相同的图像,使其不透明度达到 99%?
  • 我每 1/60 秒更新一次帧。因此,旧图像被删除并呈现新图像。我应该提到这一点。
  • 旧图删除在哪里?您的代码没有显示。
  • 这不是因为我想让问题保持简单。它被一个 clear 函数覆盖,该函数将所有背景(也是一个 BufferedImage)像素设置为特定颜色。
  • 我用显示代码的编辑更新了我的问题。
猜你喜欢
  • 2013-11-06
  • 2020-05-18
  • 1970-01-01
  • 2013-02-17
  • 2020-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多