5

2 つの画像 (この場合は HardLight) にブレンド フィルターを適用しようとしています。HardLight はベースの Android ライブラリではサポートされていないため、ピクセルごとに手作業で行っています。最初の実行は機能していますが、速度は優れていません。ベースの 500x500 画像と 500x500 フィルターから 500x500 画像を生成すると、時間がかかりすぎます。このコードのチャンクは、サムネイル (72x72) の生成にも使用され、アプリケーションのコアに不可欠です。これをスピードアップする方法について、アドバイスやヒントをいただければ幸いです。

どちらの画像もアルファを持たないと仮定することで大きな利益が得られるのであれば、それで問題ありません。: BlendMode と alpha は、この例では使用されていない値です (BlendMode はブレンドのタイプを選択します。この場合、HardLight をハードコードしました)。

public Bitmap blendedBitmap(Bitmap source, Bitmap layer, BlendMode blendMode, float alpha) {
    Bitmap base = source.copy(Config.ARGB_8888, true);
    Bitmap blend = layer.copy(Config.ARGB_8888, false);

    IntBuffer buffBase = IntBuffer.allocate(base.getWidth() * base.getHeight());
    base.copyPixelsToBuffer(buffBase);
    buffBase.rewind();

    IntBuffer buffBlend = IntBuffer.allocate(blend.getWidth() * blend.getHeight());
    blend.copyPixelsToBuffer(buffBlend);
    buffBlend.rewind();

    IntBuffer buffOut = IntBuffer.allocate(base.getWidth() * base.getHeight());
    buffOut.rewind();

    while (buffOut.position() < buffOut.limit()) {
        int filterInt = buffBlend.get();
        int srcInt = buffBase.get();

        int redValueFilter = Color.red(filterInt);
        int greenValueFilter = Color.green(filterInt);
        int blueValueFilter = Color.blue(filterInt);

        int redValueSrc = Color.red(srcInt);
        int greenValueSrc = Color.green(srcInt);
        int blueValueSrc = Color.blue(srcInt);

        int redValueFinal = hardlight(redValueFilter, redValueSrc);
        int greenValueFinal = hardlight(greenValueFilter, greenValueSrc);
        int blueValueFinal = hardlight(blueValueFilter, blueValueSrc);

        int pixel = Color.argb(255, redValueFinal, greenValueFinal, blueValueFinal);

        buffOut.put(pixel);
    }

    buffOut.rewind();

    base.copyPixelsFromBuffer(buffOut);
    blend.recycle();

    return base;
}

private int hardlight(int in1, int in2) {
    float image = (float)in2;
    float mask = (float)in1;
    return ((int)((image < 128) ? (2 * mask * image / 255):(255 - 2 * (255 - mask) * (255 - image) / 255)));

}
4

3 に答える 3

2

Android については特に何も言えませんが、浮動小数点演算は一般に整数演算よりも低速です。hardlight操作が整数として完全に機能するように見えるのに、なぜ入力を浮動小数点に変換するのだろうか?

関数を呼び出すのではなく、数式をインラインでループに入れることによっても高速化される場合があります。そうではないかもしれませんが、試してベンチマークする価値はあります。

于 2011-01-12T16:59:51.233 に答える
1

また、最終的な画質/精度の 3 ビット/ピクセルを犠牲にすることができれば、ビット単位の演算子で書き直すことにより、関数hardlight()で約 25% のパフォーマンス向上を達成できます。

int hardlight(int image, int mask) {
    return (((image < 128) ? 
           ( (((mask << 1) * image) >> 8) ):
           (255^( (((255^mask) << 1) * (255^image)) >> 8))));
}
于 2011-01-13T14:26:11.907 に答える
0

しばらく前にこのような質問がありました (リンク)。OPが彼の問題を解決したかどうかはわかりません。

私の場合、「Photoshop ブレンド」を実現するために行ったことは、単色に半透明のシャドウ オーバーレイを適用することでした。グラフィック デザイナーがシャドウ オーバーレイの方法を考え出すだけの問題でした。それはうまく機能し、ビットマップ内のピクセルを反復処理する必要があるという問題を完全に無視しました (私は getPixels() と setPixels() を使用していました)。大変だったのは本当に私のデザイナー側でしたが、彼はそれを理解すると、見栄えの良い画像を数多く生成してくれました。

基本的に、シャドウ オーバーレイでアルファ マスク (動的な色を生成するため) を使用しました。コードによる解決策について学びたいと思いますので、頑張ってください!

編集: また、私は BlendMode に慣れていません。メソッドで使用したことはありません。これは何ですか、カスタム クラスですか。

于 2011-01-12T16:48:23.940 に答える