web-dev-qa-db-ja.com

Android:ビットマップをオーバーレイしてビットマップ上に描画する方法は?

私は実際に3つの質問があります:

  1. ビットマップ上に画像を描画するか、リソースとしてビットマップを作成してからビットマップ上に描画する方が良いですか?パフォーマンスに関しては、どちらが優れていますか?
  2. ビットマップの上に透明なものを描きたい場合、どうすればいいですか?
  3. 透明なビットマップを別のビットマップにオーバーレイしたい場合、どうすればよいですか?

長いリストで申し訳ありませんが、学習のために、両方のアプローチを検討したいと思います。

56
Legend

誰もまだこれに答えていないなんて信じられない! SOでのまれな発生!

1

質問は私にはまったく意味がありません。しかし、私はそれに刺します。キャンバスへの直接描画(ポリゴン、シェーディング、テキストなど)を求めている場合と、ビットマップを読み込んでキャンバスにブリットする場合は、描画の複雑さに依存します。描画がより複雑になると、それに応じて必要なCPU時間は増加します。ただし、ビットマップをキャンバスにブリットすることは常にビットマップのサイズに比例する一定時間です。

2

「何か」が何であるかを知らずに、どうすればそれを行うことができますか? #3の答えから#2がわかるはずです。

3

仮定:

  • bmp1はbmp2よりも大きいです。
  • 両方を左上隅からオーバーレイする必要があります。

        private Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
            Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
            Canvas canvas = new Canvas(bmOverlay);
            canvas.drawBitmap(bmp1, new Matrix(), null);
            canvas.drawBitmap(bmp2, new Matrix(), null);
            return bmOverlay;
        }
    
104
Declan Shanaghy

次のようなことができます:

public void putOverlay(Bitmap bitmap, Bitmap overlay) {
    Canvas canvas = new Canvas(bitmap);
    Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
    canvas.drawBitmap(overlay, 0, 0, Paint);
} 

考え方は非常に簡単です。ビットマップをキャンバスに関連付けると、キャンバスのメソッドを呼び出してビットマップ上に描画できます。

これは、透明度のあるビットマップに対して機能します。ビットマップにアルファチャネルがある場合、ビットマップは透明になります。 Bitmap.Config を見てください。おそらくARGB_8888を使用したいでしょう。

重要: this Android描画を実行できるさまざまな方法のサンプルをご覧ください。これは非常に役立ちます。

パフォーマンスに関して(正確にはメモリに関して)、ビットマップは、ネイティブビットマップを単純にラップするため、使用するのに最適なオブジェクトです。 ImageViewはViewのサブクラスであり、BitmapDrawableはビットマップを内部に保持しますが、他にも多くのものを保持します。しかし、これは過度に単純化されています。正確な回答を得るために、パフォーマンス固有のシナリオを提案できます。

29
Lior
public static Bitmap overlayBitmapToCenter(Bitmap bitmap1, Bitmap bitmap2) {
    int bitmap1Width = bitmap1.getWidth();
    int bitmap1Height = bitmap1.getHeight();
    int bitmap2Width = bitmap2.getWidth();
    int bitmap2Height = bitmap2.getHeight();

    float marginLeft = (float) (bitmap1Width * 0.5 - bitmap2Width * 0.5);
    float marginTop = (float) (bitmap1Height * 0.5 - bitmap2Height * 0.5);

    Bitmap overlayBitmap = Bitmap.createBitmap(bitmap1Width, bitmap1Height, bitmap1.getConfig());
    Canvas canvas = new Canvas(overlayBitmap);
    canvas.drawBitmap(bitmap1, new Matrix(), null);
    canvas.drawBitmap(bitmap2, marginLeft, marginTop, null);
    return overlayBitmap;
}
13
AnsonChen

この例は、透明な画像を別の画像の上に重ねるのに間違いなく役立つと思います。これは、キャンバスに画像を描画し、ビットマップ画像を返すことで可能になります。

続きを読むまたはデモをダウンロード here

private Bitmap createSingleImageFromMultipleImages(Bitmap firstImage, Bitmap secondImage){

        Bitmap result = Bitmap.createBitmap(firstImage.getWidth(), firstImage.getHeight(), firstImage.getConfig());
        Canvas canvas = new Canvas(result);
        canvas.drawBitmap(firstImage, 0f, 0f, null);
        canvas.drawBitmap(secondImage, 10, 10, null);
        return result;
    }

ボタンのクリックで上記の関数を呼び出し、以下に示すように2つの画像を関数に渡します

public void buttonMerge(View view) {

        Bitmap bigImage = BitmapFactory.decodeResource(getResources(), R.drawable.img1);
        Bitmap smallImage = BitmapFactory.decodeResource(getResources(), R.drawable.img2);
        Bitmap mergedImages = createSingleImageFromMultipleImages(bigImage, smallImage);

        img.setImageBitmap(mergedImages);
    }

3つ以上の画像については、このリンクをたどることができます Androidで複数の画像をプログラムでマージする方法

1
Daniel Nyamasyo

ビットマップを取得することが目的の場合、これは非常に簡単です。

Canvas canvas = new Canvas();
canvas.setBitmap(image);
canvas.drawBitmap(image2, new Matrix(), null);

最終的に、imageにはimageとimage2の重複が含まれます。

1
public static Bitmap createSingleImageFromMultipleImages(Bitmap firstImage, Bitmap secondImage, ImageView secondImageView){

    Bitmap result = Bitmap.createBitmap(firstImage.getWidth(), firstImage.getHeight(), firstImage.getConfig());
    Canvas canvas = new Canvas(result);
    canvas.drawBitmap(firstImage, 0f, 0f, null);
    canvas.drawBitmap(secondImage, secondImageView.getX(), secondImageView.getY(), null);

    return result;
}
0
Svitlana