Cómo configurar la imagen de salida use com.android.camera.action.CROP

Tengo código para recortar una imagen, como esto:

public void doCrop(){ Intent intent = new Intent("com.android.camera.action.CROP"); intent.setType("image/"); List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent,0); int size = list.size(); if (size == 0 ){ Toast.makeText(this, "Cant find crop app").show(); return; } else{ intent.setData(selectImageUri); intent.putExtra("outputX", 300); intent.putExtra("outputY", 300); intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); intent.putExtra("scale", true); intent.putExtra("return-data", true); if (size == 1) { Intent i = new Intent(intent); ResolveInfo res = list.get(0); i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name)); startActivityForResult(i, CROP_RESULT); } } } public void onActivityResult (int requestCode, int resultCode, Intent dara){ if (resultCode == RESULT_OK){ if (requestCode == CROP_RESULT){ Bundle extras = data.getExtras(); if (extras != null){ bmp = extras.getParcelable("data"); } File f = new File(selectImageUri.getPath()); if (f.exists()) f.delete(); Intent inten3 = new Intent(this, tabActivity.class); startActivity(inten3); } } } 

De lo que he leído, el código intent.putExtra("outputX", 300); intent.putExtra("outputY", 300); intent.putExtra("outputX", 300); intent.putExtra("outputY", 300); Se utiliza para establecer la resolución del resultado del cultivo, pero ¿por qué no puedo obtener el resultado de resolución de imagen de más de 300×300? Cuando establezco el intent.putExtra("outputX", 800); intent.putExtra("outputY", 800); intent.putExtra("outputX", 800); intent.putExtra("outputY", 800); La función de cultivo no tiene resultado o accidente, alguna idea para esta situación?

El gato del registro dice "!! FALLA LA TRANSACCIÓN DE LA CARTERA!"

Ese intento no forma parte de la API pública de Android y no garantiza su funcionamiento en todos los dispositivos. Se utilizó en versiones anteriores de android 1.xy 2.x, pero ya no se utiliza y no se recomienda. Eso es probablemente por qué se está estrellando por todo el palce o trabajando indebidamente.

Utilice métodos como Bitmap.createBitmap(..) o Bitmap.createScaledBitmap(..) para crear una versión redimensionada o recortada de su imagen original. Estos son parte de la API de Android y están garantizados para trabajar.

Ver documentos oficiales aquí y aquí

Para recortar un mapa de bits, puede utilizar Bitmap.createBitmap(Bitmap, int x, int y, int width, int height) . Por ejemplo, si necesita recortar 10 píxeles de cada lado de un mapa de bits, utilice esto:

 Bitmap croppedBitmap = Bitmap.createBitmap(originalBitmap, 10, 10, originalBitmap.getWidth() - 20, originalBitmap.getHeight() - 20); 

