この質問は、stackoverflow全体にあります。そして、最近自分でこれを整理しなければならなかったので、それはうれしいです。私は行くにつれていくつかの重複をマークするために最善を尽くしますが、限られた画像サイズの問題に対処するので、これを好みます。
短い答え
簡単な答えは、return-dataオプションを使用しないことです。そのオプションと画像を取得する方法の詳細については、http ://www.androidworks.com/crop_large_photos_with_androidをご覧ください。この記事は、インテントの(既知の)構成オプションとその使用方法をリストした素晴らしい仕事をしています。
オプション#2:return-dataを "false"に設定すると、onActivityResult Intentインラインからビットマップを受信しなくなります。代わりに、MediaStore.EXTRA_OUTPUTを(ファイルスキームのみの)URIに設定する必要があります。ビットマップを保存する必要があります。これにはいくつかの制限があります。最初に、ファイルスキームURIを指定するために、一時ファイルシステムの場所が必要です。大きな問題ではありません(sdcardがない一部のデバイスを除く)。
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
thiz = this;
setContentView(R.layout.main);
mBtn = (Button) findViewById(R.id.btnLaunch);
photo = (ImageView) findViewById(R.id.imgPhoto);
mBtn.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
try {
// Launch picker to choose photo for selected contact
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType("image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", aspectX);
intent.putExtra("aspectY", aspectY);
intent.putExtra("outputX", outputX);
intent.putExtra("outputY", outputY);
intent.putExtra("scale", scale);
intent.putExtra("return-data", return_data);
intent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection",!faceDetection); // lol, negative boolean noFaceDetection
if (circleCrop) {
intent.putExtra("circleCrop", true);
}
startActivityForResult(intent, PHOTO_PICKED);
} catch (ActivityNotFoundException e) {
Toast.makeText(thiz, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show();
}
}
});
}
private Uri getTempUri() {
return Uri.fromFile(getTempFile());
}
private File getTempFile() {
if (isSDCARDMounted()) {
File f = new File(Environment.getExternalStorageDirectory(),TEMP_PHOTO_FILE);
try {
f.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
Toast.makeText(thiz, R.string.fileIOIssue, Toast.LENGTH_LONG).show();
}
return f;
} else {
return null;
}
}
private boolean isSDCARDMounted(){
String status = Environment.getExternalStorageState();
if (status.equals(Environment.MEDIA_MOUNTED))
return true;
return false;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case PHOTO_PICKED:
if (resultCode == RESULT_OK) {
if (data == null) {
Log.w(TAG, "Null data, but RESULT_OK, from image picker!");
Toast.makeText(this, R.string.no_photo_picked,
Toast.LENGTH_SHORT).show();
return;
}
final Bundle extras = data.getExtras();
if (extras != null) {
File tempFile = getTempFile();
// new logic to get the photo from a URI
if (data.getAction() != null) {
processPhotoUpdate(tempFile);
}
}
}
break;
}
}
コード例:http ://www.androidworks.com/crop_large_photos_with_android
詳しくは
長い答えは、その意図をまったく使用しないことです。理由を見つけるために読み続けてください。
非公式API
問題の核心は非公式の意図です。パブリックAPIの一部ではないため非公式。現在、ほとんどのデバイスで機能しますが、ほとんどのデバイスでは十分ではありません。また、Googleはあなたに通知することなくいつでもこの意図を変更することができます。それを使用してすべてのアプリを壊します。カレンダーAPIがかつて非公式だったのと同じように。実際、この作物の意図はすでに一度変わっています。したがって、このインテントの使用は避けてください。選択肢があります。このアドバイスは無視してかまいません。
「一部のデバイスで動作するステートメント」を証明するために、このリンクをたどって、Androidのコア機能の一部と見なす必要があるもの(そうでないもの)について話し合う欲求不満のAndroid開発者をお楽しみください:https ://code.google.com/p/android / issues / detail?id = 1480
コードの例の時間?このgithubプロジェクトを確認してください:https ://github.com/lorensiuswlt/AndroidImageCrop
サイズ制限について
この意図を探求しているときに私が経験したもう1つの問題は、画像のトリミングサイズの制限です。これは、上記のサンプルコードと300ピクセルを超える画像サイズを使用して簡単に再現できます。基本的に、この元の質問はすべてについてです。最良の場合、アプリはクラッシュします。しかし、バッテリーを取り外すことによってのみリセットできるデバイスがぶら下がっているところまで悪化しました。
これで、その「return-data」オプションを削除すると、再度実行できるようになります。結果を得る方法の詳細は、私がすでにこのリンクを参照した短い回答にあります:http ://www.androidworks.com/crop_large_photos_with_android
ソリューション
だから多くの問題。問題には解決策が必要です。GoogleがこのためのパブリックAPIを思い付くまでの唯一の適切な解決策は、独自の作物の意図を提供することです。githubでこのような適切な作物ライブラリを手に入れてください:https ://github.com/lvillani/android-cropimage
プロジェクトにはいくつかのドキュメントがありませんが、非公式のAndroidトリミングインテントの抜粋であるため、上にリストされている例を使用して開始できます。return-dataオプションを使用しないように注意してください。ああ、CropImageIntentBuilderクラスをチェックしてください。これにより、トリミングのインテントを簡単に作成できるようになります。このアクティビティをマニフェストに追加し、外部データストレージに書き込むためのアクセス許可を追加することを忘れないでください。
private void doCrop(File croppedResult){
CropImageIntentBuilder builder = new CropImageIntentBuilder(600,600, croppedResult);
// don't forget this, the error handling within the library is just ignoring if you do
builder.setSourceImage(mImageCaptureUri);
Intent intent = builder.getIntent(getApplicationContext());
// do not use return data for big images
intent.putExtra("return-data", false);
// start an activity and then get the result back in onActivtyResult
startActivityForResult(intent, CROP_FROM_CAMERA);
}
このライブラリを使用すると、さらにカスタマイズできるようになります。コアビットマップはサイズ変更に機能的に使用されていることを知っておくとよいでしょう:Androidで解析された画像をトリミングする方法は?
以上です。楽しみ!