2014年11月24日月曜日

【Android】合成画像の保存

合成画像の保存方法

流れとしては
1.合成する画像をViewに表示
2.Viewから表示している画像の取得
3.ファイル保存

今回はプロ生ちゃんを合成してみます
合成前


合成後

画像を表示するViewのソースコードを以下に示します。
今回はサンプルなのでテキトーにonDrawwの中でBitmap作成して合成しています。

public class PictureView extends View{
    private Bitmap mPronamaSummer;
    private Bitmap mPronama;
    private Resources res;

    public PictureView(Context context){
        super(context);

        //画像の読み込み
        res = context.getResources();
    }

    @Override
    public void onDraw(Canvas canvas){
        mPronamaSummer = BitmapFactory.decodeResource(res, R.drawable.pronamachan_summer);
        mPronama = BitmapFactory.decodeResource(res, R.drawable.pronamachan);
        //Bitmapの縮小と描画
        int w = mPronamaSummer.getWidth();
        int h = mPronamaSummer.getHeight();
        Rect src = new Rect(0, 0, w, h);
        Rect dst = new Rect(0, 0, canvas.getWidth(), canvas.getHeight());
        Paint paint = new Paint();
        paint.setAlpha(128);
        canvas.drawBitmap(mPronamaSummer, src, dst, paint);
        canvas.drawBitmap(mPronama, src, dst, paint);
    }

    public Bitmap getImage(){
        this.setDrawingCacheEnabled(true);
        Bitmap image = Bitmap.createBitmap(getDrawingCache());
        return image;
    }

    public void save(Bitmap bitmap){
        //ファイル保存
        try {
            //出力ファイルを準備
            FileOutputStream fos = new FileOutputStream("/sdcard/sample.jpg");
            //JPG形式で出力
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

1.と3については難しくないと思います。
2.Viewから表示している画像の取得でハマったのでここを説明します。
2を行っているのは以下の部分

    public Bitmap getImage(){
        this.setDrawingCacheEnabled(true);
        Bitmap image = Bitmap.createBitmap(getDrawingCache());
        return image;
    }


getDrawingChache()で表示している画像を取得し、Bitmapを作成しています。
ここで注意が必要なのが、setDrawingChacheEnableをtrueにしないと
getDrawChacheでNullPointerExceptionが発生してしまいます。

後はBitmapを保存するだけです。
今回はActivityのOptionMenyから保存を行えるようにしてあります。
@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }else if(id == R.id.action_save){
            mPictureView.save(mPictureView.getImage());
        }
        return super.onOptionsItemSelected(item);
    }


以上です。