Android Collated Picture Compression Tool Class

  • 2021-10-25 08:00:57
  • OfStack

The memory of Android device is limited. For large pictures, it must be compressed before displaying, otherwise memory overflow will occur: OOM;

Processing strategy:

1. Use thumbnails (Thumbnails);

The Android system creates thumbnails for detected images; You can operate Image in Media content provider to operate pictures;

2. Manual compression:

(1) According to the picture and screen size, compress in equal ratio and display perfectly; (2) Reduce the picture quality and compress the picture size;

The following is the gadget class organized by ourselves (after scaling, there is no quality scaling here, and the picture size may exceed our expected limit at this time; If we have strict size limit requirements, we can first scale and judge whether the picture size exceeds the limit at this time; If the limit is exceeded, it can be scaled by quality. It is recommended to use scaling, which is likely to cause image distortion.)


</pre><p><pre name="code" class="java">package com.util; 
import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import android.graphics.Bitmap; 
import android.graphics.Matrix; 
import android.graphics.Bitmap.CompressFormat; 
import android.graphics.BitmapFactory; 
import android.media.ExifInterface; 
/** 
 *  Picture compression tool class  
 * @author  , Life_ 
 */ 
public class ImageCompressUtil { 
  /** 
   *  Compress a picture by reducing its quality  
   * @param bmp 
   *       Picture bitmap object to compress  
   * @param maxSize 
   *       Maximum size of compressed picture , Unit KB 
   * @return  Compressed picture bitmap object  
   */ 
  public static Bitmap compressByQuality(Bitmap bitmap, int maxSize) { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    int quality = 100; 
    bitmap.compress(CompressFormat.JPEG, quality, baos); 
    System.out.println(" Picture size before compression: " + baos.toByteArray().length + "byte"); 
    boolean isCompressed = false; 
    while (baos.toByteArray().length / 1024 > maxSize) { 
      quality -= 10; 
      baos.reset(); 
      bitmap.compress(CompressFormat.JPEG, quality, baos); 
      System.out.println(" Mass compressed to the original " + quality + "% When the size is: " 
          + baos.toByteArray().length + "byte"); 
      isCompressed = true; 
    } 
    System.out.println(" Picture size after compression: " + baos.toByteArray().length + "byte"); 
    if (isCompressed) { 
      Bitmap compressedBitmap = BitmapFactory.decodeByteArray( 
          baos.toByteArray(), 0, baos.toByteArray().length); 
      recycleBitmap(bitmap); 
      return compressedBitmap; 
    } else { 
      return bitmap; 
    } 
  } 
  /** 
   *  Incoming picture url, Compress the size of the picture by compressing the size of the picture 
   * @param pathName  The full path of the picture  
   * @param targetWidth  Scaled target width  
   * @param targetHeight  Target height of scaling  
   * @return  Scaled picture  
   */ 
  public static Bitmap compressBySize(String pathName, int targetWidth, 
      int targetHeight) { 
    BitmapFactory.Options opts = new BitmapFactory.Options(); 
    opts.inJustDecodeBounds = true;//  Don't really analyze the picture, just get the head information of the picture, including width and height;  
    Bitmap bitmap = BitmapFactory.decodeFile(pathName, opts); 
    //  Get the width and height of the picture;  
    int imgWidth = opts.outWidth; 
    int imgHeight = opts.outHeight; 
    //  Calculate the ratio of picture width and height to target width and height respectively; Take the smallest integer greater than or equal to the ratio;  
    int widthRatio = (int) Math.ceil(imgWidth / (float) targetWidth); 
    int heightRatio = (int) Math.ceil(imgHeight / (float) targetHeight); 
    if (widthRatio > 1 || heightRatio > 1) { 
      if (widthRatio > heightRatio) { 
        opts.inSampleSize = widthRatio; 
      } else { 
        opts.inSampleSize = heightRatio; 
      } 
    } 
    //  After setting the scaling ratio, load the picture into the content;  
    opts.inJustDecodeBounds = false; 
    bitmap = BitmapFactory.decodeFile(pathName, opts); 
    return bitmap; 
  } 
  /** 
   *  Incoming bitmap, Compress the size of the picture by compressing the size of the picture   
   * @param bitmap  To compress a picture  
   * @param targetWidth  Scaled target width  
   * @param targetHeight  Target height of scaling  
   * @return  Scaled picture  
   */ 
  public static Bitmap compressBySize(Bitmap bitmap, int targetWidth, 
      int targetHeight) { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    bitmap.compress(CompressFormat.JPEG, 100, baos); 
    BitmapFactory.Options opts = new BitmapFactory.Options(); 
    opts.inJustDecodeBounds = true; 
    bitmap = BitmapFactory.decodeByteArray(baos.toByteArray(), 0, 
        baos.toByteArray().length, opts); 
    //  Get the width and height of the picture;  
    int imgWidth = opts.outWidth; 
    int imgHeight = opts.outHeight; 
    //  Calculate the ratio of picture width and height to target width and height respectively; Take the smallest integer greater than the ratio;  
    int widthRatio = (int) Math.ceil(imgWidth / (float) targetWidth); 
    int heightRatio = (int) Math.ceil(imgHeight / (float) targetHeight); 
    if (widthRatio > 1 || heightRatio > 1) { 
      if (widthRatio > heightRatio) { 
        opts.inSampleSize = widthRatio; 
      } else { 
        opts.inSampleSize = heightRatio; 
      } 
    } 
    //  After setting the scaling ratio, load the picture into memory;  
    opts.inJustDecodeBounds = false; 
    Bitmap compressedBitmap = BitmapFactory.decodeByteArray( 
        baos.toByteArray(), 0, baos.toByteArray().length, opts); 
    recycleBitmap(bitmap); 
    return compressedBitmap; 
  } 
  /** 
   *  By compressing the size of the picture to compress the size of the picture, through the way of reading into the stream, it can effectively prevent the problem of excessive memory when the network picture data stream forms bitmap objects;  
   * @param InputStream  To compress the picture, pass it in as a stream  
   * @param targetWidth  Scaled target width  
   * @param targetHeight  Target height of scaling  
   * @return  Scaled picture  
   * @throws IOException  An exception occurred while reading the input stream  
   */ 
  public static Bitmap compressBySize(InputStream is, int targetWidth, 
      int targetHeight) throws IOException { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    byte[] buff = new byte[1024]; 
    int len = 0; 
    while ((len = is.read(buff)) != -1) { 
      baos.write(buff, 0, len); 
    } 
    byte[] data = baos.toByteArray(); 
    BitmapFactory.Options opts = new BitmapFactory.Options(); 
    opts.inJustDecodeBounds = true; 
    Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, 
        opts); 
    //  Get the width and height of the picture;  
    int imgWidth = opts.outWidth; 
    int imgHeight = opts.outHeight; 
    //  Calculate the ratio of picture width and height to target width and height respectively; Take the smallest integer greater than the ratio;  
    int widthRatio = (int) Math.ceil(imgWidth / (float) targetWidth); 
    int heightRatio = (int) Math.ceil(imgHeight / (float) targetHeight); 
    if (widthRatio > 1 || heightRatio > 1) { 
      if (widthRatio > heightRatio) { 
        opts.inSampleSize = widthRatio; 
      } else { 
        opts.inSampleSize = heightRatio; 
      } 
    } 
    //  After setting the scaling ratio, load the picture into memory;  
    opts.inJustDecodeBounds = false; 
    bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, opts); 
    return bitmap; 
  } 
  /** 
   *  Rotate the picture and straighten it out  
   * @param srcPath 
   * @param bitmap 
   * @return 
   */ 
  public static Bitmap rotateBitmapByExif(String srcPath, Bitmap bitmap) { 
    ExifInterface exif; 
    Bitmap newBitmap = null; 
    try { 
      exif = new ExifInterface(srcPath); 
      if (exif != null) { //  Read the camera direction information in the picture  
        int ori = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 
            ExifInterface.ORIENTATION_NORMAL); 
        int digree = 0; 
        switch (ori) { 
        case ExifInterface.ORIENTATION_ROTATE_90: 
          digree = 90; 
          break; 
        case ExifInterface.ORIENTATION_ROTATE_180: 
          digree = 180; 
          break; 
        case ExifInterface.ORIENTATION_ROTATE_270: 
          digree = 270; 
          break; 
        } 
        if (digree != 0) { 
          Matrix m = new Matrix(); 
          m.postRotate(digree); 
          newBitmap = Bitmap.createBitmap(bitmap, 0, 0, 
              bitmap.getWidth(), bitmap.getHeight(), m, true); 
          recycleBitmap(bitmap); 
          return newBitmap; 
        } 
      } 
    } catch (IOException e) { 
      e.printStackTrace(); 
    } 
    return bitmap; 
  } 
  /** 
   *  Recycling bitmap objects  
   * @param bitmap 
   */ 
  public static void recycleBitmap(Bitmap bitmap) { 
    if (bitmap != null && !bitmap.isRecycled()) { 
      bitmap.recycle(); 
      System.gc(); 
      bitmap = null; 
    } 
  } 
}

Summarize


Related articles: