gpt4 book ai didi

java - 自定义相机不保存整个图像

转载 作者:行者123 更新时间:2023-11-29 23:41:38 24 4
gpt4 key购买 nike

我用这种方式构建了一个 android 自定义相机:

    //CameraActivity.java

public class CameraActivity extends AppCompatActivity implements CameraPreview.OnCameraStatusListener {

String path, TAG = "CameraActivity";
private CameraPreview cameraPreview;

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

requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_camera);

Button takePhoto = findViewById(R.id.takePhoto);
takePhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

Log.e(TAG, "===takePhoto()===");

if (cameraPreview != null) {
cameraPreview.takePicture();
}
}
});

//Start camera
initCameraPreview();
}

private void initCameraPreview() {
Log.e(TAG, "===initCameraPreview()===");

cameraPreview = findViewById(R.id.cameraPreview);
cameraPreview.setOnCameraStatusListener(this);
}

@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onCameraStopped(byte[] data) throws JSONException {
Log.e("TAG", "===onCameraStopped===");
File mSaveFile = getOutputMediaFile();
saveToFile(data, mSaveFile);
}

public File getOutputMediaFile() {

File mediaStorageDir =
new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "CustomCameraPics");

// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.e(TAG, "failed to create directory");
return null;
}
}

long time = System.currentTimeMillis();

File file = new File(mediaStorageDir.getPath() + File.separator + "myPic_" + time + ".png");

path = file.getPath();
Log.e("imagePath", path);

return file;
}

@RequiresApi(api = Build.VERSION_CODES.N)
public void saveToFile(byte[] bytes, File file) throws JSONException {

Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);

try {

FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();

Log.e("Image", "Saved");
Toast.makeText(CameraActivity.this, "Image Saved", Toast.LENGTH_SHORT).show();

} catch (Exception e) {
e.printStackTrace();
}
}
}

//activity_camera.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.sukshi.mycamera.CameraActivity">

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >

<com.shank.mycamera.CameraPreview
android:id="@+id/cameraPreview"
android:layout_width="match_parent"
android:layout_height="match_parent" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="Take pic"
android:id="@+id/takePhoto"/>

</RelativeLayout>

</RelativeLayout>

//CameraPreview.java

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

private static final String TAG = "CameraPreview";
private OnCameraStatusListener listener;

private Camera camera;
private SurfaceHolder holder;

private Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {

@Override
public void onPictureTaken(byte[] data, Camera camera) {
try {
camera.stopPreview();
} catch (Exception e) {
}

if (null != listener) {
try {
listener.onCameraStopped(data);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
};

public void takePicture() {
Log.e(TAG, "===takePicture()===");
if (camera != null) {
try {
camera.takePicture(null, null, pictureCallback);
} catch (Exception e) {
e.printStackTrace();
}
}
}

public CameraPreview(Context context, AttributeSet attrs) {
super(context, attrs);
holder = getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public interface OnCameraStatusListener {
void onCameraStopped(byte[] data) throws JSONException;
}

public void setOnCameraStatusListener(OnCameraStatusListener listener) {
this.listener = listener;
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.e(TAG, "==surfaceCreated==");
camera = getCameraInstance();

try {
camera.setPreviewDisplay(holder);
} catch (Exception e) {
Log.e(TAG, "Error setting camera preview", e);
camera.release();
camera = null;
}
//update()

if (camera != null) {
camera.startPreview();

Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
Camera.getCameraInfo(i, cameraInfo);
}
}
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

Log.e(TAG, "==surfaceChanged==");
try {
camera.stopPreview();
} catch (Exception e) {

}

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

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.e(TAG, "==surfaceDestroyed==");
camera.release();
camera = null;
}

public static Camera getCameraInstance() {
Camera camera = null;
int cameraId = 0;
boolean frontCameraFound = false;

try {
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
Camera.getCameraInfo(i, cameraInfo);

if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
cameraId = i;
frontCameraFound = true;
}
}

if (frontCameraFound) {
camera = Camera.open(cameraId);
} else {
camera = Camera.open();
}
Camera.Parameters parameters = camera.getParameters();
camera.setDisplayOrientation(90);
parameters.setRotation(270);
camera.setParameters(parameters);
} catch (Exception e) {

Log.e(TAG, "getCamera failed");
}
return camera;
}
}

它会在您点击“拍摄照片”按钮时保存图像。

我的要求:应保存用户在预览屏幕上可以看到的整个图像。

我面临的问题是,在某些手机中,保存的图像/位图不包含在屏幕上显示给用户的所有内容。

最佳答案

正如@CommonsWare 所解释的,没有要求捕获的图片应该与预览图片相同。您可以完全跳过 camera.takePicture(),在您的 cameraPreview.takePicture() 中,将最新的预览帧保存为位图。

这种方法的优点是您可以保证保存与用户在预览中看到的相同的图像,并且不会有任何延迟。

缺点是从 camera.takePicture() 返回的图像的分辨率和质量可能明显更好。

如果您对预览帧质量不满意,可以使用相同尺寸的setPreviewSize()setPictureSize() , 如果大小都支持 getSupportedPreviewSizes()getSupportedPictureSizes() : 通常您可以找到满意的一对。

如果你对预览帧分辨率不满意,至少为setPreviewSize()选择相同的宽高比setPictureSize() .当两者不匹配时,某些设备会产生非常奇怪的结果。

但请注意,这些步骤不能保证捕获的图像与预览的图像相同,即使只是因为 takePicture() 不可避免地会发生一些延迟。


再说一句:如果您的目标是 Android N 及更高版本,请考虑从已弃用 Camera API 切换到camera2 API。

关于java - 自定义相机不保存整个图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51799958/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com