Android App call Camera development example

Source: Internet
Author: User
Tags abs android games


These two days playing Android games, the blog has not added something for several days, ashamed! Take a look at one of the most collapsing problems of the two days.

Good early installed the development environment, really started or these two days, very unfamiliar, although there are SDK documentation, so many mosquito-like word, really do not mind to study slowly. This does not want to call the camera, the original thought it can easily be done, the cumulative spend about a day to only guarantee that there is no error ... As for the effect, it's hard to say!

First look at the api-examples has called the camera example, in the simulator although no effect, after all, can be executed, is a square in the black and white background move Bai.

So a Google-provided example, to my HTC G2 can also be executed on the error, my respect for Google immediately reduced by 0.0001% ah ... (Of course there may be G2 not standard, but after all, other software is able to use, it seems that there are a lot of robust code AH). Online debugging look at this line of error (ANDROID-7):


Parameters.setpreviewsize (W, h);

Check that the camera is not all casual (W, h) can know, so we have the following enhancements:

List<size> msupportedpreviewsizes;
msupportedpreviewsizes = Mcamera.getparameters (). getsupportedpreviewsizes ();
Mpreviewsize = Getoptimalpreviewsize (msupportedpreviewsizes, width, height);

Private Size getoptimalpreviewsize (list<size> sizes, int w, int h) {
Final double aspect_tolerance = 0.1;
Double targetratio = (double) w/h;
if (sizes = null) return null;

Size optimalsize = null;
Double Mindiff = Double.max_value;

int targetheight = h;

Try to find a size match aspect ratio and size
for (Size size:sizes) {
Double ratio = (double) size.width/size.height;
if (Math.Abs (ratio-targetratio) > Aspect_tolerance) continue;
if (Math.Abs (size.height-targetheight) < Mindiff) {
optimalsize = size;
Mindiff = Math.Abs (size.height-targetheight);
}
}

Cannot find the one match the aspect ratio ignore the requirement
if (optimalsize = = null) {
Mindiff = Double.max_value;
for (Size size:sizes) {
if (Math.Abs (size.height-targetheight) < Mindiff) {
optimalsize = size;
Mindiff = Math.Abs (size.height-targetheight);
}
}
}
return optimalsize;
}
Later in the sample to have this code, it looks a lot more powerful. Unfortunately, first getsupportedpreviewsizes () This function is only after 2.1, I initially intend to use 1.6 development ... Ok i change, this does not say first, own handset already brushes to 2.1, this function's return value incredibly is null?! If you really want to use the old version, how to do??

In view of the software can be achieved, so there must be a way! Have to write this:

