J2MEで画像(アルファ付きのpngファイルからロードされた)を新しい透明なグレースケール画像に変換する可能性はありますか?
今まで私はrgb値だけを取得し、アルファは取得しませんでした。
ありがとう。
編集:はい、32ビットグレースケールである必要があります。
私は解決策を見つけました、そしてここにコードがあります:
public Image getGrayScaleImage() {
int[] rgbData = new int[getWidth() * getHeight()];
image.getRGB(rgbData, 0, getWidth(), 0, 0, getWidth(), getHeight());
for (int x = 0; x < getWidth() * getHeight(); x++) {
rgbData[x] = getGrayScale(rgbData[x]);
}
Image grayImage = Image.createRGBImage(rgbData, getWidth(), getHeight(), true);
return grayImage;
}
private int getGrayScale(int c) {
int[] p = new int[4];
p[0] = (int) ((c & 0xFF000000) >>> 24); // Opacity level
p[1] = (int) ((c & 0x00FF0000) >>> 16); // Red level
p[2] = (int) ((c & 0x0000FF00) >>> 8); // Green level
p[3] = (int) (c & 0x000000FF); // Blue level
int nc = p[1] / 3 + p[2] / 3 + p[3] / 3;
// a little bit brighter
nc = nc / 2 + 127;
p[1] = nc;
p[2] = nc;
p[3] = nc;
int gc = (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]);
return gc;
}
getRGBは、アルファチャネルも含むカラー値を返します。したがって、配列内の各値を変更して、そこから画像を作成するだけで済みました。
nokiaフォーラムで役立つドキュメントを見つけました:MIDP 2.0:PixelsとdrawRGB()の操作
グレースケールへの変換に関するコードをありがとう。ただし、Nokia Series 40デバイスでは、このコードの実行がかなり遅いことに気付きました。
2つの最適化があります。主なものは、getGrayScale()で作成されたオブジェクトを削除することです。現在、すべてのピクセルに対して配列オブジェクトが作成されています。平均的な場合、たとえばQVGAの場合、76800個の配列オブジェクトが作成されたディスプレイは大量のゴミであり、おそらくGCを呼び出します。int [4]をクラスのフィールドとして定義すると、このオブジェクトの作成が削除されます。ここでのトレードオフは、クラスに使用される少量の追加RAMです。
2つ目は、幅と高さをgetGrayScaleImage()にキャッシュすることです。一部のデバイスでは、getWidth()およびgetHeight()のメソッド呼び出しは、最適化なしで繰り返し呼び出されます(JITコンパイラーは問題ありませんが、一部のインタープリターデバイスは問題ありません)。したがって、QVGAの場合も、getWidth()とgetHeight()はそれらの間で>150000と呼ばれます。
全体として、この変更されたバージョンははるかに高速に実行されたことがわかりました:-)
public Image getGrayScaleImage(Image screenshot) {
int width = getWidth();
int height = getHeight();
int screenSizeInPixels = (width * height);
int[] rgbData = new int[width * height];
image.getRGB(rgbData, 0, width, 0, 0, width, height);
for (int x = 0; x < screenSizeInPixels ; x++) {
rgbData[x] = getGrayScale(rgbData[x]);
}
Image grayImage = Image.createRGBImage(rgbData, width, height, true);
return grayImage;
}
static int[] p = new int[4];
private int getGrayScale(int c) {
p[0] = (int) ((c & 0xFF000000) >>> 24); // Opacity level
p[1] = (int) ((c & 0x00FF0000) >>> 16); // Red level
p[2] = (int) ((c & 0x0000FF00) >>> 8); // Green level
p[3] = (int) (c & 0x000000FF); // Blue level
int nc = p[1] / 3 + p[2] / 3 + p[3] / 3;
// a little bit brighter
nc = nc / 2 + 127;
p[1] = nc;
p[2] = nc;
p[3] = nc;
int gc = (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]);
return gc;
}
(クラスデータスペースを本当に使用したくない場合は、int []をスタック上に存在する4つの個別のローカルint変数に置き換えるだけです)