Take pictures from Android or crop them from albums

Source: Internet
Author: User
Tags crop image

In Android, intent triggers the camera program, and when the picture is taken, the data is returned, but the camera does not return the full-size image to the calling activity, given the memory problem, and, in general, it is possible to return thumbnails, such as 120*160px.

What is this for? This is not a bug, but is well-designed, but not transparent to developers.

For example, the camera 800W pixels, according to my current settings to shoot out the size of the image 3200*2400px. Some people say, that return Bai, big deal consumes 1-2m of memory, good, this size of picture really only about 1.8M size. But what you can't imagine is that the bitmap of this size will consume all the memory of your application. For security reasons, Android will only give you a shabby thumbnail image.

In Android2.3, the default bitmap is 32 bits, and the type is argb_8888, which means that one pixel occupies 4 bytes of memory. Let's do a simple math problem: 3200*2400*4 bytes = 30M, so the picture taken with the photo needs to be cropped and used.

The specific meaning of the intent additional data for the Android crop image, take a picture :

All optional data for Intent ("Com.android.camera.action.CROP") is at a glance. After understanding the meaning of each of the above options, we look at three extremely important options:

Data, Mediastore.extra_output, and Return-data.

Both data and mediastore.extra_output are optional incoming data options, you can choose to set data to bitmap, or you can choose whether to return Data (return-data:true) by associating it with the URI.

Why is there an option to not return data? If you understand the URI enough, you should know that the URI is similar to file, all of your operations, such as cropping the data are stored in the URI, you already have the corresponding URI, there is no need to superfluous, and then return to bitmap.

As already mentioned, you can set data to bitmap, but the limitation of this operation is that your bitmap cannot be too large. Therefore, we move forward the idea seems clear: truncated map with the URI, small image with bitmap.

I put this idea into a picture:

From albums

On top of that, I took a picture. This requirement was analyzed in detail to try to understand the limitations of Android itself and the implementation we should take.

According to our analysis and summary, the photo is from the source of photos and albums, and can take action has

    • Use bitmap and return data
    • Using URIs does not return data

Before we learned that using bitmap may cause the picture to be too large to return the actual size of the picture, I will use the large map URI, small figure bitmap data storage.

We're going to use the URI to save the picture after the photo:

Private Static Final String image_file_location = "File:///sdcard/temp.jpg"; // temp File Uri Imageuri = Uri.parse (image_file_location); // The Uri to store the big bitmap

It is not difficult to know that we choose the image from the album ACTION is Intent.action_get_content.

Based on an analysis of our last blog post, I have prepared two instances of intent.

One, from the album to cut large map:

Intent Intent =NewIntent (Intent.action_get_content,NULL); Intent.settype ("Image/*"); Intent.putextra ("Crop", "true"); Intent.putextra ("Aspectx", 2); Intent.putextra ("Aspecty", 1); Intent.putextra ("Outputx", 600); Intent.putextra ("Outputy", 300); Intent.putextra ("Scale",true); Intent.putextra ("Return-data",false); Intent.putextra (Mediastore.extra_output, Imageuri); Intent.putextra ("OutputFormat", Bitmap.CompressFormat.JPEG.toString ()); Intent.putextra ("Nofacedetection",true);//No Face DetectionStartactivityforresult (Intent, choose_big_picture);

Second, from the album to cut small map

Intent Intent =NewIntent (Intent.action_get_content,NULL); Intent.settype ("Image/*"); Intent.putextra ("Crop", "true"); Intent.putextra ("Aspectx", 2); Intent.putextra ("Aspecty", 1); Intent.putextra ("Outputx", 200); Intent.putextra ("Outputy", 100); Intent.putextra ("Scale",true); Intent.putextra ("Return-data",true); Intent.putextra ("OutputFormat", Bitmap.CompressFormat.JPEG.toString ()); Intent.putextra ("Nofacedetection",true);//No Face DetectionStartactivityforresult (Intent, choose_small_picture);

