【发布时间】:2015-07-20 17:22:15
【问题描述】:
在我的应用程序中保存图像时遇到问题。我在 android 版本 4.4.4 上使用 Android camera api 1 (pre api 21)。设备是 OnePlus One。
当我拍照时,我的应用程序中的内置摄像头似乎以低质量保存图像,并且还逆时针旋转了 90 度 (-90)。
这是一个带有图像的示例。
带有默认安卓相机应用的纵向视图(保存的图像):
带有内置应用摄像头的人像视图:
使用内置应用程序相机保存时的图片(保存的图像):
第一个问题,旋转方向
现在我猜测的旋转是由于这个(如果我不更改 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);
}
一直在看教程,这几乎就是他们所涵盖的内容!
【问题讨论】:
-
1.你用的是什么设备。 2. 您是否将您的图像与 ODM 相机应用程序进行比较? 3、你用的是什么相机参数; developer.android.com/reference/android/hardware/…
-
@MorrisonChang 1. OnePlus One 2. 使用 ODM 我想您的意思是普通的智能手机相机应用程序,是的 3. 我显然没有设置任何...(也许这是问题?从来不知道它存在)
-
请注意,ODM/普通智能手机应用程序可以访问旧相机 API 中不可用的内容,这可以解释差异。 Camera2 API 的发布旨在帮助创建更好的 3rd 方相机应用程序。有关硬件实现者的详细信息,请参阅source.android.com/devices/camera/camera3.html。
-
@MorrisonChang 我用我的应用程序的外观更新了这个问题。 - 所以没有更好的方法来使用旧的 api 拍摄图像吗?这很奇怪,因为我的智能手机(OnePlus One)不支持 api 21,因为它不是棒棒糖。
-
@MorrisonChang 我修好了!我需要将参数
setPictureSize设置为支持的最高宽度/高度,你得到+1 让我走上正轨。 :)