Reputation: 1229
I am interested to capture only part of the cameraPreview. I have a rectangle which has a onTouchListener. I can use this to drag my region of interest anywhere on the camera preview. My ultimate goal is to capture only that part of the preview. But I am not able to find a way. Is there any API I can make use of? Can anyone guide me here.
Thanks
Upvotes: 2
Views: 3144
Reputation: 3608
There's no support for that in the API that I know of but I have successfully done something similar.
Basically you'll need to:
Note that there is no API supported YUV decoder until FROYO via the YuvImage class which you can use something like:
YuvImage yuvimage=new YuvImage(yuv,ImageFormat.NV21,width,height,null);
ByteArrayOutputStream baos=new ByteArrayOutputStream();
yuvimage.compressToJpeg(new Rect(0,0,width,height), 100, baos);
rgb = BitmapFactory.decodeByteArray(baos.toByteArray(), 0, baos.size());
If youre only going to support 2.2 and later, your could skip the temp bitmap and use the YuvImage.compressToJpeg to crop to your scaled rect.
For OS versions prior to 2.2 you'll need you own implementation of YUV decode which can be done as follows:
/**
* Decodes YUV frame to a buffer which can be use to create a bitmap
* decode Y, U, and V values on the YUV 420 buffer described as YCbCr_422_SP by Android
* @param out the outgoing array of RGB bytes
* @param fg the incoming frame bytes
* @param width of source frame
* @param height of source frame
* @throws NullPointerException
* @throws IllegalArgumentException
*/
public static void decodeYUV(int[] out, byte[] fg, int width, int height)
throws NullPointerException, IllegalArgumentException {
int sz = width * height;
if (out == null)
throw new NullPointerException("buffer out is null");
if (out.length < sz)
throw new IllegalArgumentException("buffer out size " + out.length
+ " < minimum " + sz);
if (fg == null)
throw new NullPointerException("buffer 'fg' is null");
if (fg.length < sz)
throw new IllegalArgumentException("buffer fg size " + fg.length
+ " < minimum " + sz * 3 / 2);
int i, j;
int Y, Cr = 0, Cb = 0;
for (j = 0; j < height; j++) {
int pixPtr = j * width;
final int jDiv2 = j >> 1;
for (i = 0; i < width; i++) {
Y = fg[pixPtr];
if (Y < 0)
Y += 255;
if ((i & 0x1) != 1) {
final int cOff = sz + jDiv2 * width + (i >> 1) * 2;
Cb = fg[cOff];
if (Cb < 0)
Cb += 127;
else
Cb -= 128;
Cr = fg[cOff + 1];
if (Cr < 0)
Cr += 127;
else
Cr -= 128;
}
int R = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5);
if (R < 0)
R = 0;
else if (R > 255)
R = 255;
int G = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1)
+ (Cr >> 3) + (Cr >> 4) + (Cr >> 5);
if (G < 0)
G = 0;
else if (G > 255)
G = 255;
int B = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6);
if (B < 0)
B = 0;
else if (B > 255)
B = 255;
out[pixPtr++] = (0xff000000 + (B << 16) + (G << 8) + R);
}
}
}
Upvotes: 2