我有一个 Java 应用程序,我需要在图像上绘制文本。文本、字体和图像都是在运行时确定的。文本需要看起来不错,但在图像顶部是可读的(足够对比)。
为了满足这些要求,我创建了一个投影。这是通过在空白/透明的 BufferedImage 上以不透明的黑色绘制文本,然后应用高斯模糊滤镜来完成的。然后我再次在阴影的顶部以不透明的白色绘制文本。所以我有不透明的白色文本,周围有一个黑色模糊的阴影,很快就会消失到完全透明的状态。然后我可以在背景图像上绘制这个图像。
我要解决的问题是阴影看起来太透明了。因此,在明亮、繁忙的背景下,它并没有给白色文本提供足够的分离度。
那么如何增加阴影的不透明度呢?我尝试增加高斯模糊的半径,这会使阴影更宽,但不会使其更不透明。
我使用的代码基于Romain Guy 的DropShadowDemo。我使用他的 createDropShadow() 和 gaussianBlurFilter()。但不是在 期间分别paintComponent()
绘制阴影和文本,而是提前将它们都绘制到 BufferedImage 上;我在paintComponent()
. 也许这是我的问题?但我不明白这会如何降低阴影的不透明度。g2.setComposite()
期间我不使用paintComponent()
。
我已经研究过使用某种BufferedImageOp来调整阴影的不透明度,例如 LookupOp。但是对于一个简单的调整来说似乎需要做很多工作(我猜是创建四个数字数组)。我不认为 RescaleOp 会起作用,因为我希望结果 alpha 与源 alpha 处于同一范围(0 到 1)内。如果我可以指定一个设置 new alpha = sqrt(old alpha) 的 BufferedImageOp 或类似的东西,那将是理想的。但我不知道一个简单的方法来做到这一点。
代码的详细信息可以在这里看到:
- ShadowedText.java(创建带有阴影的文本图像)
- SetBeforeMe.java(实现绘制图像的paintComponent())
我会在这里包含相关的代码块,但似乎相关的代码量太大(代码墙)......不妨只提供指向源文件的链接。
更新
看起来像更改 BufferedImage 的 alpha 值?将是一种改变阴影不透明度的方法......基本上是一个一个地重新计算每个像素的 alpha 值。待定:它是否可移植(例如,对于 64 位机器),以及它是否足够快。如果我这样做a = sqrt(a)
或a = sin(a * pi * 0.5)
在每个像素上(考虑a
在 0 到 1 的范围内),那会很慢吗?我很高兴知道是否有一种更简单的方法可以利用可用的优化,比如内置的 BufferedImageOps 大概就是这样做的。也许答案毕竟是为 LookupOp 构建数组。有人知道一些示例代码吗?
最终更新
使用 LookupOp 解决;请参阅下面的代码。