2015-10-01 30 views
-3

請告訴我如何在instagram應用中創建一個方形尺寸的相機,就像在instagram中一樣?我在很長一段時間尋找解決方案,但我找不到它。如何爲android創建一個方形尺寸的相機

+0

歡迎計算器。請參閱[我如何提出一個好問題](http://stackoverflow.com/help/how-to-ask) – Prudhvi

+2

您是否可以在攝像頭視圖頂部使用疊加層。然後稍後裁剪照片 – Woodsy

+0

並且沒有辦法直接使用相機來做到這一點? – AnzBAM

回答

1

你不能創建一個方形大小的相機,它完全取決於設備。

基本上每個設備都有自己的相機尺寸,你可以得到所有設備尺寸的 列表,然後設置你喜歡的一個...!

這裏是一個攝像頭預覽類自動設置好大小的攝像機視圖,

import java.io.IOException; 
import java.util.List; 

import android.content.res.Configuration; 
import android.hardware.Camera; 
import android.hardware.Camera.PreviewCallback; 
import android.os.Build; 
import android.util.Log; 
import android.view.Display; 
import android.view.Surface; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.widget.RelativeLayout; 
import android.widget.Toast; 
/** 
* This class assumes the parent layout is RelativeLayout.LayoutParams. 
*/ 
@SuppressWarnings("deprecation") 
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 

    private static boolean DEBUGGING = true; 
    private static final String LOG_TAG = "CameraPreviewSample"; 
    private static final String CAMERA_PARAM_ORIENTATION = "orientation"; 
    private static final String CAMERA_PARAM_LANDSCAPE = "landscape"; 
    private static final String CAMERA_PARAM_PORTRAIT = "portrait"; 
    protected CameraActivity mActivity; 
    private SurfaceHolder mHolder; 
    protected Camera mCamera; 
    protected List<Camera.Size> mPreviewSizeList; 
    protected List<Camera.Size> mPictureSizeList; 
    protected Camera.Size mPreviewSize; 
    protected Camera.Size mPictureSize; 
    private int mSurfaceChangedCallDepth = 0; 
    private int mCameraId; 
    private LayoutMode mLayoutMode; 
    private int mCenterPosX = -1; 
    private int mCenterPosY; 
    public static boolean isSafeForTakeImage = false; 

    PreviewReadyCallback mPreviewReadyCallback = null; 

    public static enum LayoutMode 
    { 
     FitToParent, // Scale to the size that no side is larger than the parent 
     NoBlank // Scale to the size that no side is smaller than the parent 
    }; 

    public interface PreviewReadyCallback { 
     public void onPreviewReady(); 
    } 

    /** 
    * State flag: true when surface's layout size is set and surfaceChanged() 
    * process has not been completed. 
    */ 
    protected boolean mSurfaceConfiguring = false; 

    public CameraPreview(CameraActivity activity, int cameraId, LayoutMode mode) { 
     super(activity); // Always necessary 
     mActivity = activity; 
     mLayoutMode = mode; 
     mHolder = getHolder(); 
     mHolder.addCallback(this); 
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { 
      if (Camera.getNumberOfCameras() > cameraId) { 
       mCameraId = cameraId; 
      } else { 
       mCameraId = 0; 
      } 
     } else { 
      mCameraId = 0; 
     } 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { 
      mCamera = Camera.open(mCameraId); 
     } else { 
      mCamera = Camera.open(); 
     } 
     Camera.Parameters cameraParams = mCamera.getParameters(); 
     mPreviewSizeList = cameraParams.getSupportedPreviewSizes(); 
     mPictureSizeList = cameraParams.getSupportedPictureSizes(); 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     try 
     { 
      isSafeForTakeImage = true; 
      mCamera.setPreviewDisplay(mHolder); 
     } catch (IOException e) { 
      mCamera.release(); 
      mCamera = null; 
     } 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
     mSurfaceChangedCallDepth++; 
     doSurfaceChanged(width, height); 
     mSurfaceChangedCallDepth--; 
    } 

    private void doSurfaceChanged(int width, int height) 
    { 
     isSafeForTakeImage = false; 

     mCamera.stopPreview(); 

     Camera.Parameters cameraParams = mCamera.getParameters(); 
     // cameraParams.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 
     if(cameraParams.getSupportedFocusModes() != null 
       && cameraParams.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) 
     { 
      cameraParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 
     } 

     cameraParams.setRotation(90); 
     boolean portrait = isPortrait(); 

     // The code in this if-statement is prevented from executed again when surfaceChanged is 
     // called again due to the change of the layout size in this if-statement. 
     if (!mSurfaceConfiguring) { 
      Camera.Size previewSize = determinePreviewSize(portrait, width, height); 
      Camera.Size pictureSize = determinePictureSize(previewSize); 
      if (DEBUGGING) { Log.v(LOG_TAG, "Desired Preview Size - w: " + width + ", h: " + height); } 
      mPreviewSize = previewSize; 
      mPictureSize = pictureSize; 
//   mSurfaceConfiguring = adjustSurfaceLayoutSize(previewSize, portrait, width, height); 

      // Continue executing this method if this method is called recursively. 
      // Recursive call of surfaceChanged is very special case, which is a path from 
      // the catch clause at the end of this method. 
      // The later part of this method should be executed as well in the recursive 
      // invocation of this method, because the layout change made in this recursive 
      // call will not trigger another invocation of this method. 
      if (mSurfaceConfiguring && (mSurfaceChangedCallDepth <= 1)) { 
       return; 
      } 

     } 

     configureCameraParameters(cameraParams, portrait); 
     mSurfaceConfiguring = false; 

     try { 
      mCamera.startPreview(); 
      isSafeForTakeImage = true; 
     } catch (Exception e) { 
      Log.w(LOG_TAG, "Failed to start preview: " + e.getMessage()); 

      // Remove failed size 
      mPreviewSizeList.remove(mPreviewSize); 
      mPreviewSize = null; 

      // Reconfigure 
      if (mPreviewSizeList.size() > 0) { // prevent infinite loop 
       surfaceChanged(null, 0, width, height); 
      } else { 
       Toast.makeText(mActivity, "Can't start preview", Toast.LENGTH_LONG).show(); 
       Log.w(LOG_TAG, "Gave up starting preview"); 
      } 
     } 

     if (null != mPreviewReadyCallback) { 
      mPreviewReadyCallback.onPreviewReady(); 
     } 

     //TODO 
     mActivity.setMyCamera(mCamera); 
    } 

    /** 
    * @param cameraParams 
    * @param portrait 
    * @param reqWidth must be the value of the parameter passed in surfaceChanged 
    * @param reqHeight must be the value of the parameter passed in surfaceChanged 
    * @return Camera.Size object that is an element of the list returned from Camera.Parameters.getSupportedPreviewSizes. 
    */ 
    protected Camera.Size determinePreviewSize(boolean portrait, int reqWidth, int reqHeight) { 
     // Meaning of width and height is switched for preview when portrait, 
     // while it is the same as user's view for surface and metrics. 
     // That is, width must always be larger than height for setPreviewSize. 
     int reqPreviewWidth; // requested width in terms of camera hardware 
     int reqPreviewHeight; // requested height in terms of camera hardware 
     if (portrait) { 
      reqPreviewWidth = reqHeight; 
      reqPreviewHeight = reqWidth; 
     } else { 
      reqPreviewWidth = reqWidth; 
      reqPreviewHeight = reqHeight; 
     } 

     if (DEBUGGING) { 
      Log.v(LOG_TAG, "Listing all supported preview sizes"); 
      for (Camera.Size size : mPreviewSizeList) { 
       Log.v(LOG_TAG, " w: " + size.width + ", h: " + size.height); 
      } 
      Log.v(LOG_TAG, "Listing all supported picture sizes"); 
      for (Camera.Size size : mPictureSizeList) { 
       Log.v(LOG_TAG, " w: " + size.width + ", h: " + size.height); 
      } 
     } 

     // Adjust surface size with the closest aspect-ratio 
     float reqRatio = ((float) reqPreviewWidth)/reqPreviewHeight; 
     float curRatio, deltaRatio; 
     float deltaRatioMin = Float.MAX_VALUE; 
     Camera.Size retSize = null; 
     for (Camera.Size size : mPreviewSizeList) { 
      curRatio = ((float) size.width)/size.height; 
      deltaRatio = Math.abs(reqRatio - curRatio); 
      if (deltaRatio < deltaRatioMin) { 
       deltaRatioMin = deltaRatio; 
       retSize = size; 
      } 
     } 

     return retSize; 
    } 

    protected Camera.Size determinePictureSize(Camera.Size previewSize) { 
     Camera.Size retSize = null; 
     for (Camera.Size size : mPictureSizeList) { 
      if (size.equals(previewSize)) { 
       return size; 
      } 
     } 

     if (DEBUGGING) { Log.v(LOG_TAG, "Same picture size not found."); } 

     // if the preview size is not supported as a picture size 
     float reqRatio = ((float) previewSize.width)/previewSize.height; 
     float curRatio, deltaRatio; 
     float deltaRatioMin = Float.MAX_VALUE; 
     for (Camera.Size size : mPictureSizeList) { 
      curRatio = ((float) size.width)/size.height; 
      deltaRatio = Math.abs(reqRatio - curRatio); 
      if (deltaRatio < deltaRatioMin) { 
       deltaRatioMin = deltaRatio; 
       retSize = size; 
      } 
     } 

     return retSize; 
    } 

    protected boolean adjustSurfaceLayoutSize(Camera.Size previewSize, boolean portrait, 
      int availableWidth, int availableHeight) { 
     float tmpLayoutHeight, tmpLayoutWidth; 
     if (portrait) { 
      tmpLayoutHeight = previewSize.width; 
      tmpLayoutWidth = previewSize.height; 
     } else { 
      tmpLayoutHeight = previewSize.height; 
      tmpLayoutWidth = previewSize.width; 
     } 

     float factH, factW, fact; 
     factH = availableHeight/tmpLayoutHeight; 
     factW = availableWidth/tmpLayoutWidth; 
     if (mLayoutMode == LayoutMode.FitToParent) { 
      // Select smaller factor, because the surface cannot be set to the size larger than display metrics. 
      if (factH < factW) { 
       fact = factH; 
      } else { 
       fact = factW; 
      } 
     } else { 
      if (factH < factW) { 
       fact = factW; 
      } else { 
       fact = factH; 
      } 
     } 

     RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)this.getLayoutParams(); 

     int layoutHeight = (int) (tmpLayoutHeight * fact); 
     int layoutWidth = (int) (tmpLayoutWidth * fact); 
     if (DEBUGGING) { 
      Log.v(LOG_TAG, "Preview Layout Size - w: " + layoutWidth + ", h: " + layoutHeight); 
      Log.v(LOG_TAG, "Scale factor: " + fact); 
     } 

     boolean layoutChanged; 
     if ((layoutWidth != this.getWidth()) || (layoutHeight != this.getHeight())) { 
      layoutParams.height = layoutHeight; 
      layoutParams.width = layoutWidth; 
      if (mCenterPosX >= 0) { 
       layoutParams.topMargin = mCenterPosY - (layoutHeight/2); 
       layoutParams.leftMargin = mCenterPosX - (layoutWidth/2); 
      } 
      this.setLayoutParams(layoutParams); // this will trigger another surfaceChanged invocation. 
      layoutChanged = true; 
     } else { 
      layoutChanged = false; 
     } 

     return layoutChanged; 
    } 

    /** 
    * @param x X coordinate of center position on the screen. Set to negative value to unset. 
    * @param y Y coordinate of center position on the screen. 
    */ 
    public void setCenterPosition(int x, int y) { 
     mCenterPosX = x; 
     mCenterPosY = y; 
    } 

    protected void configureCameraParameters(Camera.Parameters cameraParams, boolean portrait) { 
     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { // for 2.1 and before 
      if (portrait) 
      { 
       cameraParams.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_PORTRAIT); 
      } 
      else 
      { 
       cameraParams.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_LANDSCAPE); 
      } 
     } else { // for 2.2 and later 
      int angle; 
      Display display = mActivity.getWindowManager().getDefaultDisplay(); 
      switch (display.getRotation()) { 
       case Surface.ROTATION_0: // This is display orientation 
        angle = 90; // This is camera orientation 
        break; 
       case Surface.ROTATION_90: 
        angle = 0; 
        break; 
       case Surface.ROTATION_180: 
        angle = 270; 
        break; 
       case Surface.ROTATION_270: 
        angle = 180; 
        break; 
       default: 
        angle = 90; 
        break; 
      } 
      Log.v(LOG_TAG, "angle: " + angle); 
      mCamera.setDisplayOrientation(angle); 
     } 

     cameraParams.setPreviewSize(mPreviewSize.width, mPreviewSize.height); 
     cameraParams.setPictureSize(mPictureSize.width, mPictureSize.height); 
     if (DEBUGGING) { 
      Log.v(LOG_TAG, "Preview Actual Size - w: " + mPreviewSize.width + ", h: " + mPreviewSize.height); 
      Log.v(LOG_TAG, "Picture Actual Size - w: " + mPictureSize.width + ", h: " + mPictureSize.height); 
     } 
     mCamera.setParameters(cameraParams); 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     stop(); 
     isSafeForTakeImage = false; 
    } 

    public void stop() { 
     if (null == mCamera) { 
      return; 
     } 
     mCamera.stopPreview(); 
     mCamera.release(); 
     mCamera = null; 
    } 

    public boolean isPortrait() { 
     return (mActivity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT); 
    } 

    public void setOneShotPreviewCallback(PreviewCallback callback) { 
     if (null == mCamera) { 
      return; 
     } 
     mCamera.setOneShotPreviewCallback(callback); 
    } 

    public void setPreviewCallback(PreviewCallback callback) { 
     if (null == mCamera) { 
      return; 
     } 
     mCamera.setPreviewCallback(callback); 
    } 

    public Camera.Size getPreviewSize() { 
     return mPreviewSize; 
    } 

    public void setOnPreviewReady(PreviewReadyCallback cb) { 
     mPreviewReadyCallback = cb; 
    } 

} 

你在你的AndroidManifest.xml

<uses-permission android:name="android.permission.CAMERA" /> 

<uses-feature 
    android:name="android.hardware.camera" 
    android:required="false" /> 
<uses-feature 
    android:name="android.hardware.camera.autofocus" 
    android:required="false" /> 

上面的類需要以下權限假設,您正在使用相對佈局, 在您的活動中將此代碼放入您的onResume()方法中,

surfaceview = new CameraPreview(this, 0, CameraPreview.LayoutMode.FitToParent); 
       LayoutParams previewLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT); 
       previewLayoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL); 
       relativeLayout.addView(surfaceview, 0, previewLayoutParams); 

添加以下線在你的onPause()方法

try{ 
    relativeLayout.removeView(surfaceview); 
}catch(Exception exception){ 
} 
+0

點擊圖片在這個位置捕獲 – Mahesh

+0

您需要定義回調...! –

相關問題