Android uses uri to obtain and compress bitmap images,

Source: Internet
Author: User

Android uses uri to obtain and compress bitmap images,

Many people will use Media. getBitmap in onActivityResult to retrieve the returned image when calling image library selection, as shown below:

                        Uri mImageCaptureUri = data.getData();                        Bitmap photoBmp = null;                        if (mImageCaptureUri != null) {                            photoBmp = MediaStore.Images.Media.getBitmap(ac.getContentResolver(), mImageCaptureUri);                        }

 

However, the method of Media. getBitmap to obtain a known uri image is not advisable. Let's look at the source code of the Media. getBitmap () method:

public static final Bitmap getBitmap(ContentResolver cr, Uri url)        throws FileNotFoundException, IOException {    InputStream input = cr.openInputStream(url);    Bitmap bitmap = BitmapFactory.decodeStream(input);    input.close();    return bitmap;}

 

In fact, it is very simple and rude. The returned bitmap is the original size. When the image selected in the Image Library is large, the program is very likely to report OOM.

To avoid OOM, we need to improve this method.BitmapFactory. decodeStreamBefore compressing the image, the following is my improved code:

Call in onActivityResult

    Uri mImageCaptureUri = data.getData();    Bitmap photoBmp = null;    if (mImageCaptureUri != null) {    photoBmp = getBitmapFormUri(ac, mImageCaptureUri);    }

 

/*** Obtain and compress the image through uri ** @ param uri */public static Bitmap getBitmapFormUri (Activity ac, Uri uri) throws FileNotFoundException, IOException {InputStream input = ac. getContentResolver (). openInputStream (uri); BitmapFactory. options onlyBoundsOptions = new BitmapFactory. options (); onlyBoundsOptions. inJustDecodeBounds = true; onlyBoundsOptions. inDither = true; // optional onlyBoundsOptions. inPreferredCo Nfig = Bitmap. config. ARGB_8888; // optional BitmapFactory. decodeStream (input, null, onlyBoundsOptions); input. close (); int originalWidth = onlyBoundsOptions. outWidth; int originalHeight = onlyBoundsOptions. outHeight; if (originalWidth =-1) | (originalHeight =-1) return null; // The image resolution is based on X float hh = 800f; // set the height to 800f float ww = 480f. // set the width to 480f // The zoom ratio. Because it is a fixed proportional scaling, you can use only one of the data in height or width for calculation. int be = 1; // be = 1 indicates that if (originalWidth> originalHeight & originalWidth> ww) is not scaled) {// if the width is large, scale it to be = (int) (originalWidth/ww);} else if (originalWidth <originalHeight & originalHeight> hh) based on the fixed width) {// if the height is high, scale it to be = (int) (originalHeight/hh) according to the fixed width;} if (be <= 0) be = 1; // proportional compression BitmapFactory. options bitmapOptions = new BitmapFactory. options (); bitmapOptions. inSampleSize = be; // sets the scaling ratio bitmapOptions. inDither = true; // optional bitmapOptions. inPreferredConfig = Bitmap. config. ARGB_8888; // optional input = ac. getContentResolver (). openInputStream (uri); Bitmap bitmap = BitmapFactory. decodeStream (input, null, bitmapOptions); input. close (); return compressImage (bitmap); // perform quality compression again}

 

/*** Quality compression method ** @ param image * @ return */public static Bitmap compressImage (Bitmap image) {ByteArrayOutputStream baos = new ByteArrayOutputStream (); image. compress (Bitmap. compressFormat. JPEG, 100, baos); // quality compression method. Here, 100 indicates no compression. Store the compressed data in baos int options = 100; while (baos. toByteArray (). length/1024> 100) {// cyclically determine if the size of the compressed image is greater than kb and the size of the image is greater than that of the compressed baos. reset (); // reset baos to clear baos. // The first parameter is image format. The second parameter is image quality. The value 100 is the highest, the value 0 is the worst, and the third parameter is: the stream image that saves the compressed data. compress (Bitmap. compressFormat. JPEG, options, baos); // compress options % here and store the compressed data in baos options-= 10; // decrease by 10 every time} ByteArrayInputStream isBm = new ByteArrayInputStream (baos. toByteArray (); // store the compressed data baos in ByteArrayInputStream Bitmap bitmap = BitmapFactory. decodeStream (isBm, null, null); // generates the ByteArrayInputStream data to return bitmap ;}

The OOM problem was solved, but another problem occurred. I used a Samsung mobile phone to take a photo or select a photo, and the image returned was actually converted to 90 degrees .. A hard-earned android programmer .. Then change ..

Improve the code in onActivityResult:

Uri originalUri = null; File file = null; if (null! = Data & data. getData ()! = Null) {originalUri = data. getData (); file = getFileFromMediaUri (ac, originalUri);} Bitmap photoBmp = getBitmapFormUri (ac, Uri. fromFile (file); int degree = getBitmapDegree (file. getAbsolutePath ();/*** rotate the image in a positive direction */Bitmap newbitmap = rotateBitmapByDegree (photoBmp, degree );

 

 

/*** Get the File through Uri * @ param ac * @ param uri * @ return */public static File getFileFromMediaUri (Context ac, Uri uri) {if (uri. getScheme (). toString (). compareTo ("content") = 0) {ContentResolver cr = ac. getContentResolver (); Cursor cursor = cr. query (uri, null, null); // find if (cursor! = Null) {cursor. moveToFirst (); String filePath = cursor. getString (cursor. getColumnIndex ("_ data"); // obtain the image path cursor. close (); if (filePath! = Null) {return new File (filePath) ;}} else if (uri. getScheme (). toString (). compareTo ("file") = 0) {return new File (uri. toString (). replace ("file: //", "");} return null ;}

 

/*** Read image rotation angle ** @ param path absolute path * @ return image rotation angle */public static int getBitmapDegree (String path) {int degree = 0; try {// read the image from the specified path and obtain its EXIF information. ExifInterface exifInterface = new ExifInterface (path); // obtain the image rotation information int orientation = exifInterface. getAttributeInt (ExifInterface. TAG_ORIENTATION, ExifInterface. ORIENTATION_NORMAL); switch (orientation) {case ExifInterface. ORIENTATION_ROTATE_90: degree = 90; break; case ExifInterface. ORIENTATION_ROTATE_180: degree = 180; break; case ExifInterface. ORIENTATION_ROTATE_270: degree = 270; break ;}} catch (IOException e) {e. printStackTrace ();} return degree ;}

 

/*** Rotate the image at a certain angle ** @ param bm image to be rotated * @ param degree rotation angle * @ return rotated image */public static Bitmap rotateBitmapByDegree (Bitmap bm, int degree) {Bitmap returnBm = null; // Based on the rotation angle, generate the rotating Matrix matrix = new Matrix (); matrix. postRotate (degree); try {// rotate the original image according to the rotation matrix and obtain the new image returnBm = Bitmap. createBitmap (bm, 0, 0, bm. getWidth (), bm. getHeight (), matrix, true);} catch (OutOfMemoryError e ){} If (returnBm = null) {returnBm = bm;} if (bm! = ReturnBm) {bm. recycle () ;}return returnBm ;}

 

Okay, you can fix the problem!

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.