如何将YUV图像的一部分发送到服务器?

时间:2011-01-24 03:22:26

标签: android

我的应用程序从YUV中的相机抓取预览帧并将其发送到服务器。我正在尝试更改它,因此它只会将部分图像(裁剪)发送到服务器。但是我想循环遍历字节数组并直接将裁剪后的图像发送到服务器,而不是创建一个Bitmap类并以这种方式裁剪它。

我的目标是尽可能高效。

有没有人有一些伪代码(甚至更好的实际代码)来裁剪YUV图像?

我希望代码可以像这样工作:

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(intToByteArray(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]);

我知道代码根本不起作用,但希望你能够了解我正在尝试做的事情。

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:2)

这是一个C代码片段,用于在YUV420帧上进行就地裁剪 请注意,裁剪矩形的宽度和高度以及左侧和顶部应均匀

    // 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;
}

与java或任何其他语言的对话相当容易,类似的aproach应该适用于不同的pix格式(yuv422,yuv444,...)

答案 1 :(得分:0)

在android中查看YuvImage。这提供了YUV图像裁剪的简单实现,但它以jpeg格式生成输出。

希望这有帮助。

答案 2 :(得分:0)

你可以试试这个: 此示例将相机帧发送到服务器

@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();
} 

或者在方法surfaceChanged中,你可以这样:

 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);
相关问题