2016-07-28 13 views
0

私はカスタム正方形カメラを作る必要があるプロジェクトに取り組んでいます。私は今、サンプルプロジェクトに取り組んでおり、コードをアップロードしています。カスタムスクエアカメラなので近いですが、カメラのプレビューが間違っています

ゲームの予定は、カメラのプレビューを開くことです。正方形のカメラであるという錯覚を与えるために、上にビューを描画します。フルスクリーンの画像を撮り、最後に画像を切り抜く。

すべてが計画どおりに進んでいるように見えますが、最終的に写真を撮ると、携帯電話に保存された全画面の画像の結果が、撮影した画像とは異なります。あなたが見ることができるように、私はギャラリーIに保存された絵を見たとき、私は

This is the picture I am taking, my camera preview

This is the same picture saved in my gallery

を見ることができます:私は期待された結果、問題が何であるかをお見せするために、最終的な結果を説明してみましょう私は写真を撮ったときに私のカメラのプレビューにない右側の壁の左側のデスクと部分を見ることができます。

私は私のカメラプレビュークラスで異なるものの多様性を試してみましたが、本のように私はこの記事に答えの一つで見つかったカメラプレビュークラス使用しています:私は現在、私のカメラを掲示していますAndroid Camera Preview Stretched

をプレビュークラスが必要ですが、私のmain/xmlなどが必要な場合は、それ以上のものを置くことができます。私は遠くに捜索したと感じますが、何が起こっているのか理解できません。ありがとう!

パブリッククラスCameraPreviewはSurfaceViewがSurfaceHolder.Callbackを{

private static final String TAG = "CameraPreview"; 

private Context mContext; 
private SurfaceHolder mHolder; 
private Camera mCamera; 
private List<Camera.Size> mSupportedPreviewSizes; 
private Camera.Size mPreviewSize; 

public CameraPreview(Context context, Camera camera) { 
    super(context); 
    mContext = context; 
    mCamera = camera; 

    // supported preview sizes 
    mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes(); 
    for(Camera.Size str: mSupportedPreviewSizes) 
     Log.e(TAG, str.width + "/" + str.height); 

    // Install a SurfaceHolder.Callback so we get notified when the 
    // underlying surface is created and destroyed. 
    mHolder = getHolder(); 
    mHolder.addCallback(this); 
    // deprecated setting, but required on Android versions prior to 3.0 
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
} 

public void surfaceCreated(SurfaceHolder holder) { 
    // empty. surfaceChanged will take care of stuff 
} 

public void surfaceDestroyed(SurfaceHolder holder) { 
    // empty. Take care of releasing the Camera preview in your activity. 
} 

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    Log.e(TAG, "surfaceChanged => w=" + w + ", h=" + h); 
    // If your preview can change or rotate, take care of those events here. 
    // Make sure to stop the preview before resizing or reformatting it. 
    if (mHolder.getSurface() == null){ 
     // preview surface does not exist 
     return; 
    } 

    // stop preview before making changes 
    try { 
     mCamera.stopPreview(); 
    } catch (Exception e){ 
     // ignore: tried to stop a non-existent preview 
    } 

    // set preview size and make any resize, rotate or reformatting changes here 
    // start preview with new settings 
    try { 

     Camera.Parameters parameters = mCamera.getParameters(); 
     parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); 
     parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 
     mCamera.setParameters(parameters); 
     mCamera.setDisplayOrientation(90); 
     mCamera.setPreviewDisplay(mHolder); 
     mCamera.startPreview(); 

    } catch (Exception e){ 
     Log.d(TAG, "Error starting camera preview: " + e.getMessage()); 
    } 
} 

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); 
    final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); 

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

    float ratio; 
    if(mPreviewSize.height >= mPreviewSize.width) 
     ratio = (float) mPreviewSize.height/(float) mPreviewSize.width; 
    else 
     ratio = (float) mPreviewSize.width/(float) mPreviewSize.height; 

//  One of these methods should be used, second method squishes preview slightly 
     setMeasuredDimension(width, (int) (width * ratio)); 
