开发者

How to send part of a YUV image to a server?

开发者 https://www.devze.com 2023-02-06 14:13 出处:网络
My application grabs a preview frame from the camera in YUV and sends it to a server.I\'m trying to change it so it will only send part of the image (a crop) to the server.However I want to loop throu

My application grabs a preview frame from the camera in YUV and sends it to a server. I'm trying to change it so it will only send part of the image (a crop) to the server. However I want to loop through the byte array and directly send the cropped image to the server, rather than creating a Bitmap class and cropping it that way.

My goal is to be as efficient as possible.

Does anyone have some pseudocode (or even better actual code) for cropping YUV images?

I'd like the code to work something like this:

OutputStream out = clientSocket.getOutputStream();
byte[] preview = getCameraPreview();
//Crop half of the image
int x = (int)(getX()/2);
int y = (int)(getY()/2);
//Send the width, height, and image size to the server
out.write(intToByteArray(x));
out.write(intToByt开发者_运维百科eArray(y));
out.write(intToByteArray((int)(x*y)));
//Start sending the picture to the server
for(int i = 0; i < y; i++)
    for(int j = 0; j < x; j++)
        out.write(preview[i+j]);

I know that code doesn't work at all, but hopefully you get the idea of what I'm trying to do.

Any help will be appreciated.


this is a C code snippet to do an in-place crop on a YUV420 frame note that width and height and left and top of crop rectangle should be even

    // original frame
unsigned char mYUVFrame[frameSize];

    // crop position
int lo_x, lo_y, hi_x, hi_y;

    // original size of frame
int width, height;
int new_width = (hi_x-lo_x)+1;
int new_height = (hi_y-lo_y)+1;

unsigned char *orig_pos, *new_pos;
// Y
orig_pos = mYUVFrame + lo_y*width + lo_x;
new_pos = mYUVFrame;
for (int i=0; i<new_height; i++)
{
    memmove(new_pos, orig_pos, new_width);
    orig_pos += width;
    new_pos += new_width;
}
// Cb
orig_pos = mYUVFrame + width*height + lo_x/2 + lo_y*width/4;
new_pos = mYUVFrame+new_width*new_height;
for (int i=0; i<new_height/2; i++)
{
    memmove(new_pos, orig_pos, new_width/2);
    orig_pos += width/2;
    new_pos += new_width/2;
}
// Cr
orig_pos = mYUVFrame + (width*height*5)/4 + lo_x/2 + lo_y*width/4;
new_pos = mYUVFrame + (new_width*new_height*5)/4;
for (int i=0; i<new_height/2; i++)
{
    memmove(new_pos, orig_pos, new_width/2);
    orig_pos += width/2;
    new_pos += new_width/2;
}

conversation to java or anyother language is fairly easy and a similar aproach should work for different pix formats(yuv422, yuv444, ...)


Have a look at YuvImage in android. This provides an easy implementation of YUV image cropping but it produces its output in jpeg format.

Hope this helps.


you can try this: This example send camera frames to server

@Override 
        public void onPreviewFrame(byte[] data, Camera camera) {
        try { 
            byte[] baos = convertYuvToJpeg(data, camera);
            StringBuilder dataBuilder = new StringBuilder();
            dataBuilder.append("data:image/jpeg;base64,").append(Base64.encodeToString(baos, Base64.DEFAULT));
            mSocket.emit("newFrame", dataBuilder.toString());
        } catch (Exception e) {
           Log.d("########", "ERROR");
        } 
    } 

}; 


public byte[] convertYuvToJpeg(byte[] data, Camera camera) {

    YuvImage image = new YuvImage(data, ImageFormat.NV21,
            camera.getParameters().getPreviewSize().width, camera.getParameters().getPreviewSize().height, null); 

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    int quality = 20; //set quality
    image.compressToJpeg(new Rect(0, 0, camera.getParameters().getPreviewSize().width, camera.getParameters().getPreviewSize().height), quality, baos);//this line you can crop the image quality  


    return baos.toByteArray();
} 

Or in method surfaceChanged, you can this:

 for(Camera.Size size: mCamera.getParameters().getSupportedPreviewSizes()){
                Log.d("123###########", String.valueOf(size.width)+" x "+String.valueOf(size.height)); //Size preview

            }
            Camera.Parameters mParameters = mCamera.getParameters();

            mParameters.setPreviewSize(720, 480);////set Size preview available
            mCamera.setParameters(mParameters);
0

精彩评论

暂无评论...
验证码 换一张
取 消