2015-09-22 25 views
0

我已經制作了我自己的自定義相機。這給了我不好的像素化圖像,我不知道爲什麼。我可以使用JPEG壓縮100質量。而且這是圖片,我得到 Camera picture壞pixelated圖像 - 自定義安卓相機

這是我的代碼:

public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback { 
private SurfaceHolder mHolder; 
private Context mContext; 
private Camera.Parameters parameters; 
private byte[] mBuffer; 

public CameraSurfaceView(Context context) { 
    super(context); 
    mContext = context; 
    mHolder = getHolder(); 
    mHolder.addCallback(this); 
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
} 

public void surfaceCreated(SurfaceHolder holder) { 
    // The Surface has been created, now tell the camera where to draw the preview. 
    try { 
     if (CameraConfigurationUtils.mCameraInstance != null) { 
      CameraConfigurationUtils.mCameraInstance.setDisplayOrientation(90); 
      CameraConfigurationUtils.mCameraInstance.setPreviewDisplay(holder); 
      parameters = CameraConfigurationUtils.mCameraInstance.getParameters(); 
      if (android.os.Build.VERSION.SDK_INT >= 14) { 
       CameraConfigurationUtils.setFocus(parameters, true, true, false); 
      } else { 
       CameraConfigurationUtils.setFocus(parameters, true, true, true); 
      } 
      WindowManager manager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 
      Display display = manager.getDefaultDisplay(); 
      Point theScreenResolution = new Point(); 
      theScreenResolution.set(display.getHeight(), display.getWidth()); 
      CameraConfigurationUtils.findBestPreviewSizeValue(parameters, theScreenResolution); 
      CameraConfigurationUtils.mCameraInstance.setParameters(parameters); 
      updateBufferSize(); 
      CameraConfigurationUtils.mCameraInstance.addCallbackBuffer(mBuffer); 
      CameraConfigurationUtils.mCameraInstance.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() { 
       public synchronized void onPreviewFrame(byte[] data, Camera c) { 
        if (CameraConfigurationUtils.mCameraInstance != null) { 
         CameraConfigurationUtils.mCameraInstance.addCallbackBuffer(mBuffer); 
        } 
       } 
      }); 
      CameraConfigurationUtils.startPreview(mContext); 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
     CameraConfigurationUtils.releaseCamera(); 
    } 

} 

public void surfaceDestroyed(SurfaceHolder holder) { 
    mHolder.removeCallback(this); 
    CameraConfigurationUtils.stopPreview(); 
} 

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    if (mHolder.getSurface() == null) { 
     return; 
    } 
    try { 
     CameraConfigurationUtils.mCameraInstance.setPreviewDisplay(mHolder); 
     CameraConfigurationUtils.startPreview(mContext); 
    } catch (Exception e) { 
     CameraConfigurationUtils.releaseCamera(); 
    } 
} 

public byte[] getPic(int x, int y, int width, int height) { 
    System.gc(); 
    Camera.Size s = parameters.getPreviewSize(); 
    YuvImage yuvimage = new YuvImage(mBuffer, ImageFormat.NV21, s.width, s.height, null); 
    ByteArrayOutputStream outStream = new ByteArrayOutputStream(); 
    yuvimage.compressToJpeg(new Rect(x, y, width, height), 100, outStream); // make JPG 

    yuvimage = null; 
    System.gc(); 
    return outStream.toByteArray(); 
} 

private void updateBufferSize() { 
    mBuffer = null; 
    System.gc(); 
    // prepare a buffer for copying preview data to 
    int h = parameters.getPreviewSize().height; 
    int w = parameters.getPreviewSize().width; 
    int bitsPerPixel = ImageFormat.getBitsPerPixel(parameters.getPreviewFormat()); 
    mBuffer = new byte[w * h * bitsPerPixel/8]; 
    //Log.i("surfaceCreated", "buffer length is " + mBuffer.length + " bytes"); 
} 

}

我到底做錯了什麼?

回答

1

您的圖片示例看起來就像是從攝像機反饋的普通較低分辨率預覽圖像,但我可以看到在高分辨率屏幕中它會顯示像素化。我相信,你的問題就出在這部分代碼:

CameraConfigurationUtils.findBestPreviewSizeValue(parameters, theScreenResolution); 
CameraConfigurationUtils.mCameraInstance.setParameters(parameters); 

看起來你是剛剛計算出最佳的預覽大小,這是返回到你,但你不能將其設置爲實際的預覽大小。試着這樣說:

Point bestPreviewSize = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, theScreenResolution); 
parameters.setPreviewSize(bestPreviewSize.x, bestPreviewSize.y); 
CameraConfigurationUtils.mCameraInstance.setParameters(parameters); 

另一件事是,如果你的目的是要拍攝高分辨率照片,你不應該用你的getPic()方法做,因爲這是剛開的預覽框爲JPEG,這是一個低分辨率的圖像。你應該看看Camera#takePicture method