Si necesita mostrar el selector al usuario. Entonces usted puede hacer algo como esto:

 private static final String TEMP_PHOTO_FILE = "temporary_holder.jpg"; Intent photoPickerIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); photoPickerIntent.setType("image/*"); photoPickerIntent.putExtra("crop", "true"); photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri()); photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); startActivityForResult(photoPickerIntent, REQ_CODE_PICK_IMAGE); 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) { } return f; } else { return null; } } private boolean isSDCARDMounted(){ String status = Environment.getExternalStorageState(); if (status.equals(Environment.MEDIA_MOUNTED)) return true; return false; } protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) { super.onActivityResult(requestCode, resultCode, imageReturnedIntent); switch (requestCode) { case REQ_CODE_PICK_IMAGE: if (resultCode == RESULT_OK) { if (imageReturnedIntent!=null){ File tempFile = getTempFile(); String filePath= Environment.getExternalStorageDirectory() + "/temporary_holder.jpg"; System.out.println("path "+filePath); Bitmap selectedImage = BitmapFactory.decodeFile(filePath); _image = (ImageView) findViewById(R.id.image); _image.setImageBitmap(selectedImage ); } } } 

Código desde aquí

Esta pregunta está por encima de stackoverflow. Y me alegro de que es ya que tuve que resolver esto yo mismo recientemente. Voy a hacer mi mejor esfuerzo para marcar algunos duplicados como voy, pero prefiero este ya que aborda el problema con el tamaño de imagen limitada.

Respuesta corta

La respuesta corta es no utilizar la opción return-data. Lea más sobre esa opción y cómo recuperar la imagen, a continuación, aquí: http://www.androidworks.com/crop_large_photos_with_android . El artículo hace un gran trabajo enumerando las opciones de configuración (conocidas) para el Intent y cómo usarlas.

Opción # 2: Si establece return-data en "false", no recibirá un Bitmap desde el onActivityResult Intent en línea, en su lugar tendrá que configurar MediaStore.EXTRA_OUTPUT en un Uri Desea almacenar el mapa de bits. Esto tiene algunas restricciones, primero necesita tener una ubicación del sistema de archivos temporales para darle al esquema de archivos URI, no un gran problema (excepto en algunos dispositivos que no tienen sdcards).

  /** 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; } } 

Ejemplo de código desde: http://www.androidworks.com/crop_large_photos_with_android

Más información

La larga respuesta es no usar esa intención en absoluto. Continúe leyendo para averiguar por qué.

API no oficial

El núcleo del problema es la intención no oficial. No oficial como en no parte de la API pública. Actualmente funciona para la mayoría de los dispositivos, pero la mayoría no es suficiente. Google también puede cambiar esta intención en cualquier momento sin avisarle. Rompiendo con todas las aplicaciones que lo utilizan. Al igual que la API del calendario fue una vez no oficial. De hecho, esta intención del cultivo ya ha cambiado una vez. Así que evita usar esta intención. Hay alternativas. Siéntase libre de ignorar este consejo.

Solo para probar la declaración "funciona para algunos dispositivos", sigue este enlace y disfruta de los frustrados desarrolladores de Android que hablan de lo que debería considerarse parte de las principales funciones de Android (y no lo es): https://code.google.com/p/android / Issues / detail? Id = 1480

Hora para el código de ejemplo? Compruebe este proyecto github: https://github.com/lorensiuswlt/AndroidImageCrop

Acerca del límite de tamaño

Otro problema que experimenté al explorar esta intención es el límite de tamaño de cultivo de imagen. Esto se puede reproducir fácilmente utilizando el código de ejemplo anterior y un tamaño de imagen de cualquier elemento superior a 300 píxeles. Básicamente lo que esta pregunta original es todo. En el mejor de los casos, tu aplicación se bloqueará. Pero he visto peor hasta dispositivos colgantes que sólo se podía restablecer mediante la eliminación de la batería.

Ahora, si eliminas esa opción 'return-data', podrás volver a ejecutarla. Más información sobre cómo llegar al resultado se encuentra en la respuesta corta donde he hecho referencia a este enlace ya: http://www.androidworks.com/crop_large_photos_with_android

La solución

Así que muchos problemas. Los problemas requieren una solución. La única solución decente hasta que Google viene con una API pública para esto es para proporcionar su propia intención de cultivo. Sólo tienes tus manos en una biblioteca de cultivos adecuados como éste en github: https://github.com/lvillani/android-cropimage

El proyecto carece de documentación, pero dado que es un extracto de la intención de cultivos no oficiales de Android, puede utilizar los ejemplos enumerados en la parte superior para empezar. Sólo asegúrese de no utilizar la opción de devolución de datos. Ah y echa un vistazo a la clase CropImageIntentBuilder. Eso debería permitirle crear fácilmente una intención para el cultivo. No olvide agregar esta Actividad a su manifiesto y los permisos para escribir en el almacenamiento de datos externo.

 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); } 

El uso de esta biblioteca también abre las puertas a más personalización. Es bueno saber es el núcleo de mapa de bits utilizado funcionalmente para el cambio de tamaño: ¿Cómo recortar la imagen analizada en android?

Y eso es. ¡Disfrutar!

  • Encuentra color dominante en un marco de cámara en OpenCV Android
  • Procesamiento de imágenes en Android
  • ¿Podemos utilizar la clase EffectFactory para versiones inferiores
  • Cuadros de bits en escala de grises en android
  • Com.android.camera.action.CROP establece fondo de pantalla en Motorola Defy
  • Proyección posterior en Java con OpenCV
  • Fuera de memoria con imágenes en Android 5
  • Cómo fusionar imágenes e imponerse unas a otras
  • Implementación del efecto de pintura al óleo en android
  • Píxeles de la cámara girados
  • Android: BitmapFactory.decodeByteArray ofrece bitmap pixelado
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.