Androidの標準カメラで撮った画像をPOSTで送信する

2012-08-05#android

以下のような機能を実装したい。

0. 前提

1. SDカードが挿入されているか確認する

// PictureUtil.java

public static boolean isSdCardWritable {
    String state = Environment.getExternalStorageState();
    return state.equals(Environment.MEDIA_MOUNTED);
}

2. 標準カメラアプリを起動する

private static final int CAMERA_ACTIVITY_REQUEST_CODE = 100;
private Uri pictureUri;

public void onClick(View v) {
    if (!PictureUtil.isSdCardWritable()) {
        return; // (1)
    }

    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.TITLE, System.currentTimeMillis() + ".jpg");
    values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
    pictureUri = getContentResolver().insert(MediaStore.Images.Media.EXTRA_CONTENT_URI, values); // (2)

    Intent intent = new Intent();
    intent.setAction("android.media.action.IMAGE_CAPTURE");
    intent.putExtra(MediaStore.EXTRA_OUTPUT, pictureUri); // (3)
    startActivityForResult(intent, CAMERA_ACTIVITY_REQUEST_CODE);
}

3. 撮った画像を取得する

private Bitmap picture;
private final int TARGET_WIDTH = 300;
private final int TARGET_HEIGHT = 300;

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode != CAMERA_ACTIVITY_REQUEST_CODE || resultCode != RESULT_OK) {
        return;
    }

    if (pictureUri == null) {
        return; // (1)
    }

    try {
        InputStream is = getContentResolver().openInputStream(pictureUri);
        picture = BitmapFactory.decodeStream(is);
        picture = PictureUtil.resize(picture, TARGET_WIDTH, TARGET_HEIGHT); // (2)
        picture.recycle(); // (3)
    } catch (IOException e) {
        return;
    }
}

4. 画像を縮小する

// PictureUtil.java

private static Bitmap resize(Bitmap picture, int targetWidth, int targetHeight) {
    if (picture == null || height < 0 || width < 0) {
        return null;
    }

    int pictureWidth = picture.getWidth();
    int pictureHeight = picture.getHeight();
    float scale = Math.min((float) targetWidth / pictureWidth, (float) targetHeight / pictureHeight); // (1)

    Matrix matrix = new Matrix();
    matrix.postScale(scale, scale);
    
    return Bitmap.createBitmap(picture, 0, 0, pictureWidth, pictureHeight, matrix, true);
}

5. エンティティに画像データを追加してPOSTリクエストを送信する

public void onClick(View v) {
    if (picture.isRecycle()) { // (1)
        try {
            InputStream is = getContentResolver().openInputStream(pictureUri);
            picture = BitmapFactory.decodeStream(is);
            picture = PictureUtil.resize(picture, TARGET_WIDTH, TARGET_HEIGHT);
            picture.recycle();
        } catch (IOException e) {
            return;
        }
    }

    ByteArrayBody bab = PictureUtil.toByteArrayBody(picture); // (2)
    MultipartEntity requestEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
    requestEntity.addPart("picture", bab); // (3)
    requestEntity.addPart("string", new StringEntity("文字列"));
    // その他、送信したいデータを追加

    HttpClient client = new DefaultHttpClient();
    HttpPost request = new HttpPost("http://example.com");
    request.setEntity(requestEntity);

    // 以下、POSTリクエスト送信処理
}
// PictureUtil.java

private final int QUALITY = 100;

public static ByteArrayBody toByteArrayBody(Bitmap picture) {
    if (picture == null) {
        return null;
    }

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    picture.compress(CompressFormat.JPEG, QUALITY, bos); // (4)
    byte[] data = bos.toByteArray();
    return new ByteArrayBody(data, System.currentTimeMillis() + ".jpg");
}