在我的项目中,我试图在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 :(得分:0)
通过google官方网页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" />