

Androidで以下のように二つの画像を重ねる処理を書いているのですが、

[code]

    Bitmap imageA = loadImage();
    Bitmap imageB = loadImage();
    Bitmap output = Bitmap.createBitmap(width,height,Config.ARGB_8888);
    Canvas canvas = new Canvas(output);
    canvas.drawBitmap(imageA, 0, 0, null);
    canvas.drawBitmap(imageB, 0, 0, null);
    
[/code]

imageBの方を境界をぼかして重ねたいです。

## 合成イメージ

![合成イメージ](https://i.stack.imgur.com/zsF8S.jpg)

画像自体をぼかすのではなく、境界部分がなめらかに変化するようにしたいのです。  
imageAとimageBは下図の青枠がBitmapの大きさで、両方とも同じサイズです。  
背景は透明(`0x00000000`)で、色が乗っている箇所は完全に不透明(アルファ値は255)です。

[Bitmap.extractAlpha()](http://developer.android.com/reference/android/graphics/Bitmap.html#extractAlpha\(\))を上手く使えば良いらしいという記事を見かけましたが、使い方がよくわかりませんでした……


CC BY-SA 3.0
2015-04-23T07:38:02.603
9506
2015-08-02T20:09:44.193
450
question
android
Androidで画像合成するときに境界をぼかして重ねたい


画像系は得意ではないのですが面白そうなので試してみました。  
もっとスマートなやり方があると思います。

とりあえず思い浮かんだのが、画像の外側から内側へ透明度を変更しながら描画する方法です。  
この処理を行った画像と別の画像を重ねて見ても、それっぽく表示されました。  
繰り返し処理の値を変えれば、ぼかしの大きさなどを変えることも出来ると思います。

[code]

    private Bitmap feathering(Bitmap src) {
        int width = src.getWidth();
        int height = src.getHeight();
    
        Bitmap dst = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    
        Canvas canvas = new Canvas(dst);
        Paint paint = new Paint();
        for (int i = 1; i < 255; i++) {
            paint.setAlpha(i);
            Rect rect = new Rect(i, i, width - i, height - i);
            canvas.drawBitmap(src, rect, rect, paint);
        }
        return dst;
    }
    
[/code]

**追記です**  
すみません。質問をよく読んでいませんでした。  
青枠が画像の大きさだったのですね、、  
この回答は役に立ちません。。

**追記2**

力技ですがalpha値を見て不透明のエリアを絵の範囲としてぼかし処理を入れてみました。  
前提として、ぼかし処理を入れる部分は矩形である必要があります。  
こんな感じでいかがでしょうか？

[code]

    private void hoge() {
        // 後ろ側
        Bitmap img1 = BitmapFactory.decodeResource(getResources(), R.drawable.img1).copy(Bitmap.Config.ARGB_8888, true);
        // 表側（ぼかしを入れるほう）
        Bitmap img2 = BitmapFactory.decodeResource(getResources(), R.drawable.img2).copy(Bitmap.Config.ARGB_8888, true);
        imageView.setImageBitmap(margeBitmap(img1, img2));
    }
    
    private Bitmap margeBitmap(Bitmap img1, Bitmap img2) {
        int w = img1.getWidth();
        int h = img1.getHeight();
    
        IntBuffer buff = IntBuffer.wrap(new int[w * h]);
        img2.copyPixelsToBuffer(buff);
    
        Point p1 = new Point(0, 0);
        Point p2 = new Point(0, 0);
        boolean p1flg = false;
    
        // 不透明の一番最初と一番最後を取得
        for (int y = 0; y < h; y++) {
            for (int x = 0; x < w; x++) {
                int pixel = buff.get((y * w) + x);
                if ((pixel & 0xff000000) == 0xff000000) {
                    if (!p1flg) {
                        p1.set(x, y);
                        p1flg = true;
                    }
                    p2.set(x, y);
                }
            }
        }
    
        // img2の枠ぼかし処理
        Bitmap dst = img1.copy(Bitmap.Config.ARGB_8888, true);
        Canvas canvas = new Canvas(dst);
        Paint paint = new Paint();
        for (int i = 1; i < 255; i++) {
            paint.setAlpha(i);
            Rect rect = new Rect(i + p1.x, i + p1.y, p2.x - i, p2.y - i);
            canvas.drawBitmap(img2, rect, rect, paint);
        }
        return dst;
    }
    
[/code]


CC BY-SA 3.0
2015-04-28T02:36:58.840
9632
2015-04-28T08:33:21.630
2015-04-28T08:33:21.630
8216
8216
9506
answer


ブラーした画像をマスクする機能がありますので  
今回のような場合のような画像を標準APIだけで実現できるような気がします。

コード

[code]

    BlurMaskFilter filter1 = new　BlurMaskFilter(10,BlurMaskFilter.Blur.NORMAL);
    
    circle1.setMaskFilter(filter1);
    canvas.drawCircle(canvas.getWidth()/4, canvas.getHeight()*2/4, canvas.getWidth()/6, circle1);
    
[/code]

ブラーを内側にかけたり外側にかけたりは引数で変えられます。  
BlurMaskFilter.Blur.INNER  
BlurMaskFilter.Blur.OUTER  
BlurMaskFilter.Blur.SOLID

* * *

追記です。

画像に対してのぼかしだと自分の書いた方法 **だけだとダメ** みたいです。  
スタックオーバーフロー内にBitmap.extractAlpha()を用いた方法がありました。  
<https://stackoverflow.com/questions/3580051/how-to-prevent-androids-
drawbitmap-from-only-drawing-black-images>


CC BY-SA 3.0
2015-05-04T15:57:12.180
9824
2015-05-04T17:08:01.370
2017-05-23T12:38:55.250
-1
9552
9506
answer