public class Supportedsizesreflect {
private static method parameters_getsupportedpreviewsizes = null;
private static method parameters_getsupportedpicturesizes = null;

static {
Initcompatibility ();
};

private static void Initcompatibility () {
try {
parameters_getsupportedpreviewsizes = Camera.Parameters.class.getMethod (
"Getsupportedpreviewsizes", new class[] {});

parameters_getsupportedpicturesizes = Camera.Parameters.class.getMethod (
"Getsupportedpicturesizes", new class[] {});

catch (Nosuchmethodexception nsme) {
Nsme.printstacktrace ();
parameters_getsupportedpreviewsizes = parameters_getsupportedpicturesizes = null;
}
}

/**
* Effective after Android 2.1
* @param p
* @return android1.x return null
*/
public static list<size> getsupportedpreviewsizes (Camera.parameters p) {
Return getsupportedsizes (P, parameters_getsupportedpreviewsizes);
}

public static list<size> getsupportedpicturesizes (Camera.parameters p) {
Return getsupportedsizes (P, parameters_getsupportedpicturesizes);
}

@SuppressWarnings ("Unchecked")
private static list<size> getsupportedsizes (Camera.parameters p, method method) {
try {
if (method!= null) {
Return (list<size>) Method.invoke (p);
} else {
return null;
}
catch (InvocationTargetException ite) {
Throwable cause = Ite.getcause ();
if (cause instanceof RuntimeException) {
throw (runtimeexception) cause;
else if (cause instanceof Error) {
throw (Error) cause;
} else {
throw new RuntimeException (ITE);
}
catch (Illegalaccessexception IE) {
return null;
}
}
}

Ah ah ~,リフレクションなんか, the big suspicion o Muhammad ... And then you're going to call it in a similar way.


@Override
public void surfacechanged (surfaceholder holder, int format, int width,int height) {

Camera.parameters params = Camera.getparameters ();

List<size> supportedpicturesizes
= supportedsizesreflect.getsupportedpicturesizes (params);
List<size> supportedpreviewsizes
= supportedsizesreflect.getsupportedpreviewsizes (params);

if (supportedpicturesizes!= null &&
supportedpreviewsizes!= NULL &&
Supportedpicturesizes.size () > 0 &&
Supportedpreviewsizes.size () > 0) {

2.x
picturesize = supportedpicturesizes.get (0);

int maxSize = 1280;
if (MaxSize > 0) {
for (Size size:supportedpicturesizes) {
if (maxSize >= Math.max (size.width,size.height)) {
picturesize = size;
Break
}
}
}

WindowManager WindowManager = (windowmanager) context.getsystemservice (Context.window_service);
Display display = Windowmanager.getdefaultdisplay ();
Displaymetrics displaymetrics = new Displaymetrics ();
Display.getmetrics (Displaymetrics);

Previewsize = Getoptimalpreviewsize (
Supportedpreviewsizes,
Display.getwidth (),
Display.getheight ());

Params.setpicturesize (Picturesize.width, picturesize.height);
Params.setpreviewsize (Previewsize.width, previewsize.height);

}
This.camera.setParameters (params);
try {
This.camera.setPreviewDisplay (holder);
catch (IOException e) {
E.printstacktrace ();
}
This.camera.startPreview ();
}

Crash countless times after summed up Ah, found that the program to write a bad mandatory end, the camera can not be opened again, kill are not, can only restart the phone is good. Reboot once again so slow, who knows there is more suitable for G2 row?

Oh there is another, preview the screen 90°, 2.X can be used Parameters.set ("Rotation", "90″), before the words must be written parameters.set (" Orientation "," Portrait "). But it is said that not all machines can be ...


It says that the camera is initialized, and if you think it's OK, it's a big mistake. The next thing makes people feel more headache.

In my application, do not need to take pictures of the picture stored, just to the preview of the image data processing is good, very natural I just use the onpreviewframe call, consider processing the data stream passed in.

Many posts on the Internet, and then use the Bitmapfactory Decodebytearray () function to parse the picture on the line, I tried it, found that this is downright lies, the data stream default is YCBCR_420_SP (although can be changed, But the other format may not be compatible), Decodebytearray () do not recognize! After SDK2.2, it seems to provide a yuvimage class to turn around (what does Google offer this excuse at the outset? , do you want to abandon the old machine?? Absolutely not (poor people understand the poor most)!

Fortunately, the world is always not lack of good people and cattle, someone to provide such a section of the conversion code:

static public void Decodeyuv420sp (int[] RGB, byte[] yuv420sp, int width, int height) {
Final int framesize = width * height;

for (int j = 0, YP = 0; j < height; J + +) {
int UVP = framesize + (j >> 1) * width, u = 0, v = 0;
for (int i = 0; i < width; i++, yp++) {
int y = (0xFF & ((int) YUV420SP[YP])-16;
if (Y < 0) y = 0;
if ((i & 1) = = 0) {
v = (0xFF & yuv420sp[uvp++])-128;
U = (0xFF & yuv420sp[uvp++])-128;
}

int y1192 = 1192 * y;
int r = (y1192 + 1634 * v);
int g = (y1192-833 * v-400 * u);
int B = (y1192 + 2066 * u);

if (r < 0) R = 0; else if (R > 262143) r = 262143;
if (g < 0) g = 0; else if (g > 262143) g = 262143;
if (b < 0) b = 0; else if (b > 262143) b = 262143;

RGB[YP] = 0xff000000 | ((R << 6) & 0xff0000) | ((G >> 2) & 0xff00) | ((b >>) & 0xff);
}
}
}

I am not very clear about the principle, but it can work here, for the time being ... And then you can have the finished rgb[] passed to Decodebytearray ().

By the way kindly put the use of SDK2.2 after the bar, if useful ...

public void Onpreviewframe (byte[] data, Camera arg1) {
FileOutputStream outstream = null;
try {
Yuvimage yuvimage = new Yuvimage (Data,imageformat.nv21,arg1.getparameters (). Getpreviewsize (). Width, Arg1.getparameters (). Getpreviewsize (). Height,null);
Bytearrayoutputstream BAOs = new Bytearrayoutputstream ();
Yuvimage.compresstojpeg (New Rect (0,0,arg1.getparameters (). Getpreviewsize (). Width,arg1.getparameters (). Getpreviewsize (). height), BAOs;

OutStream = new FileOutputStream (String.Format ("/sdcard/%d.jpg", System.currenttimemillis ());
Outstream.write (Baos.tobytearray ());
Outstream.close ();

LOG.D (TAG, "onpreviewframe-wrote bytes:" + data.length);
catch (FileNotFoundException e) {
E.printstacktrace ();
catch (IOException e) {
E.printstacktrace ();
finally {
}
Preview.this.invalidate ();
}


Oh, the resulting image rotated 90° (it seems that some models set setrotation (90) can be done, but still that sentence, not universal ah, and this is the API after 2.1. Turn it on manually ...


Matrix matrix = new Matrix ();
Matrix.postrotate (90);
Here's the RGB is just converted to deal with the Dongdong
Bitmap BMP = Bitmap.createbitmap (RGB, 0, W, W, H, Bitmap.Config.ARGB_4444);
Bitmap nbmp = Bitmap.createbitmap (BMP,
0, 0, bmp.getwidth (), Bmp.getheight (), Matrix, True);
Finally, normal ~ ~ ~

Taking into account the need to do identification, it is natural to turn it into grayscale images, the classic psychological formula Gray = r*0.299 + g*0.587 + b*0.114, but the mobile phone calculation speed is not so fast, so the floating-point operation or try to avoid it ~ then consider Gray = (r*299 + g*587 + b*114 + 500)/1000 or Gray = (r*30 + g*59 + b*11 + 50)/100. But division is always not fast enough, with the shift bar ... Gray = (r*19595 + g*38469 + b*7472) >> 16, slightly smaller, with Gray = (r*38 + g*75 + b*15) >> 7 is enough.

After a hard study, write the code in high spirits on the phone ran a bit, although not fast enough to come out, think is also a large load operation Ah, self-comfort customers should be able to have such patience.

At this time, I suddenly think of a very important thing!
I need is the gray scale, that is, the brightness of the air volume, and the beginning of the YUV, is not brightness chroma saturation?! Then the Y classification is not the gray value I need!! What I am doing, the hard turn into RGB, and then turn into brightness, full of support is not. Thinking of this, I immediately banged my head against the wall 99,181 times to mourn the memory of my brain cells that died in vain. Immediately rewrite, delete a lot of code, fast more, the effect is good ~ ~ Despise two hours ago of their own!

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.