问题
I am trying to click only a rectangular portion of the screen from camera using this code:
Java code: package com.example.cameraapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.IOException;
public class CameraActivity extends Activity implements Camera.PictureCallback, SurfaceHolder.Callback {
public static final String EXTRA_CAMERA_DATA = "camera_data";
private static final String KEY_IS_CAPTURING = "is_capturing";
private Camera mCamera, dummyCamera;
private ImageView mCameraImage;
private SurfaceView mCameraPreview,s1;
private Button mCaptureImageButton;
private byte[] mCameraData;
private boolean mIsCapturing;
private View v1;
private View.OnClickListener mCaptureImageButtonClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
// mCamera.release();
// mCamera = Camera.open();
// mCamera.setPreviewDisplay(mCameraPreview.getHolder());
// mCamera.startPreview();
// final SurfaceHolder surfaceHolder = mCameraPreview.getHolder();
// surfaceHolder.addCallback(CameraActivity.this);
// surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
captureImage();
}catch (Exception e){
e.printStackTrace();
}
}
};
private View.OnClickListener mRecaptureImageButtonClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
setupImageCapture();
}
};
private View.OnClickListener mDoneButtonClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mCameraData != null) {
Intent intent = new Intent();
intent.putExtra(EXTRA_CAMERA_DATA, mCameraData);
setResult(RESULT_OK, intent);
} else {
setResult(RESULT_CANCELED);
}
finish();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
mCameraImage = (ImageView) findViewById(R.id.camera_image_view);
mCameraImage.setVisibility(View.INVISIBLE);
v1 = findViewById(R.id.v1);
mCameraPreview = (SurfaceView) findViewById(R.id.preview_view);
s1 = (SurfaceView) findViewById(R.id.preview_view_1);
// final SurfaceHolder surfaceHolder = mCameraPreview.getHolder();
// surfaceHolder.addCallback(this);
// surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
final SurfaceHolder surfaceHolder2 = s1.getHolder();
surfaceHolder2.addCallback(this);
surfaceHolder2.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mCaptureImageButton = (Button) findViewById(R.id.capture_image_button);
mCaptureImageButton.setOnClickListener(mCaptureImageButtonClickListener);
final Button doneButton = (Button) findViewById(R.id.done_button);
doneButton.setOnClickListener(mDoneButtonClickListener);
mIsCapturing = true;
}
@Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putBoolean(KEY_IS_CAPTURING, mIsCapturing);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mIsCapturing = savedInstanceState.getBoolean(KEY_IS_CAPTURING, mCameraData == null);
if (mCameraData != null) {
setupImageDisplay();
} else {
setupImageCapture();
}
}
@Override
protected void onResume() {
super.onResume();
if (mCamera == null) {
try {
mCamera = Camera.open();
// dummyCamera = mCamera;
mCamera.setPreviewDisplay(s1.getHolder());
// dummyCamera.setPreviewDisplay(s1.getHolder());
if (mIsCapturing) {
// dummyCamera.startPreview();
mCamera.startPreview();
}
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(CameraActivity.this, "Unable to open camera.", Toast.LENGTH_LONG)
.show();
}
}
}
@Override
protected void onPause() {
super.onPause();
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
@Override
public void onPictureTaken(byte[] data, Camera camera) {
mCameraData = data;
setupImageDisplay();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (mCamera != null) {
try {
// mCamera.stopPreview();
mCamera.setPreviewDisplay(holder);
// dummyCamera.setPreviewDisplay(s1.getHolder());
if (mIsCapturing) {
mCamera.startPreview();
// dummyCamera.startPreview();
}
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(CameraActivity.this, "Unable to start camera preview.", Toast.LENGTH_LONG).show();
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
private void captureImage() {
mCamera.takePicture(null, null, this);
}
private void setupImageCapture() {
try {
mCameraImage.setVisibility(View.INVISIBLE);
mCameraPreview.setVisibility(View.VISIBLE);
s1.setVisibility(View.VISIBLE);
v1.setVisibility(View.VISIBLE);
mCamera.setPreviewDisplay(s1.getHolder());
mCamera.startPreview();
mCaptureImageButton.setText(R.string.capture_image);
mCaptureImageButton.setOnClickListener(mCaptureImageButtonClickListener);
}catch (Exception e){
e.printStackTrace();
}
}
private void setupImageDisplay() {
Bitmap bitmap = BitmapFactory.decodeByteArray(mCameraData, 0, mCameraData.length);
Bitmap resizedbitmap1=Bitmap.createBitmap(bitmap, 0,0,mCameraPreview.getWidth(), mCameraPreview.getHeight());
mCameraImage.setImageBitmap(resizedbitmap1);
mCamera.stopPreview();
mCameraPreview.setVisibility(View.INVISIBLE);
s1.setVisibility(View.INVISIBLE);
v1.setVisibility(View.INVISIBLE);
mCameraImage.setVisibility(View.VISIBLE);
mCaptureImageButton.setText(R.string.recapture_image);
mCaptureImageButton.setOnClickListener(mRecaptureImageButtonClickListener);
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/capturing_image" />
<FrameLayout
android:id="@+id/camera_frame"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<ImageView
android:id="@+id/camera_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<SurfaceView
android:id="@+id/preview_view_1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<View
android:id="@+id/v1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCFFFFFF"/>
<SurfaceView
android:id="@+id/preview_view"
android:layout_margin="80dp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- <LinearLayout-->
<!-- android:layout_width="match_parent"-->
<!-- android:background="@android:color/transparent"-->
<!-- android:layout_height="match_parent">-->
<!-- -->
<!-- </LinearLayout>-->
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:orientation="horizontal">
<Button
android:id="@+id/capture_image_button"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="@string/capture_image" />
<Button
android:id="@+id/done_button"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="@string/done" />
</LinearLayout>
</LinearLayout>
Here seems to be 2 workarounds:
Either i dynamically set the surface view "camera_image_view" at the time user try to capture screen. But i tried that in onClick and it is not working. Please suggest me some changes if you found any bug in that.
Clicking a full screen image and then cropping it to whatever fits inside the length and width of "camera_image_view". I tried this also but i think there is some flaw in this line:
Bitmap resizedbitmap1=Bitmap.createBitmap(bitmap, 0,0,mCameraPreview.getWidth(), mCameraPreview.getHeight());
as it is generating some broken colors instead of the cropped image.
So please help me with any of the two ways as both will work for me.
来源:https://stackoverflow.com/questions/61731115/cropping-a-full-screen-camera-image-bitmap-into-a-surface-view-height-and-width