gpt4 book ai didi

Android onPictureTaken 导致图像质量差/旋转错误

转载 作者:太空宇宙 更新时间:2023-11-03 11:08:21 25 4
gpt4 key购买 nike

我在应用程序中保存图像时遇到问题。我在 Android 版本 4.4.4 上使用 Android 相机 api 1(pre api 21)。设备是 OnePlus One。

当我拍照时,我的应用程序中的内置相机似乎保存的图像质量很差,而且还逆时针旋转了 90 度 (-90)。

这是一个图片示例。

使用默认 android 相机应用程序的人像 View (保存的图像):

enter image description here

使用内置应用程序相机的人像 View :

enter image description here

使用内置应用程序相机保存时的图片(保存的图像):

enter image description here

第一个问题,旋转方向

现在我猜旋转是由于这个原因造成的(如果我不更改 setDisplayOrientation 相机在我的应用程序中倾斜):

public void refreshCamera(Camera camera) {
if (holder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
camera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}

int rotation = ((WindowManager)activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
int degrees = 0;

// specifically for back facing camera
switch (rotation) {
case Surface.ROTATION_0:
degrees = 90;
break;
case Surface.ROTATION_90:
degrees = 0;
break;
case Surface.ROTATION_180:
degrees = 270;
break;
case Surface.ROTATION_270:
degrees = 180;
break;
}

camera.setDisplayOrientation(degrees);
setCamera(camera);
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
} catch (Exception e) {
Log.d(VIEW_LOG_TAG, "Error starting camera preview: " + e.getMessage());
}
}

为了解决这个问题,我想我可以在保存图像后旋转图像,不过编写这样的方法似乎是在浪费代码。

第二个问题,质量

我不知道为什么质量这么差,我猜这与此有关:

private PictureCallback getPictureCallback() {
return new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// save picture on seperate thread so camera can refresh quicker
new Thread(new SavePicThread(data)).start();
// refresh camera to continue preview
cameraPreview.refreshCamera(camera);
}
};
}

public class SavePicThread implements Runnable {
byte[] data;
public SavePicThread(byte[] data) {
this.data = data;
}
public void run() {
// make a new picture file
File pictureFile = getOutputMediaFile();

if (pictureFile == null) {
return;
}
try {
// write to the file
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.flush();
fos.close();
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Toast toast = Toast.makeText(getActivity(), "Picture saved", Toast.LENGTH_SHORT);
toast.show();
}
});
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// make the picture visible to the rest of the device
galleryAddPic(pictureFile);
}
}

// make picture and save to a folder
private File getOutputMediaFile() {
// make a new file directory inside the "sdcard" folder
// File mediaStorageDir = new File("/sdcard/", "fela"); // private pic for app

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

// if the directory does not exist
if (!mediaStorageDir.exists()) {
// if you cannot make this directory return
if (!mediaStorageDir.mkdirs()) {
return null;
}
}

// take the current timeStamp
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
// and make a media file:
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");

return mediaFile;
}

/**
* makes the image visible for the device (gallery)
* @param pic file
*/
private void galleryAddPic(File file) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
getActivity().sendBroadcast(mediaScanIntent);
}

一直在看教程,这几乎是他们涵盖的内容!

最佳答案

我了解到您找到了图像质量的解决方案。实际上,您不能假设默认的 PictureSize 是设备上可用的最佳质量;您应该使用 getSupportedPictureSizes(),然后调用 setPictureSize()

关于轮换,情况比较麻烦。相机参数支持 setRotation()方法

Sets the clockwise rotation angle in degrees relative to the orientation of the camera. This affects the pictures returned from JPEG Camera.PictureCallback. The camera driver may set orientation in the EXIF header without rotating the picture. Or the driver may rotate the picture and the EXIF thumbnail. If the Jpeg picture is rotated, the orientation in the EXIF header will be missing or 1 (row #0 is top and column #0 is left side).

从描述中可以看出,有些设备实际上会保存方向正确的 JPEG 图片,但其他设备只会保存 EXIF header 。

不幸的是,方向标志对于许多图像查看器应用程序来说是不够的,例如 - 对于 Windows 内置图像预览。以编程方式执行全尺寸图像的旋转是可能的,但这是一项耗时且(更重要的)内存消耗的任务。最简单的方法是create a bitmap and rotate it .

许多人使用缩放位图来加快旋转速度并使用更少的内存。但这将不可避免地破坏您获得最佳图像质量的目的。

关于Android onPictureTaken 导致图像质量差/旋转错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30146770/

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