2015-09-22 6 views
0

Я сделал свою собственную пользовательскую камеру. Это дает мне плохое пиксельное изображение, я не знаю, почему. Я использую сжатие JPEG со 100 качеством. И это изображение я получаю Camera pictureПлохое неравномерное изображение - пользовательская камера для Android

Это мой код:

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.

Смежные вопросы