问题
I am trying to create an app which captures some x*y sized rectangular portion from the camera view. To achieve that I have been to many threads but none of them seems to be working as required.
Basically what i want to achieve is as shown:
My requirement is when i open camera there should be a rectangular highlighted bright part on the screen and the rest of the screen should look black translucent displaying the rest of the camera view but when user clicks the button then the camera should only click the highlighted brighten part of the screen.
I am trying thisCustom camera android thread but it is not displaying the rest of the part as translucent. It only shows whatever comes under the surfaceview.
Now what i have done is using another surface view on top of it but now it is clicking the previous portion of the surface not the current one.
So please give me some advice to achieve the same.
My Activity 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.stopPreview();
mCamera.setPreviewDisplay(mCameraPreview.getHolder());
mCamera.startPreview();
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);
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.setPreviewDisplay(mCameraPreview.getHolder());
// 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);
mCameraImage.setImageBitmap(bitmap);
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 file:
<?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"
xmlns:custom="http://schemas.android.com/apk/res-auto"
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">
<com.edmodo.cropper.CropImageView
android:id="@+id/camera_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<!-- <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" />
<!-- <com.example.cameraapplication.CropOverlayNew-->
<!-- android:id="@+id/cropper"-->
<!-- 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>
来源:https://stackoverflow.com/questions/61728321/how-to-change-preview-of-camera-at-runtime