I decoded the RGB color data from the Android Camera PreviewCallback
onPreviewFrame() frame.
My function that decodes the YUV byte[] buffer from the preview
callback and converts it into an ARGB_8888 int[] buffer is presented
below.

The luminance buffer takes up the first width * height bytes of the
byte buffer and can be displayed as a gray-scale image if desiered.
The chromonance follows with each U or V value representing a 2x2
square region of 4 luminance values. The bytes are packed as follows
(display in monospaced font to view as grid):
Y1a Y1b Y2c Y2d Y3e Y3f
Y1g Y1h Y2i Y2j Y3k Y3l
Y4m Y4n Y5o Y5p Y6q Y6r
Y4s Y4t Y5u Y5v Y6w Y6x
U1  V1  U2  V2  U3  V3
U4  V4  U5  V5  U6  V6

I strongly believe that Google, you should have told us this
yourselves and saved me several days.

This code has been tested on the HTC G1 device processing 480x320 size
frames.  Similar functions downrez in the same single pass through the
image to a smaller frame size for full display on the screen at a
faster rate.  Note: this processing must be done in a separate Thread
from onPreviewFrame().

// decode Y, U, and V values on the YUV 420 buffer described as
YCbCr_422_SP by Android
// David Manpearl 081201
public static void decodeYUV(int[] out, byte[] fg, int width, int
height) throws NullPointerException, IllegalArgumentException {
        final 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;
                }
        }
}

On Dec 1, 8:52 am, Dave Sparks <[EMAIL PROTECTED]> wrote:
> The G1 preview format is YUV 420 semi-planar (U and V are subsampled
> by 2 in both X and Y). The Y plane is first, followed by UV pairs - I
> believe the U sample comes first in the pair.
>
> Technically it's YCbCr 420 semi-planar, but very few people use that
> term.
>
> On Nov 26, 6:27 pm, dmanpearl <[EMAIL PROTECTED]> wrote:
>
>
>
> > Hello Blindfold,
>
> > Thanks for your help.  I solved the user interface problems I was
> > experiencing by using a separate thread to do my image processing. I'm
> > still using an ImageView, and without problems.  Perhaps I will try a
> > Canvas in a SurfaceHolder later in this exercise to compare speeds.
>
> > MORE ON THE CAMERA LIVE PREVIEW FILTERED DISPLAY CAPABILITY
>
> > As you know, I want to display live camera data through a custom
> > filter.
>
> > I got most of the way through theYCbCr_422_SPdata buffer returned to
> > Android's Camera.PreviewCallback onCameraFrame() callback function,
> > and now I am looking for help decyphering the U, V portion of the
> > buffer.  I verified that the first (width*height) bytes are simple Y
> > luminance values that can be displayed (via Bitmap and ImageView) to
> > make a viable gray-scale image.  The total number of bytes are (width
> > * height * 3 / 2).
>
> > The remaining 1/2 image bytes are clearly used to store U, V (Cb, Cr)
> > data.  Therefore, there are 1/4 image bytes for each U, V component
> > (i.e. each U, V component is used for 4 pixels of the image).  This
> > looks like 411 or 420 data, not 422, but we have bigger fish to fry.
>
> > I cannot determine if the U V data is aligned adjacently, in
> > alternating rows, or in squares as described in this Wikipedia
> > graphical description:  http://en.wikipedia.org/wiki/Image:Yuv420.svg.
> > Once I finally determine the structure of the U, V data, I have
> > several equations to convert from YUV to RGB and I have tried many
> > ways of combining the UV data with the luminance data of the first 2/3
> > of the buffer to no avail.  So far I can only display mono-chrome.
>
> > If you or others on this list can decode the AndroidYCbCr_422_SP
> > data, please post the solution as soon as possible.  Your efforts and
> > generosity are greatly appreciated.  I am convinced that
> > representatives from Google/Android and others monitoring this list
> > know how to do this.  Please share the information.  It is crutial to
> > our project.  I do not care about the Emulator and it's different
> > encoding.  I realize that Google is probably waiting to implement a
> > unified solution and share it through an API update, but we cannot
> > wait.
>
> >  - Thank you, David Manpearl
>
> > On Nov 26, 10:23 am, blindfold <[EMAIL PROTECTED]> wrote:
>
> > > Hi David,
>
> > > > I can't seem to make coexist: SurfaceHolder for the camera & ImageView
> > > > for the filtered Bitmap to display.
>
> > > ...
>
> > > > Do you know why I can't make the Camera's Surface and an ImageView
> > > > Bitmap simultaneous members of the same active ViewGroup?
>
> > > I do not use ImageView myself so I cannot really judge your problem. I
> > > draw my filtered Bitmap to a Canvas in a SurfaceView. No ImageView
> > > anywhere.
>
> > > Regards- Hide quoted text -
>
> - Show quoted text -
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
[EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to