2017-06-21 66 views
1

在我的项目中,我试图在framelayout中显示相机。它显示完美,但我想要捕捉图像,当我按下按钮。我附上了我的代码。如何使用框架布局捕捉照片?

这是我的MainActivity.java代码:

public class MainActivity extends AppCompatActivity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    getFragmentManager().beginTransaction().add(R.id.cameraview1, new CameraExtractionFragment()).commit(); 

    Button but = (Button)findViewById(R.id.selfienext); 
    but.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Intent intent = new Intent(MainActivity.this,DocumentCapture.class); 
      startActivity(intent); 
     } 
    }); 
} 
} 

CameraExtractionFragment.java代码:

class CameraExtractionFragment extends Fragment { 
private CameraExtraction mCameraExtraction; 
Camera mCamera; 
int mNumberOfCameras; 
int cameraId; 
int rotation; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    mCameraExtraction = new CameraExtraction(
      this.getActivity().getBaseContext(), 
      this.getActivity().getWindowManager().getDefaultDisplay().getRotation() 
    ); 

    // Find the total number of cameras available 
    mNumberOfCameras = Camera.getNumberOfCameras(); 

    // Find the ID of the rear-facing ("default") camera 
    Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); 
    for (int i = 0; i < mNumberOfCameras; i++) { 
     Camera.getCameraInfo(i, cameraInfo); 
     if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 
      cameraId = i; 
     } 
    } 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)    { 
    return mCameraExtraction; 
} 

@Override 
public void onResume() { 
    super.onResume(); 

    // Use mCurrentCamera to select the camera desired to safely restore 
    // the fragment after the camera has been changed 
    mCamera = Camera.open(cameraId); 
    mCameraExtraction.setCamera(mCamera); 
} 

@Override 
public void onPause() { 
    super.onPause(); 

    if (mCamera != null) 
    { 
     mCamera.stopPreview(); 
     mCamera.release(); 
    } 
} 


// Modo en el que se pinta la cámara: encajada por dentro o saliendo los bordes por fuera. 
public enum CameraViewMode { 

    /** 
    * Inner mode 
    */ 
    Inner, 
    /** 
    * Outer mode 
    */ 
    Outer 
} 
} 

CameraExtraction.java代码:

class CameraExtraction extends ViewGroup implements SurfaceHolder.Callback { 

private final String TAG = "CameraExtraction"; 

Camera mCamera; 
SurfaceHolder mHolder; 
SurfaceView mSurfaceView; 
int mNumberOfCameras; 
int cameraId; 
Rect desiredSize; 
CameraExtractionFragment.CameraViewMode cameraViewMode; 
boolean mSurfaceCreated = false; 
List<Camera.Size> mSupportedPreviewSizes; 
int rotation; 
Camera.Size mPreviewSize; 

public CameraExtraction(Context context, int rotation) { 
    super(context); 

    this.rotation = rotation; 

    mSurfaceView = new SurfaceView(context); 

    addView(mSurfaceView); 

    // Install a SurfaceHolder.Callback so we get notified when the 
    mHolder = mSurfaceView.getHolder(); 
    mHolder.addCallback(this); 
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

    cameraViewMode = CameraExtractionFragment.CameraViewMode.Inner; 
} 

public void setCamera(Camera camera) { 
    mCamera = camera; 
    if (mCamera != null) { 
     mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes(); 
     if (mSurfaceCreated) requestLayout(); 
    } 
} 

public void switchCamera(Camera camera) { 
    setCamera(camera); 
    try { 
     camera.setPreviewDisplay(mHolder); 
    } catch (IOException exception) { 
     Log.e(TAG, "IOException caused by setPreviewDisplay()", exception); 
    } 
} 

@SuppressLint("DrawAllocation") 
@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    if (mSurfaceView == null ||mSurfaceView.getHolder() == null) return; 

    if (mSurfaceView.getHolder().getSurface() == null) { 
     // preview surface does not exist 
     return; 
    } 

    final int width = resolveSize(getSuggestedMinimumWidth(), 
      widthMeasureSpec); 
    final int height = resolveSize(getSuggestedMinimumHeight(), 
      heightMeasureSpec); 
    setMeasuredDimension(width, height); 

    if (mSupportedPreviewSizes != null) { 

     mPreviewSize = getNearestPreviewSize(mCamera.new Size(widthMeasureSpec,heightMeasureSpec)); 
    } 

