Cómo disminuir el tamaño de la imagen sin perder su calidad en android.

Tengo un ImageView en mi proyecto,tengo que poner una de mayor tamaño de la imagen.

Soy nuevo en android.

por favor, ayudar.

  • He utilizado el recorte. pero. Recorte de una imagen daños a su calidad..después de recortar puedo añadir una imagen a la imageview.pero se reduce la calidad de la imagen..pero cuando estoy tomando la imagen más grande..la imagen no se muestra..
  • Ahora, ¿cómo puedo disminuir el tamaño de la imagen withou perder su calidad..Puede proporcionar algún código de ejemplo..plzz ayuda..gracias de antemano..

5 Comentarios

  1. 86

    A continuación el código de Trabajo para la escala de la imagen como de la relación de aspecto:

    Bitmap bitmapImage = BitmapFactory.decodeFile("Your path");
    int nh = (int) ( bitmapImage.getHeight() * (512.0 / bitmapImage.getWidth()) );
    Bitmap scaled = Bitmap.createScaledBitmap(bitmapImage, 512, nh, true);
    your_imageview.setImageBitmap(scaled);

    Comprimir la imagen sin perder la calidad como whatsapp

    public String compressImage(String imageUri) {
    String filePath = getRealPathFromURI(imageUri);
    Bitmap scaledBitmap = null;
    BitmapFactory.Options options = new BitmapFactory.Options();
    //     by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If
    //     you try the use the bitmap here, you will get null.
    options.inJustDecodeBounds = true;
    Bitmap bmp = BitmapFactory.decodeFile(filePath, options);
    int actualHeight = options.outHeight;
    int actualWidth = options.outWidth;
    //     max Height and width values of the compressed image is taken as 816x612
    float maxHeight = 816.0f;
    float maxWidth = 612.0f;
    float imgRatio = actualWidth / actualHeight;
    float maxRatio = maxWidth / maxHeight;
    //     width and height values are set maintaining the aspect ratio of the image
    if (actualHeight > maxHeight || actualWidth > maxWidth) {
    if (imgRatio < maxRatio) {
    imgRatio = maxHeight / actualHeight;
    actualWidth = (int) (imgRatio * actualWidth);
    actualHeight = (int) maxHeight;
    } else if (imgRatio > maxRatio) {
    imgRatio = maxWidth / actualWidth;
    actualHeight = (int) (imgRatio * actualHeight);
    actualWidth = (int) maxWidth;
    } else {
    actualHeight = (int) maxHeight;
    actualWidth = (int) maxWidth;
    }
    }
    //     setting inSampleSize value allows to load a scaled down version of the original image
    options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);
    //     inJustDecodeBounds set to false to load the actual bitmap
    options.inJustDecodeBounds = false;
    //     this options allow android to claim the bitmap memory if it runs low on memory
    options.inPurgeable = true;
    options.inInputShareable = true;
    options.inTempStorage = new byte[16 * 1024];
    try {
    //         load the bitmap from its path
    bmp = BitmapFactory.decodeFile(filePath, options);
    } catch (OutOfMemoryError exception) {
    exception.printStackTrace();
    }
    try {
    scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
    } catch (OutOfMemoryError exception) {
    exception.printStackTrace();
    }
    float ratioX = actualWidth / (float) options.outWidth;
    float ratioY = actualHeight / (float) options.outHeight;
    float middleX = actualWidth / 2.0f;
    float middleY = actualHeight / 2.0f;
    Matrix scaleMatrix = new Matrix();
    scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
    Canvas canvas = new Canvas(scaledBitmap);
    canvas.setMatrix(scaleMatrix);
    canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));
    //     check the rotation of the image and display it properly
    ExifInterface exif;
    try {
    exif = new ExifInterface(filePath);
    int orientation = exif.getAttributeInt(
    ExifInterface.TAG_ORIENTATION, 0);
    Log.d("EXIF", "Exif: " + orientation);
    Matrix matrix = new Matrix();
    if (orientation == 6) {
    matrix.postRotate(90);
    Log.d("EXIF", "Exif: " + orientation);
    } else if (orientation == 3) {
    matrix.postRotate(180);
    Log.d("EXIF", "Exif: " + orientation);
    } else if (orientation == 8) {
    matrix.postRotate(270);
    Log.d("EXIF", "Exif: " + orientation);
    }
    scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
    scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix,
    true);
    } catch (IOException e) {
    e.printStackTrace();
    }
    FileOutputStream out = null;
    String filename = getFilename();
    try {
    out = new FileOutputStream(filename);
    //         write the compressed bitmap at the destination specified by filename.
    scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    }
    return filename;
    }
    public String getFilename() {
    File file = new File(Environment.getExternalStorageDirectory().getPath(), "MyFolder/Images");
    if (!file.exists()) {
    file.mkdirs();
    }
    String uriSting = (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".jpg");
    return uriSting;
    }
    private String getRealPathFromURI(String contentURI) {
    Uri contentUri = Uri.parse(contentURI);
    Cursor cursor = getContentResolver().query(contentUri, null, null, null, null);
    if (cursor == null) {
    return contentUri.getPath();
    } else {
    cursor.moveToFirst();
    int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
    return cursor.getString(index);
    }
    }
    public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;
    if (height > reqHeight || width > reqWidth) {
    final int heightRatio = Math.round((float) height / (float) reqHeight);
    final int widthRatio = Math.round((float) width / (float) reqWidth);
    inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }
    final float totalPixels = width * height;
    final float totalReqPixelsCap = reqWidth * reqHeight * 2;
    while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
    inSampleSize++;
    }
    return inSampleSize;
    }
    • Aandyan Cómo el código va a reaccionar si el tamaño de la imagen y las dimensiones son demasiado pequeños o grandes…Y por qué 816×612 está codificado podemos calcular mediante programación
    • básicamente, el código anterior se utiliza para reducir el tamaño de las imágenes con el mantenimiento de la relación de aspecto. más importante es que todas las imágenes deben tener la altura y la anchura de estos son definidos por los requerimientos de tu aplicación. si usted está usando imágenes de alta calidad para su foto de perfil puede cambiar la altura máxima ancho máximo de 300, por lo que su relación con su establecimiento. Y también se puede comprobar real de la altura y el ancho antes de la compresión si es mayor que su requisito, usted puede hacer la compresión.
    • Cómo hacer una Dinámica para todo el tamaño de las Imágenes, y para todos los dispositivos con diferente resolución,,
    • Se está trabajando perfectamente bien para la galería de imágenes. pero si trato de reducir la imagen de la cámara, va a distorsionar la calidad de la imagen y haga una imagen muy pequeña. Alguna idea de cómo solucionar esto?
    • funcionó a la perfección @JittyAandyan, incluso las imágenes de la cámara se está comprimido, la calidad de la diferencia es de 80%, pero el tamaño es gettin reducido al 50% de la original, me ha ayudado mucho, mientras que el envío de imágenes al servidor después de la conversión a cadena base64..
    • el aspecto que tiene error: float imgRatio = (float) actualWidth / (float) actualHeight;
    • El código funciona bien para imágenes de retrato (actualWidth < actualHeight) pero para imágenes de paisajes, los dos (imgRatio vs maxRatio) comparaciones deben ser invertida.
    • decodeFile en el método de compresión de devolver null
    • ¿Cómo puedo cambiar la disminución de la proporción de la calidad?
    • cómo pasar de la imagen comprimida filepath a base avanzada para cargar la imagen imageRef.put(filepath) en whatsapp método?
    • Después de seleccionar la imagen desde la galería, ¿por qué se reduce el tamaño real de la imagen. e.g supongamos que seleccionar la imagen de 5MB imagen de la galería, después de usar este código se reduce a 200 KB. está bien, pero ¿por qué también los cambios de la galería real de tamaño de imagen de 200 KB . ¿Puede alguien explicar por favor
    • opciones.inPurgeable & opciones.inInputShareable está en desuso por lo que en lugar de opciones.inPurgeable = true; opciones.inInputShareable = true; opciones de uso.inBitmap = bmp;

  2. 1

    Crear La Clase Para CompressFile Imagen

    public class CompressFile {
    public static File getCompressedImageFile(File file, Context mContext) {
    try {
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;
    if (getFileExt(file.getName()).equals("png") || getFileExt(file.getName()).equals("PNG")) {
    o.inSampleSize = 6;
    } else {
    o.inSampleSize = 6;
    }
    FileInputStream inputStream = new FileInputStream(file);
    BitmapFactory.decodeStream(inputStream, null, o);
    inputStream.close();
    //The new size we want to scale to
    final int REQUIRED_SIZE = 100;
    //Find the correct scale value. It should be the power of 2.
    int scale = 1;
    while (o.outWidth / scale / 2 >= REQUIRED_SIZE &&
    o.outHeight / scale / 2 >= REQUIRED_SIZE) {
    scale *= 2;
    }
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    inputStream = new FileInputStream(file);
    Bitmap selectedBitmap = BitmapFactory.decodeStream(inputStream, null, o2);
    ExifInterface ei = new ExifInterface(file.getAbsolutePath());
    int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
    ExifInterface.ORIENTATION_UNDEFINED);
    switch (orientation) {
    case ExifInterface.ORIENTATION_ROTATE_90:
    rotateImage(selectedBitmap, 90);
    break;
    case ExifInterface.ORIENTATION_ROTATE_180:
    rotateImage(selectedBitmap, 180);
    break;
    case ExifInterface.ORIENTATION_ROTATE_270:
    rotateImage(selectedBitmap, 270);
    break;
    case ExifInterface.ORIENTATION_NORMAL:
    default:
    break;
    }
    inputStream.close();
    //here i override the original image file
    File folder = new File(Environment.getExternalStorageDirectory() + "/FolderName");
    boolean success = true;
    if (!folder.exists()) {
    success = folder.mkdir();
    }
    if (success) {
    File newFile = new File(new File(folder.getAbsolutePath()), file.getName());
    if (newFile.exists()) {
    newFile.delete();
    }
    FileOutputStream outputStream = new FileOutputStream(newFile);
    if (getFileExt(file.getName()).equals("png") || getFileExt(file.getName()).equals("PNG")) {
    selectedBitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
    } else {
    selectedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
    }
    return newFile;
    } else {
    return null;
    }
    } catch (Exception e) {
    return null;
    }
    }
    public static String getFileExt(String fileName) {
    return fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
    }
    public static Bitmap rotateImage(Bitmap source, float angle) {
    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(),
    matrix, true);
    }
    }
  3. 1

    Utilizar este código para comprimir el mapa de bits de menor tamaño.

    BitmapFactory.Options Options = new BitmapFactory.Options();
    Options.inSampleSize = 4;
    Options.inJustDecodeBounds = false;
    action_bitmap = BitmapFactory.decodeFile(Glob.savedImage, Options);

    Glob.savedImage es la Cadena de ruta de acceso de la imagen.

  4. 0

    La aceptó responder funciona bien cuando está agarrando una imagen de la galería, pero cuando se trata de obtener una imagen desde el gestor de archivos, se produce un error. La razón es que la Uri tiene un formato diferente al que getRealPathFromURI(imageUri) no logran obtener la ruta de acceso real a partir de ella.

    Con el fin de resolver este problema, utilice los mismos métodos de la aceptó respuesta, excepto para copressImage() & getRealPathFromURI() que se ajusta a apoyar tanto a las imágenes grabadas desde archivo pesebre & galería:

    public static String compressImage(Context context, Uri uri) {
    String filePath = getRealPathFromURI(context, uri);
    Bitmap scaledBitmap = null;
    BitmapFactory.Options options = new BitmapFactory.Options();
    //     by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If
    //     you try the use the bitmap here, you will get null.
    options.inJustDecodeBounds = true;
    Bitmap bmp = BitmapFactory.decodeFile(filePath, options);
    int actualHeight = options.outHeight;
    int actualWidth = options.outWidth;
    //     max Height and width values of the compressed image is taken as 816x612
    float maxHeight = 816.0f;
    float maxWidth = 612.0f;
    float imgRatio = actualWidth / actualHeight;
    float maxRatio = maxWidth / maxHeight;
    //     width and height values are set maintaining the aspect ratio of the image
    if (actualHeight > maxHeight || actualWidth > maxWidth) {
    if (imgRatio < maxRatio) {
    imgRatio = maxHeight / actualHeight;
    actualWidth = (int) (imgRatio * actualWidth);
    actualHeight = (int) maxHeight;
    } else if (imgRatio > maxRatio) {
    imgRatio = maxWidth / actualWidth;
    actualHeight = (int) (imgRatio * actualHeight);
    actualWidth = (int) maxWidth;
    } else {
    actualHeight = (int) maxHeight;
    actualWidth = (int) maxWidth;
    }
    }
    //     setting inSampleSize value allows to load a scaled down version of the original image
    options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);
    //     inJustDecodeBounds set to false to load the actual bitmap
    options.inJustDecodeBounds = false;
    //     this options allow android to claim the bitmap memory if it runs low on memory
    options.inPurgeable = true;
    options.inInputShareable = true;
    options.inTempStorage = new byte[16 * 1024];
    try {
    //         load the bitmap from its path
    bmp = BitmapFactory.decodeFile(filePath, options);
    } catch (OutOfMemoryError exception) {
    exception.printStackTrace();
    }
    try {
    scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
    } catch (OutOfMemoryError exception) {
    exception.printStackTrace();
    }
    float ratioX = actualWidth / (float) options.outWidth;
    float ratioY = actualHeight / (float) options.outHeight;
    float middleX = actualWidth / 2.0f;
    float middleY = actualHeight / 2.0f;
    Matrix scaleMatrix = new Matrix();
    scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
    Canvas canvas = new Canvas(scaledBitmap);
    canvas.setMatrix(scaleMatrix);
    canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));
    //     check the rotation of the image and display it properly
    ExifInterface exif;
    try {
    exif = new ExifInterface(filePath);
    int orientation = exif.getAttributeInt(
    ExifInterface.TAG_ORIENTATION, 0);
    Log.d("EXIF", "Exif: " + orientation);
    Matrix matrix = new Matrix();
    if (orientation == 6) {
    matrix.postRotate(90);
    Log.d("EXIF", "Exif: " + orientation);
    } else if (orientation == 3) {
    matrix.postRotate(180);
    Log.d("EXIF", "Exif: " + orientation);
    } else if (orientation == 8) {
    matrix.postRotate(270);
    Log.d("EXIF", "Exif: " + orientation);
    }
    scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
    scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix,
    true);
    } catch (IOException e) {
    e.printStackTrace();
    }
    FileOutputStream out = null;
    String filename = getFilename();
    try {
    out = new FileOutputStream(filename);
    //         write the compressed bitmap at the destination specified by filename.
    scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    }
    return filename;
    }
    public static String getRealPathFromURI(Context context, Uri uri) {
    Uri queryUri = MediaStore.Files.getContentUri("external");
    String columnData = MediaStore.Files.FileColumns.DATA;
    String columnSize = MediaStore.Files.FileColumns.SIZE;
    String[] projectionData = {MediaStore.Files.FileColumns.DATA};
    String name = null;
    String size = null;
    Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
    if ((cursor != null) && (cursor.getCount() > 0)) {
    int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
    int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
    cursor.moveToFirst();
    name = cursor.getString(nameIndex);
    size = cursor.getString(sizeIndex);
    cursor.close();
    }
    String imagePath = "";
    if ((name != null) && (size != null)) {
    String selectionNS = columnData + " LIKE '%" + name + "' AND " + columnSize + "='" + size + "'";
    Cursor cursorLike = context.getContentResolver().query(queryUri, projectionData, selectionNS, null, null);
    if ((cursorLike != null) && (cursorLike.getCount() > 0)) {
    cursorLike.moveToFirst();
    int indexData = cursorLike.getColumnIndex(columnData);
    if (cursorLike.getString(indexData) != null) {
    imagePath = cursorLike.getString(indexData);
    }
    cursorLike.close();
    }
    }
    return imagePath;
    }
  5. -1

    Para la Compresión de imagen con compresión JPEG y mantener la transparencia como PNG utilizar este código. A mí me funcionó.

    Bitmap newBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
    Canvas canvas = new Canvas(newBitmap);
    canvas.drawColor(Color.WHITE);
    canvas.drawBitmap(bitmap, 0, 0, null);
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    newBitmap.compress(Bitmap.CompressFormat.JPEG, 50, outputStream);

Dejar respuesta

Please enter your comment!
Please enter your name here