About a few months ago, I was worried about the company's app being photographed on Android phones.
Internet search, indeed there are many examples, most of them are copied to copy, and the level is mostly in the appearance of the demo, can be used to explain the knowledge point, but a real project, it is flawed.
At that time, I used the popular solution, temporarily did a photo function, it seems very good. The problem followed, I use millet mobile phones, on other phones are running normal, millet here is always touching nails. Although I am a rational rice noodles, but also secretly to the Millet engineer greetings to all over. I'm ashamed!
The document can not find an answer, I have been to Com.android.camera.action.CROP holding a big question, where it comes from, what it can do, it receives processing what type of data? Google is secretive about this, but in official documents only a few words and intent, but not very detailed.
With the project drive, I can not hold the idea of not understanding the principle of not going forward, the only thing to do is to solve the problem. Finally found a solution in the German question, said that even the rice is not a problem. At that time cheerfully changed the code, indeed on all the mobile phone run up, a moment of relief, the question of this also left behind.
Until months ago, the boss asked to double the resolution of photos uploaded to the server. OK, double simple, add outputx and Outputy.
Intent.putextra ("Outputx", OUTPUTX);
Intent.putextra ("Outputy", outputy);
This increase startled me. Boss's mobile phone photos are almost a thumbnail, but I greet the whole of the engineer's millet at this time reflects the domestic God machine fan son, millet on the size of everything normal. Why is this? I have a rough idea of why, but I don't know how to solve it.
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.
Take my Xiaomi phone as an example, camera 800W pixels, according to my current settings to shoot out the size of the picture for 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 computational question: 3200*2400*4 bytes = 30M.
Such a staggering number! Even if you're willing to spend so much memory on a bitmap that has a lifetime of over 10s, Android won't agree.
Mobile devices typically has the constrained system resources.
Android devices can has as little as 16MB of memory available to a single application.
This is the original version of the Android doc, although different mobile phone system manufacturers may be around the 16M this number has slightly raised, but this 30M, the general mobile phone is really wasteful. Also only millet this cattle machine, memory comparable to personal PC, in the soil rich like a spendthrift to do the domineering.
OK, said so much, is nothing more than spit on the bitter, burst personal experience only, where is the actual solution?
I also Google to, saying that the general Baidu can not, that Google or direct StackOverflow, just to see English.
At last, I found a solution in the blog of an Android team abroad, confirming my conjecture and giving the actual code.
I translated this article into Chinese, as the basis of this blog, suggest a detailed look.
"Translate" How to use Android Mediastore to crop large images http://www.linuxidc.com/Linux/2012-11/73939.htm
The great thing about this URL is that it solves the size limit of Android to the returned image, and explains in detail the specific meaning of the intent additional data for the cropped image. OK, I'm just standing on the shoulders of giants, improving the program to suit a wider range of needs.
Take the illustration:
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:
This article focuses on understanding the sources of demand and how to think and solve problems. The next article will describe the specific actions.
In this article, I'll show you how to get from a photo album.
In the previous article, I made a detailed analysis of the need for taking pictures, trying to get everyone 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
• Do not return data using URIs
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 the analysis of our previous article, I have prepared two instances of intent.
One, from the album to cut large map:
Intent Intent = new Intent (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 Detection
Startactivityforresult (Intent, choose_big_picture);
Second, from the album to cut small map
Intent Intent = new Intent (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 Detection
Startactivityforresult (Intent, choose_small_picture);
Third, the corresponding Onactivityresult can handle the returned data in this way
Switch (requestcode) {
Case Choose_big_picture:
LOG.D (TAG, "choose_big_picture:data =" + data);//it seems to is null
if (Imageuri! = null) {
Bitmap Bitmap = Decodeuriasbitmap (Imageuri);//decode Bitmap
Imageview.setimagebitmap (bitmap);
}
Break
Case Choose_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
}
Private Bitmap Decodeuriasbitmap (Uri uri) {
Bitmap Bitmap = null;
try {
Bitmap = Bitmapfactory.decodestream (Getcontentresolver (). Openinputstream (URI));
} catch (FileNotFoundException e) {
E.printstacktrace ();
return null;
}
return bitmap;
}
:
Large
Small map
In the previous blog, we learned how to use Android albums. In this blog, I will show you how to take pictures.
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 FILE
Uri 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:
Intent Intent = 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) {
Case Take_big_picture:
LOG.D (TAG, "take_big_picture:data =" + data);//it seems to is null
TODO sent to Crop
Cropimageuri (Imageuri, N, crop_big_picture);
Break
Case Take_small_picture:
LOG.I (TAG, "take_small_picture:data =" + data);
TODO sent to Crop
Cropimageuri (Imageuri, 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 void Cropimageuri (URI uri, int outputx, int outputy, int requestcode) {
Intent Intent = new Intent ("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 Detection
Startactivityforresult (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) {
Case Crop_big_picture://from Crop_big_picture
LOG.D (TAG, "crop_big_picture:data =" + data);//it seems to is null
if (Imageuri! = null) {
Bitmap Bitmap = Decodeuriasbitmap (Imageuri);
Imageview.setimagebitmap (bitmap);
}
Break
Case Crop_small_picture:
if (Imageuri! = null) {
Bitmap Bitmap = Decodeuriasbitmap (Imageuri);
Imageview.setimagebitmap (bitmap);
}else{
LOG.E (TAG, "crop_small_picture:data =" + data);
}
Break
Default
Break
}
:
SOURCE Download:
Free in http://linux.linuxidc.com/
User name and password are www.linuxidc.com
Specific download directory in/2012 materials/November/11th/android big Picture cutting the ultimate solution
An analysis of the ultimate solution for Android big picture cropping