    if (mCamera != null) { 
     Camera.Parameters parameters = mCamera.getParameters(); 
     parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); 

     mCamera.setParameters(parameters); 
    } 
} 

@Override 
protected void onLayout(boolean changed, int l, int t, int r, int b) { 
    if (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); 
     } 
    } 
} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    try { 
     if (mCamera != null) { 
      mCamera.setPreviewDisplay(holder); 
      mCamera.setPreviewCallback(new Camera.PreviewCallback() { 
       @Override 
       public void onPreviewFrame(byte[] data, Camera camera) { 
       } 
      }); 
     } 
    } catch (IOException exception) { 
     Log.e(TAG, "IOException caused by setPreviewDisplay()", exception); 
    } 
} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) { 
    if (mSurfaceView == null || mSurfaceView.getHolder() == null) return; 

    if (mSurfaceView.getHolder().getSurface() == null) { 
     // preview surface does not exist 
     return; 
    } 

    // set preview size and make any resize, rotate or 
    // reformatting changes here 
    Camera.Parameters param = mCamera.getParameters(); 
    Point previewSize = new Point(480,480); 

    Camera.Size size = getNearestPreviewSize(mCamera.new Size(previewSize.x,previewSize.y)); 
    param.setPreviewSize(size.width, size.height); 
    mCamera.setParameters(param); 
    rotation = setCameraDisplayOrientation(cameraId, mCamera); 

    // start preview with new settings 
    try { 
     mCamera.setPreviewCallback(new Camera.PreviewCallback() { 

      @Override 
      public void onPreviewFrame(byte[] data, Camera camera) { 
       // TODO Auto-generated method stub 

      } 
     }); 
     mCamera.setPreviewDisplay(mSurfaceView.getHolder()); 
     mCamera.startPreview(); 

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

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    if (mCamera != null) 
    { 
//   mCamera.stopPreview(); 
//   mCamera.release(); 
    } 
} 


protected Rect getCameraViewSizeCompensated(Camera.Size cameraPreviewSize, Point hostViewSize) { 
    Rect toReturn=null; 

    float ratioWidth = hostViewSize.x/(float)cameraPreviewSize.width; 
    float ratioHeight = hostViewSize.y/(float)cameraPreviewSize.height; 

    switch (cameraViewMode){ 
     case Inner: 
      if (ratioWidth < ratioHeight) { 
       int newHeight = (int)(cameraPreviewSize.height*ratioWidth); 
       int y = (hostViewSize.y - newHeight)/2; 
       toReturn = new Rect(0, y, hostViewSize.x, y+newHeight); 
      } else { 
       int newWidth = (int)(cameraPreviewSize.width*ratioHeight); 
       int x = (hostViewSize.x - newWidth)/2; 
       toReturn = new Rect(x, 0, x+newWidth,hostViewSize.y); 
      } 
      break; 
     case Outer: 
      if (ratioWidth < ratioHeight) { 
       int newWidth = (int)(cameraPreviewSize.width*ratioHeight); 
       int x = (hostViewSize.x - newWidth)/2; 
       toReturn = new Rect(x, 0, x+newWidth,hostViewSize.y); 
      } else { 
       int newHeight = (int)(cameraPreviewSize.height*ratioWidth); 
       int y = (hostViewSize.y - newHeight)/2; 
       toReturn = new Rect(0, y, hostViewSize.x, y+newHeight); 
      } 
      break; 
    } 
    return toReturn; 
} 

private Camera.Size getNearestPreviewSize(Camera.Size size) { 
    List<Camera.Size> availableSizes = 
mCamera.getParameters().getSupportedPreviewSizes(); 
    if (availableSizes == null || availableSizes.size() <= 0) return null; 

    Camera.Size toReturn = availableSizes.get(0); 
    int distance = Math.abs(size.width*size.height - toReturn.width*toReturn.height); 
    for (int a=1; a<availableSizes.size(); a++) { 
     int temp = Math.abs(size.width*size.height - availableSizes.get(a).width*availableSizes.get(a).height); 
     if (temp < distance) { 
      distance = temp; 
      toReturn = availableSizes.get(a); 
     } 
    } 
    return toReturn; 
} 


public int setCameraDisplayOrientation(int cameraId, android.hardware.Camera camera) { 

    Camera.CameraInfo info = new Camera.CameraInfo(); 
    Camera.getCameraInfo(cameraId, info); 
    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 result; 
    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 
     result = (info.orientation + degrees) % 360; 
     result = (360 - result) % 360; // compensate the mirror 
    } else { // back-facing 
     result = (info.orientation - degrees + 360) % 360; 
    } 
    camera.setDisplayOrientation(result); 
    return result/90; 
} 
} 

