画像の上にテキストを描画する必要がある Java アプリケーションがあります。テキスト、フォント、画像はすべて実行時に決定されます。テキストは見栄えがよく、画像の上で読みやすい (十分にコントラストが強い) 必要があります。
これらの要件を満たすために、ドロップ シャドウを作成します。これは、空白/透明な BufferedImage に不透明な黒でテキストを描画し、ガウスぼかしフィルターを適用することによって行われます。次に、ドロップ シャドウの上に不透明な白でテキストを再度描画します。そのため、不透明な白いテキストがあり、その周りに黒いぼやけた影があり、すぐに完全に透明になります。次に、この画像を背景画像の上に描画できます。
私が解決しようとしている問題は、ドロップ シャドウが透明すぎるように見えることです。そのため、明るく賑やかな背景に対しては、白いテキストが十分に分離されません。
では、影の不透明度を上げるにはどうすればよいでしょうか。ガウスぼかしの半径を大きくしてみました。これにより、影が広くなりますが、不透明にはなりません。
私が使用しているコードは、Romain Guy によるこの DropShadowDemoに基づいています。彼の createDropShadow() と gaussianBlurFilter() を使用します。ただし、ドロップ シャドウとテキストを別々にpaintComponent()
描画する代わりに、事前に両方を BufferedImage に描画します。そして、この単一の BufferedImage を背景の上に描画しpaintComponent()
ます. 多分それは私の問題ですか?しかし、それが影の不透明度をどのように減少させるかわかりません。g2.setComposite()
中は使用していませんpaintComponent()
。
LookupOp などのある種のBufferedImageOpを使用して、ドロップ シャドウの不透明度を調整することを検討しました。しかし、単純な調整 (数値の 4 つの配列を作成することだと思います) には多くの作業が必要なようです。結果のアルファをソースのアルファと同じ範囲 (0 から 1) に収めたいので、RescaleOp は機能しないと思います。new alpha = sqrt(old alpha) などを設定する BufferedImageOp を指定できれば理想的です。しかし、私はそれを行う簡単な方法を知りません。
コードの詳細は次の場所で確認できます。
- ShadowedText.java (ドロップ シャドウ付きのテキスト イメージを作成します)
- SetBeforeMe.java (画像を描画する paintComponent() を実装)
関連するコード ブロックをここに含めますが、関連するコードの量が大きすぎるようです (コードの壁)... ソース ファイルへのリンクを提供するだけでもかまいません。
アップデート
BufferedImage のアルファ値を変更しますか? ドロップシャドウの不透明度を変更する方法です...基本的に、各ピクセルのアルファ値を1つずつ再計算します。TBD: 移植可能かどうか (64 ビット マシンなど)、および十分に高速かどうか。a = sqrt(a)
またはa = sin(a * pi * 0.5)
すべてのピクセルで (0 から 1 の範囲で考えて)実行a
すると、遅くなりますか? 組み込みの BufferedImageOps がおそらく行うように、利用可能な最適化を利用するより簡単な方法があるかどうかを知りたいです。結局、答えは LookupOp の配列を構築することかもしれません。そのためのサンプルコードを知っている人はいますか?
最終更新
LookupOp を使用して解決しました。以下のコードを参照してください。