//  setMeasuredDimension((int) (width * ratio), height); 

    float camHeight = (int) (width * ratio); 
    float newCamHeight; 
    float newHeightRatio; 

    if (camHeight < height) { 
     newHeightRatio = (float) height/(float) mPreviewSize.height; 
     newCamHeight = (newHeightRatio * camHeight); 
     Log.e(TAG, camHeight + " " + height + " " + mPreviewSize.height + " " + newHeightRatio + " " + newCamHeight); 
     setMeasuredDimension((int) (width * newHeightRatio), (int) newCamHeight); 
     Log.e(TAG, mPreviewSize.width + " | " + mPreviewSize.height + " | ratio - " + ratio + " | H_ratio - " + newHeightRatio + " | A_width - " + (width * newHeightRatio) + " | A_height - " + newCamHeight); 
    } else { 
     newCamHeight = camHeight; 
     setMeasuredDimension(width, (int) newCamHeight); 
     Log.e(TAG, mPreviewSize.width + " | " + mPreviewSize.height + " | ratio - " + ratio + " | A_width - " + (width) + " | A_height - " + newCamHeight); 
    } 
} 

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

    if (sizes == null) 
     return null; 

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

    int targetHeight = h; 

    for (Camera.Size size : sizes) { 
     double ratio = (double) size.height/size.width; 
     if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) 
      continue; 

     if (Math.abs(size.height - targetHeight) < minDiff) { 
      optimalSize = size; 
      minDiff = Math.abs(size.height - targetHeight); 
     } 
    } 

    if (optimalSize == null) { 
     minDiff = Double.MAX_VALUE; 
     for (Camera.Size size : sizes) { 
      if (Math.abs(size.height - targetHeight) < minDiff) { 
       optimalSize = size; 
       minDiff = Math.abs(size.height - targetHeight); 
      } 
     } 
    } 

    return optimalSize; 
} 

}

答えて

0

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

 
    SurfaceView mSurfaceView; 
 
    SurfaceHolder mHolder; 
 
    Size mPreviewSize; 
 
    List<Size> mSupportedPreviewSizes; 
 
    Camera mCamera; 
 
    Context context; 
 
    boolean surfaceExists = false; 
 
    boolean isPreview = false; 
 
    static int wid = 0; 
 
    static int hig = 0; 
 
    
 

 
    int y = 0; 
 
    private static final double ASPECT_RATIO = 3.0/4.0; 
 
    private static final int PICTURE_SIZE_MAX_WIDTH = 1280; 
 
    private static final int PREVIEW_SIZE_MAX_WIDTH = 3264; 
 
    Preview(Context context, SurfaceView sv) { 
 
     super(context); 
 
     this.context=context; 
 
     mSurfaceView = sv; 
 
\t \t mHolder = mSurfaceView.getHolder(); 
 
     mHolder.addCallback(this); 
 
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
 
    } 
 

 
    @Override 
 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
 
     
 
    \t int height = MeasureSpec.getSize(heightMeasureSpec); 
 
     int width = MeasureSpec.getSize(widthMeasureSpec); 
 

 
     if (width > height * ASPECT_RATIO) { 
 
      width = (int) (height * ASPECT_RATIO + .5); 
 
     } else { 
 
      height = (int) (width/ASPECT_RATIO + .5); 
 
     } 
 

 
     setMeasuredDimension(width, height); 
 
    } 
 
