2013-03-28 81 views
7

嗨,我有一個自定義相機,我點擊按鈕,點擊它捕捉圖像...一切都很好,但在一些設備預覽拉伸,預覽覆蓋一半屏幕和閃爍...一些奇怪的不良影響。如何解決這個問題?在一些設備的Android自定義相機問題

這是我的代碼:

攝像頭活動:

preview = new Preview(this, (SurfaceView) findViewById(R.id.surfaceView)); 

preview.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); 

((FrameLayout) findViewById(R.id.preview)).addView(preview); 

preview.setKeepScreenOn(true); 

buttonClick = (Button) findViewById(R.id.buttonClick); 

buttonClick.setOnClickListener(new OnClickListener() { 
    public void onClick(View v) { 
     // preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback); 
     camera.takePicture(shutterCallback, rawCallback, jpegCallback); 
     // camera.setDisplayOrientation(90); 
     } 
}); 

預覽類:

class Preview extends ViewGroup implements SurfaceHolder.Callback { 
    private final String TAG = "Preview"; 

    SurfaceView mSurfaceView; 
    SurfaceHolder mHolder; 
    Size mPreviewSize; 
    List<Size> mSupportedPreviewSizes; 
    Camera mCamera; 

    @SuppressWarnings("deprecation") 
    Preview(Context context, SurfaceView sv) { 
     super(context); 

     mSurfaceView = sv; 
     // addView(mSurfaceView); 

     mHolder = mSurfaceView.getHolder(); 
     mHolder.addCallback(this); 
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

    public void setCamera(Camera camera) { 
     mCamera = camera; 
     if (mCamera != null) { 

      // get Camera parameters 
      Camera.Parameters params = mCamera.getParameters(); 

      mSupportedPreviewSizes = params.getSupportedPreviewSizes(); 
      requestLayout(); 

      List<String> focusModes = params.getSupportedFocusModes(); 
      if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) { 
       // set the focus mode 
       params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); 
       // set Camera parameters 
       mCamera.setParameters(params); 
      } 
     } 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     // We purposely disregard child measurements because act as a 
     // wrapper to a SurfaceView that centers the camera preview instead 
     // of stretching it. 
     final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); 
     final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); 
     setMeasuredDimension(width, height); 

     if (mSupportedPreviewSizes != null) { 
      mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height); 
     } 
    } 

    @Override 
    protected void onLayout(boolean changed, int l, int t, int r, int b) { 
     if (changed && getChildCount() > 0) { 
      final View child = getChildAt(0); 

      final int width = r - l; 
      final int height = b - t; 

      int previewWidth = width; 
      int previewHeight = height; 
      if (mPreviewSize != null) { 
       previewWidth = mPreviewSize.width; 
       previewHeight = mPreviewSize.height; 
      } 

      // Center the child SurfaceView within the parent. 
      if (width * previewHeight > height * previewWidth) { 
       final int scaledChildWidth = previewWidth * height/previewHeight; 
       child.layout((width - scaledChildWidth)/2, 0, (width + scaledChildWidth)/2, height); 
      } else { 
       final int scaledChildHeight = previewHeight * width/previewWidth; 
       child.layout(0, (height - scaledChildHeight)/2, width, (height + scaledChildHeight)/2); 
      } 
     } 
    } 

    public void surfaceCreated(SurfaceHolder holder) { 
     // The Surface has been created, acquire the camera and tell it where 
     // to draw. 
     try { 
      if (mCamera != null) { 
       mCamera.setPreviewDisplay(holder); 
      } 
     } catch (IOException exception) { 
      Log.e(TAG, "IOException caused by setPreviewDisplay()", exception); 
     } 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 
     // Surface will be destroyed when we return, so stop the preview. 
     if (mCamera != null) { 
      mCamera.stopPreview(); 
     } 
    } 

    private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { 
     final double ASPECT_TOLERANCE = 0.1; 
     double targetRatio = (double) w/h; 
     if (sizes == null) 
      return null; 

     Size optimalSize = null; 
     double minDiff = Double.MAX_VALUE; 

     int targetHeight = h; 

     // Try to find an size match aspect ratio and size 
     for (Size size : sizes) { 
      double ratio = (double) size.width/size.height; 
      if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) 
       continue; 
      if (Math.abs(size.height - targetHeight) < minDiff) { 
       optimalSize = size; 
       minDiff = Math.abs(size.height - targetHeight); 
      } 
     } 

     // Cannot find the one match the aspect ratio, ignore the requirement 
     if (optimalSize == null) { 
      minDiff = Double.MAX_VALUE; 
      for (Size size : sizes) { 
       if (Math.abs(size.height - targetHeight) < minDiff) { 
        optimalSize = size; 
        minDiff = Math.abs(size.height - targetHeight); 
       } 
      } 
     } 
     return optimalSize; 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     if (mCamera != null) { 
      Camera.Parameters parameters = mCamera.getParameters(); 
      parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); 
      requestLayout(); 

      mCamera.setParameters(parameters); 
      mCamera.startPreview(); 
     } 
    } 

} 
+0

我在Sony Xperia –

+0

@ZalaJanaksinh中有同樣的問題,您的手機上是否安裝了McAfee Antivirus? http://talk.sonymobile.com/thread/47893?start=0&tstart=0 –

+0

@ZalaJanaksinh,其實,你必須已經安裝了McAfee因爲它來自於索尼的Xperia預裝。完整地閱讀線索的鏈接。這個解決方案可能無法解決Sukamo的問題,因爲他沒有告訴我們哪些手機受到影響,但至少應該解決你的問題。 –

回答

1

McAfee防病毒可能在這個case的罪魁禍首。

在這種情況下,卸載它應該可以解決問題。