エンジニア

AndroidでViewのキャプチャを撮る

投稿日:2015年1月27日 更新日:

今回のエンジニアブログを担当させていただきます、佐藤です。

今回はAndroidで、Viewのキャプチャを撮る→保存→メールに添付ということをやって行こうと思います!

・まずはキャプチャを撮る部分

/**  
 * キャプチャを撮る  
 * @param 撮りたいview  
 * @return 撮ったキャプチャ(Bitmap)  
 */
public Bitmap getViewCapture(View view) {
    view.setDrawingCacheEnabled(true);

    // Viewのキャッシュを取得  
    Bitmap cache = view.getDrawingCache();
    Bitmap screenShot = Bitmap.createBitmap(cache);
    view.setDrawingCacheEnabled(false);
    return screenShot;
}

撮りたいViewのキャッシュを有効にして、キャッシュからBitmapを作成しています。

・撮ったキャプチャの保存

/**  
 * 撮ったキャプチャを保存  
 * @param view  
 * @param 書き込み先ファイルfile  
 */
public void saveCapture(View view, File file) {
    // キャプチャを撮る  
    Bitmap capture = getViewCapture(view);
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(file, false);
        // 画像のフォーマットと画質と出力先を指定して保存  
        capture.compress(CompressFormat.JPEG, 100, fos);
        fos.flush();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (fos != null) {
            try {
                fos.close();
            } catch (IOException ie) {
                fos = null;
            }
        }
    }
}

先ほど作成したのメソッドでViewのキャプチャを取得して、保存をしています。

FileOutputStreamのコンストラクタ第2引数でappendの指定ができます。
今回は上書きモードですが、trueにすることで追記モードにもできます。
また、保存する画像の形式はCompressFormat.JPEG,CompressFormat.PNG,CompressFormat.WEBPといった指定の仕方をします。

・保存したキャプチャをメールに添付する

// パスを指定してファイルを読み込む  
File file = new File(Environment.getExternalStorageDirectory() + "/capture.jpeg");

// メールアプリを起動  
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, new String[] {"example@mail.com"});
intent.setType("message/rfc822");
// 添付ファイルを指定  
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
startActivity(intent);

今回、添付する画像はストレージからじゃないと添付できないようなので、Environment.getExternalStorageDirectory()でストレージのパスを指定しています。

ストレージにアクセスするのでパーミッションの設定も忘れずにします。

AndroidManifest.xml

     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

これで画像のキャプチャ → 保存 → メールに添付ができました!

SendScreenShotActivity.java

import java.io.File;
import java.io.FileOutputStream;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class SendScreenShotActivity extends Activity implements OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 全体キャプチャ  
        Button captureAll = (Button)findViewById(R.id.capture_all);
        captureAll.setOnClickListener(this);

        // アイコン画像のみキャプチャ  
        Button captureIcon = (Button)findViewById(R.id.capture_icon);
        captureIcon.setOnClickListener(this);

        // キャプチャした画像を添付してメールを送る  
        Button sendMail = (Button)findViewById(R.id.send_mail);
        sendMail.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        // 読み書きするファイル名を指定  
        File file = new File(Environment.getExternalStorageDirectory() + "/capture.jpeg");
        // 指定したファイル名が無ければ作成する。  
        file.getParentFile().mkdir();

        switch(v.getId()) {
        case R.id.capture_all:
            // 全体を撮る  
            saveCapture(findViewById(android.R.id.content),file);
            break;
        case R.id.capture_icon:
            // View1を撮る  
            saveCapture(findViewById(R.id.icon),file);
            break;
        case R.id.send_mail:
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_SEND);
            intent.putExtra(Intent.EXTRA_EMAIL, new String[] {"hoge@mail.com"});
            intent.setType("message/rfc822");
            intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
            startActivity(intent);

            break;
        }
    }

    /**  
    * 撮ったキャプチャを保存  
    * @param view  
    * @param 書き込み先ファイルfile  
    */
    public void saveCapture(View view, File file) {
        // キャプチャを撮る  
        Bitmap capture = getViewCapture(view);
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file, false);
            // 画像のフォーマットと画質と出力先を指定して保存  
            capture.compress(CompressFormat.JPEG, 100, fos);
            fos.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException ie) {
                    fos = null;
                }
            }
        }
    }

    /**  
    * キャプチャを撮る  
    * @param 撮りたいview  
    * @return 撮ったキャプチャ(Bitmap)  
    */
    public Bitmap getViewCapture(View view) {
        view.setDrawingCacheEnabled(true);

        // Viewのキャプチャを取得  
        Bitmap cache = view.getDrawingCache();
        if(cache == null){
            return null;
        }
        Bitmap screenShot = Bitmap.createBitmap(cache);
        view.setDrawingCacheEnabled(false);
        return screenShot;
    }
}

activity_main.xml

<LinearLayout 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"  
    android:background="#ffffff"  
    android:gravity="center_horizontal"  
    android:orientation="vertical">

    <Button  
        android:id="@+id/capture_all"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:text="@string/capture_all"   
        android:padding="@dimen/activity_vertical_margin"/>

    <Button  
       android:id="@+id/capture_icon"  
       android:layout_width="wrap_content"  
       android:layout_height="wrap_content"  
       android:text="@string/capture_icon"  
       android:padding="@dimen/activity_vertical_margin" />

    <ImageView  
       android:id="@+id/icon"  
       android:layout_width="wrap_content"  
       android:layout_height="wrap_content"  
       android:src="@drawable/ic_launcher"  
       android:padding="@dimen/activity_vertical_margin"/>

    <Button  
       android:id="@+id/send_mail"  
       android:layout_width="wrap_content"  
       android:layout_height="wrap_content"  
       android:text="@string/send_mail"  
       android:padding="@dimen/activity_vertical_margin" />

</LinearLayout>

< 画面全体を撮ったときのキャプチャ >
capture
< アイコンのみ撮ったときのキャプチャ >
icon_capture

キャプチャを撮るViewにandroid.R.id.contentを指定すると表示されている全体のViewを取得することができます。
各Viewを指定すれば指定したView単体のキャプチャを取得できます。

Fileの読み書きが少しややこしく感じましたが、画面キャプチャが撮れるようになったので検証やシェア機能等に利用できそうだなと思いました!

採用情報

ワンダープラネットでは、一緒に働く仲間を幅広い職種で募集しております。

-エンジニア
-

© WonderPlanet Inc.