public void determineDisplayOrientation(Camera camera) { 
 
     CameraInfo cameraInfo = new CameraInfo(); 
 
     Camera.getCameraInfo(0, cameraInfo); 
 

 
     Display display = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 
 
     int rotation = display.getRotation(); 
 
     int degrees = 0; 
 

 
     switch (rotation) { 
 
      case Surface.ROTATION_0: 
 
       degrees = 0; 
 
       break; 
 

 
      case Surface.ROTATION_90: 
 
       degrees = 90; 
 
       break; 
 

 
      case Surface.ROTATION_180: 
 
       degrees = 180; 
 
       break; 
 

 
      case Surface.ROTATION_270: 
 
       degrees = 270; 
 
       break; 
 
     } 
 
     int displayOrientation; 
 

 
     if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 
 
      displayOrientation = (cameraInfo.orientation + degrees) % 360; 
 
      displayOrientation = (360 - displayOrientation) % 360; 
 
     } else { 
 
      displayOrientation = (cameraInfo.orientation - degrees + 360) % 360; 
 
     } 
 

 
     camera.setDisplayOrientation(displayOrientation); 
 

 
    } 
 
    @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) { 
 
      \t 
 
       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. 
 
    \t try { 
 
    \t \t if (mCamera != null) { 
 
    \t   \t mHolder.removeCallback(this); 
 
    \t    mCamera.stopPreview(); 
 
    \t    mCamera.release(); 
 
    \t   } 
 
\t \t } catch (Exception e) { 
 
\t \t \t // TODO: handle exception 
 
\t \t \t e.printStackTrace(); 
 
\t \t } 
 
    } 
 
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) { 
 
    \t 
 
    \t wid = w; 
 
    \t hig = h; 
 
    \t 
 
    \t 
 
    } 
 
    private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters){ 
 
     Camera.Size bestSize = null; 
 
     List<Camera.Size> sizeList = parameters.getSupportedPreviewSizes(); 
 
     
 
     bestSize = sizeList.get(0); 
 
     
 
     for(int i = 1; i < sizeList.size(); i++){ 
 
     if((sizeList.get(i).width * sizeList.get(i).height) > 
 
      (bestSize.width * bestSize.height)){ 
 
      bestSize = sizeList.get(i); 
 
     } 
 
     } 
 

 
     return bestSize; 
 
     } 
 
    
 
    public void setupCamera(Camera camera,boolean isResolutionHigh) { 
 
    \t mCamera = camera; 
 
    \t if (mCamera != null) { 
 
    \t \t determineDisplayOrientation(mCamera); 
 
    \t Camera.Parameters myParameters = mCamera.getParameters(); 
 
    \t \t 
 
    \t \t if(isResolutionHigh){ 
 
    \t  
 
     \t  Camera.Size myBestSize = getBestPreviewSize(wid, hig, myParameters); 
 
     \t  
 
     \t if(myBestSize != null){ 
 
     \t  myParameters.setPreviewSize(myBestSize.width, myBestSize.height); 
 
     \t  mCamera.setParameters(myParameters); 
 
     \t  mCamera.startPreview(); 
 
     \t  isPreview = true; 
 
     \t  
 
     \t  
 
     \t  } 
 
     \t  
 
    \t \t } 
 
    \t \t 
 
    \t \t else{ 
 
    \t \t \t 
 
    \t \t \t Size bestPreviewSize = determineBestPreviewSize(myParameters); 
 
    \t \t  Size bestPictureSize = determineBestPictureSize(myParameters); 
 

 
    \t \t  myParameters.setPreviewSize(bestPreviewSize.width, bestPreviewSize.height); 
 
    \t \t  myParameters.setPictureSize(bestPictureSize.width, bestPictureSize.height); 
 
    \t \t  myParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 
 

 
    \t \t  mCamera.setParameters(myParameters); 
 
    \t \t } 
 
    \t } 
 
    } 
 
    private Size determineBestPreviewSize(Camera.Parameters parameters) { 
 
     List<Size> sizes = parameters.getSupportedPreviewSizes(); 
 

 
     return determineBestSize(sizes, PREVIEW_SIZE_MAX_WIDTH); 
 
    } 
 

 
    private Size determineBestPictureSize(Camera.Parameters parameters) { 
 
     List<Size> sizes = parameters.getSupportedPictureSizes(); 
 

 
     return determineBestSize(sizes, PICTURE_SIZE_MAX_WIDTH); 
 
    } 
 

 
    protected Size determineBestSize(List<Size> sizes, int widthThreshold) { 
 
     Size bestSize = null; 
 

 
     for (Size currentSize : sizes) { 
 
      boolean isDesiredRatio = (currentSize.width/4) == (currentSize.height/3); 
 
      boolean isBetterSize = (bestSize == null || currentSize.width > bestSize.width); 
 
      boolean isInBounds = currentSize.width <= PICTURE_SIZE_MAX_WIDTH; 
 

 
      if (isDesiredRatio && isInBounds && isBetterSize) { 
 
       bestSize = currentSize; 
 
      } 
 
     } 
 

 
     if (bestSize == null) { 
 
      // listener.onCameraError(); 
 

 
      return sizes.get(0); 
 
     } 
 

 
     return bestSize; 
 
    } 
 
    } 
 
    }

+0

ThankssそれをTRY実装延び、私はこれを試みたが、イムはまだ有します同じ問題?あなたはこの問題を解決できましたか?私も別のデバイスで試した –

+0

私は正方形のカメラを使用していたとサムスンS5の私の問題を解決した.... – Andolasoft

+0

サムスンS5以外のすべてのデバイスで動作している上記のコード – Andolasoft

関連する問題