大きい画像だとうまく動かない
トリミング機能をintentで呼び出そうと思い「android トリミング intent」でググったら大体以下のようなサンプルが出てくる。
Intent intent = new Intent("com.android.camera.action.CROP"); intent.setData(uri); // トリミングに渡す画像パス intent.putExtra("outputX", 200); // トリミング後の画像の幅 intent.putExtra("outputY", 200); // トリミング後の画像の高さ intent.putExtra("aspectX", 1); // トリミング後の画像のアスペクト比(X) intent.putExtra("aspectY", 1); // トリミング後の画像のアスペクト比(Y) intent.putExtra("scale", true); // トリミング中の枠を拡大縮小させるか intent.putExtra("return-data", true); // トリミングしたデータを返すよ startActivityForResult(intent, REQUEST_CROP_PICK);
これでトリミング機能を呼び出すことが出来て、以下のように返却されたデータを受け取れる。
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQUEST_GET_CONTENT: break; case REQUEST_CROP_PICK: Bitmap bitmap = data.getExtras().getParcelable("data"); } }
これで動くには動く。
ただ問題があって大きい画像を扱うと何も返ってこなくなる・・・。
例えば壁紙用にoutpuX、outputYに480、800とか指定すると動かない。
調べてみた
でも壁紙設定アプリでは出来てるわけだから何か方法があるはず。
ってことで調べてみた。
壁紙設定アプリではこのパッケージを呼び出してたので、そのソースを見れば解決する(はず)。
com.cooliris.media.CropImage
調べた結果
カメラ扱う時も同じ(だったと思う)だけど、intentに大きい画像渡すと動かない。
ので、トリミング機能に「データを返せ」ではなく「データを保存してくれ」と指示して解決。
トリミングはOSのバージョンによって呼ぶものが変わるっぽい。
その部分のソースはどこかからコピペしたんですが、引用元がどこだか分からなくなった・・・。
ただGalaxyNexusでは動かなかったので、パッケージを追加してあります。
サンプル
下にギャラリーで画像を選択して、トリミングした画像をSDカードに保存した後に画面に表示するサンプルを(エラーハンドリングとか適当)。
package goodspeed.jp.ne.hatena.d.cropimage; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import android.app.Activity; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.widget.ImageView; public class ImageCropSampleActivity extends Activity { private static final int PICK_PICUTER = 0; private static final int CROP_IMAGE = 1; private File mFile; private ImageView mImageView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mImageView = (ImageView)findViewById(R.id.image); // ギャラリー呼び出し Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_PICK); startActivityForResult(intent, PICK_PICUTER); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == PICK_PICUTER && resultCode == RESULT_OK) { // ギャラリーで選択されたファイルパス Uri uri = data.getData(); // トリミングがいくつかあるようなので、使えるものを使う PackageManager pm = this.getPackageManager(); List<ApplicationInfo> list = pm.getInstalledApplications(0); String[] apps = {"com.android.gallery", "com.cooliris.media", "com.google.android.gallery3d"}; String[] clss = {"com.android.camera.CropImage", "com.cooliris.media.CropImage", "com.android.gallery3d.app.CropImage"}; int classtype = -1; for (ApplicationInfo ai : list) { String s1 = ai.packageName; if (apps[0].equals(s1)) { classtype = 0; } if (apps[1].equals(s1)) { classtype = 1; } if (apps[2].equals(s1)) { classtype = 2; } } // トリミング呼び出し Intent intent = new Intent(); if (classtype >= 0) { // 適当に保存するところ作る Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); String filename = sdf.format(date)+".png"; String dirPath = Environment.getExternalStorageDirectory().getPath()+"/"+getString(R.string.app_name); File dir = new File(dirPath); if(!dir.exists()){ if(!dir.mkdirs()){ // ディレクトリ作れなかった } } // 先にファイルを用意しておいて、トリミングさんにそこに保存してくれるように頼む mFile = new File(dirPath+"/"+filename); intent.setClassName(apps[classtype], clss[classtype]); intent.setData(uri); intent.putExtra("outputX", 800); intent.putExtra("outputY", 800); intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); intent.putExtra("scale", true); intent.putExtra("noFaceDetection", true); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mFile)); intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.name()); startActivityForResult(intent, CROP_IMAGE); } else { // トリミング機能呼び出し失敗 } } if (requestCode == CROP_IMAGE && resultCode == RESULT_OK){ // トリミングした画像を表示 InputStream inputStream; try { inputStream = new FileInputStream(mFile); Bitmap bitmap = BitmapFactory.decodeStream(inputStream); mImageView.setImageBitmap(bitmap); } catch (FileNotFoundException e) { // ファイルがなかった } } } }


