質問

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は、アルファチャネルも含まれる色値を返します。そのため、配列内の各値を変更して、そこから画像を作成するだけでした。

ノキアフォーラムで有用な文書を見つけました。 MIDP 2.0:ピクセルとdrawrgb()での作業

他のヒント

GreyScaleに変換するコードをありがとう。ただし、Nokiaシリーズ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変数に置き換えます)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top