2011-01-24 3 views
0

私のアプリケーションは、YUVのカメラからプレビューフレームを取得し、それをサーバーに送信します。私はそれを変更しようとしているので、画像の一部(作物)をサーバーに送るだけです。しかし、私はバイト配列をループして、ビットマップクラスを作成してそのように切り取るのではなく、切り取ったイメージを直接サーバーに送りたいと思っています。YUVイメージの一部をサーバーに送る方法は?

私の目標はできるだけ効率的にすることです。

誰かが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]); 

を私はコードが全く動作しないことを知っているが、うまくいけば、あなたは私が何をしようとしているのアイデアを得ます。

ご協力いただければ幸いです。

+0

あなたがこれに対する答えを見つけましたか?これはまさに私が今必要としていることです。 – SamRowley

答えて

0

androidでYuvImageをご覧ください。これにより、YUV画像のクロッピングは簡単に実行できますが、出力はJPEG形式で出力されます。

これが役に立ちます。

+0

カメラがフレームを送信している間にこのトリミングを行いたい場合、これは遅すぎるかもしれません。 –

2

これはYUV420フレーム 幅ノートと高さにインプレース作物を行うにはCのコードスニペットで、左と作物の長方形の上でも

// 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あなたはこれを試すことができ

+0

あなたの答えは非常に有望ですが、コードは実際には機能しません。他のオープンソースのプロジェクトやチュートリアルでそれをお持ちですか?それで、あなたが使っている文脈は何ですか? –

0

異なるPIXフォーマット(YUV422、YUV444、...)のために働く必要があります。サーバーへのカメラのフレームを送信 この例

@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); 
関連する問題