una tomar samsung por pantallazo pantalla mano mandar hacer desde con como celular captura android image filesize android-camera-intent onactivityresult

android - tomar - como mandar un pantallazo por whatsapp



Android reduce el tamaño del archivo para que la imagen capturada por la cámara sea inferior a 500 kb (8)

Mi requisito es cargar la imagen de la cámara en el servidor, pero debe ser inferior a 500 KB. En el caso, si es superior a 500 KB, debe reducirse al tamaño inferior a 500 KB (pero un poco más cerca)

Para esto, estoy usando el siguiente código -

@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { try { super.onActivityResult(requestCode, resultCode, data); if (resultCode == getActivity().RESULT_OK) { if (requestCode == REQUEST_CODE_CAMERA) { try { photo = MediaStore.Images.Media.getBitmap( ctx.getContentResolver(), capturedImageUri); String selectedImagePath = getRealPathFromURI(capturedImageUri); img_file = new File(selectedImagePath); Log.d("img_file_size", "file size in KBs (initially): " + (img_file.length()/1000)); if(CommonUtilities.isImageFileSizeGreaterThan500KB(img_file)) { photo = CommonUtilities.getResizedBitmapLessThan500KB(photo, 500); } photo = CommonUtilities.getCorrectBitmap(photo, selectedImagePath); // // CALL THIS METHOD TO GET THE URI FROM THE BITMAP img_file = new File(ctx.getCacheDir(), "image.jpg"); img_file.createNewFile(); //Convert bitmap to byte array ByteArrayOutputStream bytes = new ByteArrayOutputStream(); photo.compress(Bitmap.CompressFormat.JPEG, 100, bytes); //write the bytes in file FileOutputStream fo = new FileOutputStream(img_file); fo.write(bytes.toByteArray()); // remember close de FileOutput fo.close(); Log.d("img_file_size", "file size in KBs after image manipulations: " + (img_file.length()/1000)); } catch (Exception e) { Logs.setLogException(class_name, "onActivityResult(), when captured from camera", e); } } } } catch (Exception e) { Logs.setLogException(class_name, "onActivityResult()", e); } catch (OutOfMemoryError e) { Logs.setLogError(class_name, "onActivityResult()", e); } }

Y

public static Bitmap getResizedBitmapLessThan500KB(Bitmap image, int maxSize) { int width = image.getWidth(); int height = image.getHeight(); float bitmapRatio = (float)width / (float) height; if (bitmapRatio > 0) { width = maxSize; height = (int) (width / bitmapRatio); } else { height = maxSize; width = (int) (height * bitmapRatio); } Bitmap reduced_bitmap = Bitmap.createScaledBitmap(image, width, height, true); if(sizeOf(reduced_bitmap) > (500 * 1000)) { return getResizedBitmap(reduced_bitmap, maxSize); } else { return reduced_bitmap; } }

Para rotar la imagen, si es necesario.

public static Bitmap getCorrectBitmap(Bitmap bitmap, String filePath) { ExifInterface ei; Bitmap rotatedBitmap = bitmap; try { ei = new ExifInterface(filePath); int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); Matrix matrix = new Matrix(); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: matrix.postRotate(90); break; case ExifInterface.ORIENTATION_ROTATE_180: matrix.postRotate(180); break; case ExifInterface.ORIENTATION_ROTATE_270: matrix.postRotate(270); break; } rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return rotatedBitmap; }

Aquí está la salida del tamaño del archivo de imagen inicialmente y después de todas las operaciones para reducir el tamaño del archivo.

img_file_size size tamaño de archivo en KB (inicialmente): 3294

img_file_size size tamaño de archivo en KBs después de manipulaciones de imagen: 235

Ver la diferencia arriba (en la salida). El tamaño del archivo inicial sin esas operaciones, y después de esas operaciones de compresión y otras. Necesito ese tamaño para estar un poco más cerca de 500 kb.

El código anterior funciona bastante bien para mí, ya que reduce el tamaño del archivo de imagen para que sea inferior a 500 KB.

Pero, los siguientes son los problemas con el código anterior :

  • Este código está reduciendo el tamaño del archivo incluso si es inferior a 500 KB

  • En caso de que sea más de 500 KB, el tamaño reducido del archivo se vuelve muy inferior a 500 KB, aunque lo necesito un poco más cerca.

Necesito deshacerme de más de 2 temas. Entonces, necesito saber qué debo manipular en el código anterior.

Como también quiero corregir la orientación EXIF ​​(imágenes rotadas), junto con mi requisito mencionado anteriormente.


Esta no es la solución para su problema, sino el error por el que obtiene archivos muy pequeños.

En getResizedBitmapLessThan500KB(photo, 500) el 500 es el máximo con / altura en píxeles de la imagen, no el tamaño máximo en kb.

Así que todos los archivos comprimidos son menos de 500x500 píxeles


Otro problema que tiene es que está midiendo el tamaño del mapa de bits (que no está comprimido), y luego lo convierte a JPG y lo mide. Probablemente, el JPG siempre será más pequeño, y el grado de compresión será un factor de lo que es la imagen. ¿Muchas zonas grandes del mismo color? ¡Genial! ¿Un patrón extremadamente "ocupado"? La compresión no será tan buena.

OK, para mayor aclaración:

Si está apuntando a un determinado tamaño de archivo, no puede hacerlo mirando el tamaño ANTES de la compresión. Podría tener una idea general (por ejemplo, compresas JPEG por un factor de ~ 15 para estas fotos), por lo que podría apuntar a 500k * 15 para el mapa de bits. Pero dependiendo de lo que haya en la foto, es posible que no golpees exactamente ese objetivo. Así que probablemente quieras hacer esto:

  1. Elige un jpegFactor
  2. bitMapTarget = target * jpegFactor
  3. ajustar el tamaño del mapa para que se ajuste a bitMapTarget
  4. comprimir mapa de bits a JPEG
  5. Si aún está por encima del objetivo, ajuste el jpegFactor y vuelva a intentarlo.

Podría tener algunos pasos en el # 5 para averiguar qué tan cerca estaba y tratar de tenerlo en cuenta.


Para reducir el tamaño de la imagen, he usado este código ... y su trabajo para mí ... Por favor, compruébelo una vez ... Podría ser útil para usted ...

Bitmap photo1 ; private byte[] imageByteArray1 ; BitmapFactory.Options opt1 = new BitmapFactory.Options(); opt1.inJustDecodeBounds=true; BitmapFactory.decodeFile(imageUrl.get(imgCount).toString(),opt1); // The new size we want to scale to final int REQUIRED_SIZE=320; // Find the correct scale value. It should be the power of 2. int width_tmp=opt1.outWidth,height_tmp=opt1.outHeight; int scale=2; while(true){ if(width_tmp>REQUIRED_SIZE||height_tmp>REQUIRED_SIZE) break; width_tmp/=2; height_tmp/=2; scale*=2; } // Decode with inSampleSize BitmapFactory.Options o2=new BitmapFactory.Options(); o2.inSampleSize=scale; o2.inJustDecodeBounds=false; photo1=BitmapFactory.decodeFile(imageUrl.get(imgCount).toString(),o2); ByteArrayOutputStream baos1=new ByteArrayOutputStream(); photo1.compress(Bitmap.CompressFormat.JPEG,60,baos1); imageByteArray1=baos1.toByteArray();


Personalizar mi getResizedBitmapLessThan500KB () a esto a continuación, funcionó para mí.

public static final long CAMERA_IMAGE_MAX_DESIRED_SIZE_IN_BYTES = 2524970; public static final double CAMERA_IMAGE_MAX_SIZE_AFTER_COMPRESSSION_IN_BYTES = 1893729.0; public static Bitmap getResizedBitmapLessThan500KB(Bitmap image, int maxSize, long file_size_in_bytes) { int width = image.getWidth(); int height = image.getHeight(); if(file_size_in_bytes <= AppGlobalConstants.CAMERA_IMAGE_MAX_DESIRED_SIZE_IN_BYTES) { if (width > height) { if (width > 500) maxSize = width * 75 / 100; } else { if (height > 500) maxSize = height * 75 / 100; } } else { double percentage = ((AppGlobalConstants.CAMERA_IMAGE_MAX_SIZE_AFTER_COMPRESSSION_IN_BYTES/file_size_in_bytes)*100); if (width > height) { if (width > 500) maxSize = width * (int)percentage / 100; } else { if (height > 500) maxSize = height * (int)percentage / 100; } if(maxSize > 600) { maxSize = 600; } } float bitmapRatio = (float)width / (float) height; if (bitmapRatio > 0) { width = maxSize; height = (int) (width / bitmapRatio); } else { height = maxSize; width = (int) (height * bitmapRatio); } Bitmap reduced_bitmap = Bitmap.createScaledBitmap(image, width, height, true); // Log.d("file_size","file_size_during_manipulation: "+String.valueOf(sizeOf(reduced_bitmap))); if(sizeOf(reduced_bitmap) > (500 * 1000)) { return getResizedBitmap(reduced_bitmap, maxSize, sizeOf(reduced_bitmap)); } else { return reduced_bitmap; } }


Por favor, compruebe si este código es útil:

final static int COMPRESSED_RATIO = 13; final static int perPixelDataSize = 4; public byte[] getJPGLessThanMaxSize(Bitmap image, int maxSize){ int maxPixelCount = maxSize *1024 * COMPRESSED_RATIO / perPixelDataSize; int imagePixelCount = image.getWidth() * image.getHeight(); Bitmap reducedBitmap; // Adjust Bitmap Dimensions if necessary. if(imagePixelCount > maxPixelCount) reducedBitmap = getResizedBitmapLessThanMaxSize(image, maxSize); else reducedBitmap = image; float compressedRatio = 1; byte[] resultBitmap; ByteArrayOutputStream outStream = new ByteArrayOutputStream(); int jpgQuality = 100; // Adjust Quality until file size is less than maxSize. do{ reducedBitmap.compress(Bitmap.CompressFormat.JPEG, jpgQuality, outStream); resultBitmap = outStream.toByteArray(); compressedRatio = resultBitmap.length / (reducedBitmap.getWidth() * reducedBitmap.getHeight() * perPixelDataSize); if(compressedRatio > (COMPRESSED_RATIO-1)){ jpgQuality -= 1; }else if(compressedRatio > (COMPRESSED_RATIO*0.8)){ jpgQuality -= 5; }else{ jpgQuality -= 10; } }while(resultBitmap.length > (maxSize * 1024)); return resultBitmap; } public Bitmap getResizedBitmapLessThanMaxSize(Bitmap image, int maxSize) { int width = image.getWidth(); int height = image.getHeight(); float bitmapRatio = (float)width / (float) height; // For uncompressed bitmap, the data size is: // H * W * perPixelDataSize = H * H * bitmapRatio * perPixelDataSize // height = (int) Math.sqrt(maxSize * 1024 * COMPRESSED_RATIO / perPixelDataSize / bitmapRatio); width = (int) (height * bitmapRatio); Bitmap reduced_bitmap = Bitmap.createScaledBitmap(image, width, height, true); return reduced_bitmap; }


Puedes verificar el tamaño antes de redimensionarlo. Si el mapa de bits es más grande que 500kb en tamaño, entonces cambie su tamaño.

También para hacer que el mapa de bits más grande se acerque a un tamaño de 500 kb, verifique la diferencia entre el tamaño y la compresión en consecuencia.

if(sizeOf(reduced_bitmap) > (500 * 1024)) { return getResizedBitmap(reduced_bitmap, maxSize, sizeOf(reduced_bitmap)); } else { return reduced_bitmap; }

y en redimensionar, Bitmap calcula la diferencia de tamaño y comprime en consecuencia


Supongo que desea utilizar la galería o la cámara del sistema para obtener la imagen. Tenga en cuenta que hay un límite superior para el máximo de datos transferidos a través de Intent y es por eso que siempre obtiene una versión reducida de las imágenes.

Puede consultar https://developer.android.com/training/camera/photobasics.html para obtener la solución estándar. En resumen, debe adquirir acceso al almacenamiento externo y generar un URI para la cámara u obtener el URI desde la aplicación de la galería. Luego use el ContentResolver para obtener la imagen.

InputStream inputStream = mContentResolver.openInputStream(mUri);

Es posible que desee implementar la resolución de contenido para otras aplicaciones para acceder a sus datos y esa es la práctica estándar.


puedes probar este método

public static Bitmap getScaledBitmap(Bitmap b, int reqWidth, int reqHeight) { Matrix m = new Matrix(); m.setRectToRect(new RectF(0, 0, b.getWidth(), b.getHeight()), new RectF(0, 0, reqWidth, reqHeight), Matrix.ScaleToFit.CENTER); return Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true); } //call this method like Bitmap bm400=getScaledBitmap(bm,500,500);

es útil para usted.