DocumentCapture.java代码:

public class DocumentCapture extends AppCompatActivity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_document_capture); 

    Button but = (Button)findViewById(R.id.docnext); 
    but.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Intent intent = new Intent(DocumentCapture.this,VerificationResult.class); 
      startActivity(intent); 
     } 
    }); 

} 
} 

这是我拍摄按钮代码:

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" 
    android:layout_marginTop="5dp"> 
     <FrameLayout 
      android:id="@+id/cameraview1" 
      android:layout_width="match_parent" 
      android:layout_height="350dp"> 
     </FrameLayout> 

     <Button 
      android:id="@+id/selfiecapture" 
      android:layout_width="100dp" 
      android:layout_height="wrap_content" 
      android:layout_marginLeft="10dp" 
      android:background="@drawable/btn" 
      android:text="Capture" 
      android:textColor="#FFFFFF" 
      android:textSize="17dp" 
      android:textAllCaps="false" 
      android:layout_gravity="left"/>   

</LinearLayout> 
+0

你看着https://开头stackoverflow.com/quest离子/ 10913682 /如何到俘获并节省-的图像,使用定制相机功能于Android的? –

+0

'Intent intent = new Intent(MainActivity.this,DocumentCapture.class);'你提到'DocumentCapture.class'在你的文章中添加这个类 – Gopal

回答

0

后通过谷歌官方页面获得Link

您可以使用此方法调用Camera API。

CameraActivity

public class CameraActivity extends Activity { 

private Camera mCamera; 
private CameraPreview mPreview; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    // Create an instance of Camera 
    mCamera = getCameraInstance(); 

    // Create our Preview view and set it as the content of our activity. 
    mPreview = new CameraPreview(this, mCamera); 
    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); 
    preview.addView(mPreview); 
    // Add a listener to the Capture button 
    Button captureButton = (Button) findViewById(id.button_capture); 
    captureButton.setOnClickListener(
    new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     // get an image from the camera 
     mCamera.takePicture(null, null, mPicture); 
    } 
    } 
); 
    } 
} 

/** A safe way to get an instance of the Camera object. */ 
public static Camera getCameraInstance(){ 
    Camera c = null; 
    try { 
    c = Camera.open(); // attempt to get a Camera instance 
    } 
    catch (Exception e){ 
    // Camera is not available (in use or does not exist) 
    } 
    return c; // returns null if camera is unavailable 
} 

private PictureCallback mPicture = new PictureCallback() { 

@Override 
public void onPictureTaken(byte[] data, Camera camera) { 

    File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE); 
    if (pictureFile == null){ 
     Log.d(TAG, "Error creating media file, check storage permissions: " + 
      e.getMessage()); 
     return; 
    } 

    try { 
     FileOutputStream fos = new FileOutputStream(pictureFile); 
     fos.write(data); 
     fos.close(); 
    } catch (FileNotFoundException e) { 
     Log.d(TAG, "File not found: " + e.getMessage()); 
    } catch (IOException e) { 
     Log.d(TAG, "Error accessing file: " + e.getMessage()); 
    } 
    } 
}; 

创建相机预览类

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 
    private SurfaceHolder mHolder; 
    private Camera mCamera; 

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

    // 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) { 
    // The Surface has been created, now tell the camera where to draw the preview. 
    try { 
     mCamera.setPreviewDisplay(holder); 
     mCamera.startPreview(); 
    } catch (IOException e) { 
     Log.d(TAG, "Error setting camera preview: " + e.getMessage()); 
    } 
} 

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) { 
    // 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 { 
     mCamera.setPreviewDisplay(mHolder); 
     mCamera.startPreview(); 

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

添加这些在AndroidManifest.xml文件

<uses-feature android:name="android.hardware.camera" /> 
<uses-permission android:name="android.permission.CAMERA" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />