Androidで画像合成
Androidアプリ作成中に画像合成が必要になったので、画像合成方法についてまとめていきます。
方法としては下記2つの方法があります。
・2つの画像を重ねて表示させる
・2枚の画像を合成して1枚の画像にする
今回は、今後のことを考えて合成に挑戦しています。
「メイン画面」は合成元の2枚の写真を表示して、合成ボタンを押すことで合成した画像がポップアップ表示される単純なサンプルを作成しました。
メイン画面
ポップアップダイアログ
① まずはメイン画面を作成します
1)レイアウトファイル(fragment_main.xml)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivityFragment"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:text="最下層のレイヤー画像" android:id="@+id/textView" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:gravity="center_horizontal" /> <ImageView android:layout_width="200dp" android:layout_height="139dp" android:layout_marginTop="10dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:id="@+id/imageView" android:background="@drawable/base" android:layout_gravity="center_horizontal" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:text="写真フレーム画像" android:id="@+id/textView2" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:gravity="center_horizontal" /> <ImageView android:layout_width="200dp" android:layout_height="139dp" android:layout_marginTop="10dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:id="@+id/imageView2" android:background="@drawable/frame" android:layout_gravity="center_horizontal" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="合成" android:id="@+id/button" android:onClick="onClickComposition" /> </LinearLayout> </RelativeLayout>
2)MainActivity.java
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Window varWindow = getWindow(); varWindow.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); getSupportActionBar().hide(); setContentView(R.layout.activity_main); } // ボタン押下時の処理 public void onClickComposition(View view) { PopupDialogFlagment popupDialogFlagment = new PopupDialogFlagment(); popupDialogFlagment.show(getSupportFragmentManager(), "CompositionBitmapDialog"); } }
② 次にポップアップ画面を作成します。ポップアップ画面作成時に2つの画像を合成してImageViewに表示するように処理を書いてあります。
1) レイアウトファイル(popuplayout.xml)
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- コンテンツ --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_marginTop="6dp" android:layout_marginLeft="6dp" android:layout_marginRight="6dp" android:background="#d8d8d8" android:gravity="center_horizontal" android:orientation="vertical" android:weightSum="1" android:id="@+id/linearLayout2"> <!-- タイトル --> <TableLayout android:layout_width="match_parent" android:layout_height="match_parent" android:stretchColumns="0"> <TableRow android:layout_width="match_parent" android:layout_height="match_parent" android:background="#FFFFFF"> <ImageView android:layout_width="300dp" android:layout_height="209dp" android:id="@+id/imageView3" android:layout_gravity="center" android:layout_marginTop="30dp" android:layout_marginBottom="30dp" /> </TableRow> </TableLayout> <Button android:id="@+id/ok_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FFFFFF" android:layout_marginTop="1dp" android:text="OK" android:textColor="@android:color/black" /> </LinearLayout> </RelativeLayout>
2) PopupDialogFlagment.java
public class PopupDialogFlagment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { Dialog dialog = new Dialog(getActivity()); // タイトル非表示 dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE); // フルスクリーン dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN); // layoutの読み込み dialog.setContentView(R.layout.popuplayout); // 背景を透明にする dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); // Bitmap合成 // Bitmapの枠を作成 Bitmap baseBitmap = Bitmap.createBitmap(400, 278, Bitmap.Config.ARGB_8888); // BaseになるBitmapの生成 Canvas canvas = new Canvas(baseBitmap); // 表示画面の取得 & 設定 Bitmap baseImage = BitmapFactory.decodeResource(getResources(), R.drawable.base); baseImage = Bitmap.createScaledBitmap(baseImage, 400, 278, false); canvas.drawBitmap(baseImage, 0, 0, null); Bitmap frameBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.frame); frameBitmap = Bitmap.createScaledBitmap(frameBitmap, 400, 278, false); canvas.drawBitmap(frameBitmap, 0, 0, null); ((ImageView)dialog.findViewById(R.id.imageView3)).setImageBitmap(baseBitmap); // OK ボタンのリスナ dialog.findViewById(R.id.ok_button).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { dismiss(); } }); // Dialogを返す return dialog; } }
画像合成は部分の実装は以下の通りです。
ベースになるビットマップを用意して、画像をどんどん追加していきます。
Bitmap baseImage = BitmapFactory.decodeResource(getResources(), R.drawable.base); baseImage = Bitmap.createScaledBitmap(baseImage, 400, 278, false); canvas.drawBitmap(baseImage, 0, 0, null); Bitmap frameBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.frame); frameBitmap = Bitmap.createScaledBitmap(frameBitmap, 400, 278, false); canvas.drawBitmap(frameBitmap, 0, 0, null); ((ImageView)dialog.findViewById(R.id.imageView3)).setImageBitmap(baseBitmap);
こんな感じで簡単に画像合成が行えます。皆さんも挑戦してみてください。