11/2 Java/SWTの画像処理について
11/16 日常
11/20 SWT・追記
はい、こんにちわ。
今日はがらりと話題を変えて私が最も得意とする(というかこれ以外はほとんど出来ない)Javaのお話をしようと思います。
JavaはJavaでも「SWT」(標準で付属してないGUIライブラリ)です。
SWTに関しては調べればざくざくと情報が出てくるのでそちらにお任せしますです。
で、さっそく本題に入りましょう。
まず、今日の話題が出ることになったきっかけがTaking a look at SWT Imagesのページなんですね。
このページにはSWTで出来る画像処理について役立つ知識が盛りだくさん! なんですが英語でわかりにく〜い(´д`)ハァ〜
まぁプログラミングをする者なら多少の英語くらい何とかせねばならんのですが、ワカランもんはワカランのじゃーっ!ヽ(`Д´)ノ
なので、そのページに書いてあることを元にして、かなり端折ったりしながら適当に翻訳&まとめたいと思います。(まだわからないところも多いのですよ)
今回使用するクラス
・Image …… 画像を表示する時に必要なクラス。今回はこれが無くては始まらない。
・ImageData …… 画像の細かいデータ(透明度や色情報など)を持っている。
・ImageLoader …… 今回はおまけ的扱い。画像を簡単に読み出したり保存したり出来る。また、ImageDataを使って保存も出来る。
・GC …… これもかなり重要。加工したImageをcanvasなどのウィジットに描きだすときに使用。
などのクラスを主に使います。 細かいことは追々説明するかもしれません。
お品書き
・画像全体の透明度の変更
・指定色のみの透明化
・ピクセル単位の透明度の指定
・ImageLoadeを使って加工した画像を保存
・GCを使い方。あれこれ。
使用する画像
実験した時はこの2倍の大きさでやってたんですけどね。
画像全体の透明度の変更
画像全体の透明度を変更するには、ImageDataのalphaプロパティを変更すればオーケーです。
ただしImageDataで透過処理をした画像はaddPaintListener()を使用しないと透過されない。
指定色のみの透明化
透過したい色を指定。 実は指定したピクセル(の色)でも出来る。
透過したい色を取得して、ImageDataのtransparentPixelプロパティにセットします。
困ったことにjpgだけは圧縮の関係でRGB値が変化するのかうまく透過できない。
bmpは無問題。png,gifは画質を高くすれば大丈夫なはずです。たぶん。
ちなみに、このテスト画像だけ文字が黒いコトには突っ込まないでください。
ピクセル単位の透明度の指定
タイトルどおり、1ピクセルごとに透明度を設定します。
これも使い方は簡単でImageDataのプロパティ[alphaData]に値をセットすれば良いのです。
まず、alphaDataはバイト配列なので、表示画像のピクセル数分(縦×横)のbyte[]を用意します。
あとはfor文でひたすら全ピクセルに透明度を指定していけばオーケーです。
まぁ別に全ピクセルに指定する必要も無いんですが。
使い道として徐々に透明になっていく、っていうのや、下半分だけ半透明っていうのも出来るでしょう。
ImageLoadeを使って加工した画像を保存
ImageLoaderクラスを使って、ウィジットに描画された画像を保存します。
GCなどで動的に描かれた画像を保存するのに使える。。。 ってそのまんまやん。
でもいまいち理解していない部分があるので、話半分に聞いておいてください。
保存される画像の大きさは、新規に作ったImage3の大きさです。
実は気をつけることがひとつ。
shellにタイトルバーがついてると、GCの0,0座標はウィンドウの左上、タイトルバーの直下になるのです。
そのぶん画面領域が減るので、このまま保存を実行するとタイトルバーの分だけ下部に空きが出来てしまいます。
これを回避するにはshellにタイトルバーを表示させないか、タイトルバーの正確な大きさを調べておくかですね。
ちなみに、横幅もちょび〜っとだけ、狭くなってます。
保存形式はSWT.IMAGE_BMPのほかにも、IMAGE_JPG、IMAGE_GIF、IMAGE_PNG、IMAGE_TIFFがありました。
ただ、試してないので使えるかどうかはわかりません。
どっかでTIFFあたりにバグがあるとか無いとか聞いたような……?
GCを使い方。あれこれ。
GC。グラフィックコンテキスト。仮想画面?
デスクトップではない別の領域があって、そこに線を書いたり円を書くなどいろいろでき、 その仮想画面を実画面に転送することによって描画とする。
ゲームとか作るなら必須だねッ!
大まかにできることの箇条書き。
これまでに描いた透過処理ももちろんGC無くしては語りえないので
GCは大事ダヨ!
終わりに。
いや……長かったですよ……。意外に。
もともと、ノベルゲームが作りたくてJavaの画像処理を調べていたけど
ようやく、出口の入り口が見え始めたかもしれません。 遥か遠くに。
もう正直疲れたヨ( -Д-)〜3
また明日から目標目指してがんばろー
追伸:
使用済みオブジェクトのdispose()は忘れないでください。
会社での日課。
自習。
……エート、モウ半年ハ、過ギマシタヨ?
まぁ、好き放題自習させてもらってるから先日のような結果が出せるんですけどね……
ある日突然クビになったりしてw アハハッwwww (←笑い事じゃない?
いやー、Cが難しいなぁー。
いまだにCを勉強する意味はあるのか疑問ですよー。C++で十分じゃないのかなぁ?
でもまぁC++を勉強しようと思ったらCが必要になるから結局おなじかぁ。。。
がんばろー
11/2に書いたSWTに関する話題の追記です。
指定色を透過した上で、さらに別の色を半透過したい場合。
描画に適したウィジット
最後に。
使用する画像
例によって1/2倍です。
指定色を透過した上で、さらに別の色を半透過したい場合。
前提
・ImageData.transparentPixelプロパティとalphaプロパティは両立しないらしい。
・ImageData.transparentPixelは一色しか指定できない。
・ImageData.alphaプロパティは強制で画像全体(全色)が透過されてしまう。
前提をご覧のように前回の方法では二色以上の透過が出来ませんでした。
しかしそれを実現する方法がないわけではもちろん、ないです。
それを実現する方法は簡単で、
前回のピクセル単位の透明度の指定をちょこっと応用すれば実現できます。
今回は灰色の画像に四角い枠の画像を合成します。
枠画像の0,0ピクセルを完全に透過し、赤茶色の部分を半透過してみます。
もちろん半透過色を複数指定すれば複数の色がそれぞれの透過度で透過できます。
描画に適したウィジット
前回の日記では特に何も考えずShellに直接描画してましたが、
Shellに描画してると困ったことになったりしますので、実際に使用するときにはcanvasに描画するようにしましょう。
例えば短い間隔で何度もredraw()を繰り返すと、再描画した際にずいぶんとちらつきます。
canvasでもデフォルトのだとちらつきますので、回避するにはコンストラクタにSWT.NO_BACKGROUNDを指定すればおkです。
最後に。
めんどくさくて原因を追求しなかったんですが、
以前SWT.IMAGE_COPYを使用してイメージのコピーを作った時、
なぜか上下左右が反転したものが出来たんですよ。
いま再現しようとしても出来ないのがさらに謎なんですが、まぁその時は回避策として
Image copyimg = new Image(Display.getDefault(),(ImageData)img.getImageData.clone());
で新しいImageを作りました。
何か折に参考になれば幸いでス。
11/16 日常
11/20 SWT・追記
11/2 Java/SWTの画像処理について |
はい、こんにちわ。
今日はがらりと話題を変えて私が最も得意とする(というかこれ以外はほとんど出来ない)Javaのお話をしようと思います。
JavaはJavaでも「SWT」(標準で付属してないGUIライブラリ)です。
SWTに関しては調べればざくざくと情報が出てくるのでそちらにお任せしますです。
で、さっそく本題に入りましょう。
まず、今日の話題が出ることになったきっかけがTaking a look at SWT Imagesのページなんですね。
このページにはSWTで出来る画像処理について役立つ知識が盛りだくさん! なんですが英語でわかりにく〜い(´д`)ハァ〜
まぁプログラミングをする者なら多少の英語くらい何とかせねばならんのですが、ワカランもんはワカランのじゃーっ!ヽ(`Д´)ノ
なので、そのページに書いてあることを元にして、かなり端折ったりしながら適当に翻訳&まとめたいと思います。(まだわからないところも多いのですよ)
今回使用するクラス
・Image …… 画像を表示する時に必要なクラス。今回はこれが無くては始まらない。
・ImageData …… 画像の細かいデータ(透明度や色情報など)を持っている。
・ImageLoader …… 今回はおまけ的扱い。画像を簡単に読み出したり保存したり出来る。また、ImageDataを使って保存も出来る。
・GC …… これもかなり重要。加工したImageをcanvasなどのウィジットに描きだすときに使用。
などのクラスを主に使います。 細かいことは追々説明するかもしれません。
お品書き
・画像全体の透明度の変更
・指定色のみの透明化
・ピクセル単位の透明度の指定
・ImageLoadeを使って加工した画像を保存
・GCを使い方。あれこれ。
使用する画像
back.jpg | test.jpg(bmp,gif,pngもあり) |
画像全体の透明度の変更
画像全体の透明度を変更するには、ImageDataのalphaプロパティを変更すればオーケーです。
ただしImageDataで透過処理をした画像はaddPaintListener()を使用しないと透過されない。
指定色のみの透明化
透過したい色を指定。 実は指定したピクセル(の色)でも出来る。
透過したい色を取得して、ImageDataのtransparentPixelプロパティにセットします。
困ったことにjpgだけは圧縮の関係でRGB値が変化するのかうまく透過できない。
bmpは無問題。png,gifは画質を高くすれば大丈夫なはずです。たぶん。
ちなみに、このテスト画像だけ文字が黒いコトには突っ込まないでください。
ピクセル単位の透明度の指定
タイトルどおり、1ピクセルごとに透明度を設定します。
これも使い方は簡単でImageDataのプロパティ[alphaData]に値をセットすれば良いのです。
まず、alphaDataはバイト配列なので、表示画像のピクセル数分(縦×横)のbyte[]を用意します。
あとはfor文でひたすら全ピクセルに透明度を指定していけばオーケーです。
まぁ別に全ピクセルに指定する必要も無いんですが。
使い道として徐々に透明になっていく、っていうのや、下半分だけ半透明っていうのも出来るでしょう。
ImageLoadeを使って加工した画像を保存
ImageLoaderクラスを使って、ウィジットに描画された画像を保存します。
GCなどで動的に描かれた画像を保存するのに使える。。。 ってそのまんまやん。
でもいまいち理解していない部分があるので、話半分に聞いておいてください。
保存される画像の大きさは、新規に作ったImage3の大きさです。
実は気をつけることがひとつ。
shellにタイトルバーがついてると、GCの0,0座標はウィンドウの左上、タイトルバーの直下になるのです。
そのぶん画面領域が減るので、このまま保存を実行するとタイトルバーの分だけ下部に空きが出来てしまいます。
これを回避するにはshellにタイトルバーを表示させないか、タイトルバーの正確な大きさを調べておくかですね。
ちなみに、横幅もちょび〜っとだけ、狭くなってます。
保存形式はSWT.IMAGE_BMPのほかにも、IMAGE_JPG、IMAGE_GIF、IMAGE_PNG、IMAGE_TIFFがありました。
ただ、試してないので使えるかどうかはわかりません。
どっかでTIFFあたりにバグがあるとか無いとか聞いたような……?
GCを使い方。あれこれ。
GC。グラフィックコンテキスト。仮想画面?
デスクトップではない別の領域があって、そこに線を書いたり円を書くなどいろいろでき、 その仮想画面を実画面に転送することによって描画とする。
ゲームとか作るなら必須だねッ!
大まかにできることの箇条書き。
・点 ・線 ・弧 ・長方形 ・楕円 ・多角形 ・多角線 |
(点は見えないので省略) |
これまでに描いた透過処理ももちろんGC無くしては語りえないので
GCは大事ダヨ!
終わりに。
いや……長かったですよ……。意外に。
もともと、ノベルゲームが作りたくてJavaの画像処理を調べていたけど
ようやく、出口の入り口が見え始めたかもしれません。 遥か遠くに。
もう正直疲れたヨ( -Д-)〜3
また明日から目標目指してがんばろー
追伸:
使用済みオブジェクトのdispose()は忘れないでください。
11/16 日常 |
会社での日課。
自習。
……エート、モウ半年ハ、過ギマシタヨ?
まぁ、好き放題自習させてもらってるから先日のような結果が出せるんですけどね……
ある日突然クビになったりしてw アハハッwwww (←笑い事じゃない?
いやー、Cが難しいなぁー。
いまだにCを勉強する意味はあるのか疑問ですよー。C++で十分じゃないのかなぁ?
でもまぁC++を勉強しようと思ったらCが必要になるから結局おなじかぁ。。。
がんばろー
11/20 SWT・追記 |
11/2に書いたSWTに関する話題の追記です。
指定色を透過した上で、さらに別の色を半透過したい場合。
描画に適したウィジット
最後に。
使用する画像
back1120.png(ただの灰色画像) | Frame.png |
指定色を透過した上で、さらに別の色を半透過したい場合。
前提
・ImageData.transparentPixelプロパティとalphaプロパティは両立しないらしい。
・ImageData.transparentPixelは一色しか指定できない。
・ImageData.alphaプロパティは強制で画像全体(全色)が透過されてしまう。
前提をご覧のように前回の方法では二色以上の透過が出来ませんでした。
しかしそれを実現する方法がないわけではもちろん、ないです。
それを実現する方法は簡単で、
前回のピクセル単位の透明度の指定をちょこっと応用すれば実現できます。
今回は灰色の画像に四角い枠の画像を合成します。
枠画像の0,0ピクセルを完全に透過し、赤茶色の部分を半透過してみます。
もちろん半透過色を複数指定すれば複数の色がそれぞれの透過度で透過できます。
描画に適したウィジット
前回の日記では特に何も考えずShellに直接描画してましたが、
Shellに描画してると困ったことになったりしますので、実際に使用するときにはcanvasに描画するようにしましょう。
例えば短い間隔で何度もredraw()を繰り返すと、再描画した際にずいぶんとちらつきます。
canvasでもデフォルトのだとちらつきますので、回避するにはコンストラクタにSWT.NO_BACKGROUNDを指定すればおkです。
最後に。
めんどくさくて原因を追求しなかったんですが、
以前SWT.IMAGE_COPYを使用してイメージのコピーを作った時、
なぜか上下左右が反転したものが出来たんですよ。
いま再現しようとしても出来ないのがさらに謎なんですが、まぁその時は回避策として
Image copyimg = new Image(Display.getDefault(),(ImageData)img.getImageData.clone());
で新しいImageを作りました。
何か折に参考になれば幸いでス。