Third, the corresponding Onactivityresult can handle the returned data in this way

Switch(requestcode) { Casechoose_big_picture:log.d (TAG,"Choose_big_picture:data =" + data);//It seems to is null    if(Imageuri! =NULL) {Bitmap Bitmap= Decodeuriasbitmap (Imageuri);//decode BitmapImageview.setimagebitmap (bitmap); }     Break;  Casechoose_small_picture:if(Data! =NULL) {Bitmap Bitmap= Data.getparcelableextra ("Data");        Imageview.setimagebitmap (bitmap); }Else{log.e (TAG,"Choose_small_picture:data =" +data); }     Break; default:     Break; }PrivateBitmap decodeuriasbitmap (Uri uri) {Bitmap Bitmap=NULL; Try{bitmap=Bitmapfactory.decodestream (Getcontentresolver (). Openinputstream (URI)); } Catch(FileNotFoundException e) {e.printstacktrace (); return NULL; }    returnbitmap; }
Photo

Photo is a bit special, you know, now the Android smartphone camera is millions of pixels, the pictures are very large. Therefore, we can not use the same as the photo album Bitmap, regardless of the large map of the small map to use the URI to operate uniformly.

First, prepare the URI you want to use:

private static final String image_file_location = "file:///sdcard/temp.jpg";//temp fileuri Imageuri = Uri.parse (image_ file_location);//the Uri to store the big bitmap

Second, using Mediastore.action_image_capture can easily call camera program to take pictures:

New Intent (mediastore.action_image_capture); // Action is capture Intent.putextra (Mediastore.extra_output, Imageuri); Startactivityforresult (Intent, take_big_picture); // or Take_small_picture

Thirdly, we can get the returned data (URI) in Onactivityresult, and pass the URI to the program.

Switch(requestcode) { Casetake_big_picture:log.d (TAG,"Take_big_picture:data =" + data);//It seems to is null//TODO sent to cropCropimageuri (Imageuri,800, 400, crop_big_picture);  Break;  Casetake_small_picture:log.i (TAG,"Take_small_picture:data =" +data); //TODO sent to cropCropimageuri (Imageuri,300, 150, crop_small_picture);  Break; default:     Break; }

You can see, whether it is a big picture or a small picture, are used by the URI, only the size is different. We encapsulate this operation in a single method.

Private voidCropimageuri (Uri Uri,intOUTPUTX,intOutputy,intRequestcode) {Intent Intent=NewIntent ("Com.android.camera.action.CROP"); Intent.setdataandtype (URI,"Image/*"); Intent.putextra ("Crop", "true"); Intent.putextra ("Aspectx", 2); Intent.putextra ("Aspecty", 1); Intent.putextra ("Outputx", OUTPUTX); Intent.putextra ("Outputy", outputy); Intent.putextra ("Scale",true);    Intent.putextra (Mediastore.extra_output, URI); Intent.putextra ("Return-data",false); Intent.putextra ("OutputFormat", Bitmap.CompressFormat.JPEG.toString ()); Intent.putextra ("Nofacedetection",true);//No Face DetectionStartactivityforresult (Intent, Requestcode); }

Four, the last step, we have passed the data into the crop picture program, the next thing to do is to process the returned data:

    Switch(requestcode) { CaseCrop_big_picture://From crop_big_picturelog.d (TAG,"Crop_big_picture:data =" + data);//It seems to is null    if(Imageuri! =NULL) {Bitmap Bitmap=Decodeuriasbitmap (Imageuri);    Imageview.setimagebitmap (bitmap); }     Break;  Casecrop_small_picture:if(Imageuri! =NULL) {Bitmap Bitmap=Decodeuriasbitmap (Imageuri);    Imageview.setimagebitmap (bitmap); }Else{log.e (TAG,"Crop_small_picture:data =" +data); }     Break; default:     Break; }
Pick From: Https://github.com/ryanhoo/PhotoCropper

Take pictures from Android or crop them from albums

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.