我正在尝试为Android应用程序创建自定义相机。我已成功使用自己的客户界面获取相机拍照并保存。 SurfaceView预览也以纵向模式显示(也是需要的)。我的问题是,保存图片后,它们不会以拍摄照片时相机所在的方向显示。我知道在这里有一些与我非常相似的问题,但他们无法帮助我。我用来测试它的电话(当然在模拟器之外)是HTC Evo 4G。下面是我的代码细分。非常感谢您提供的任何帮助!请注意,我在一个类中执行所有这些操作,并将图像保存为文件而不是位图。
清单
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<activity android:name=".CameraClass"
android:screenOrientation="portrait" />
按钮单击
btn_takepicture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
mCamera.takePicture(null, null, pic_call);
Toast.makeText(getApplicationContext(), "Picture Added!", Toast.LENGTH_SHORT).show();
}
});
图片回调方法
private PictureCallback pic_call= new PictureCallback() {
public void onPictureTaken(byte[] datas, Camera mCamera) {
// TODO Auto-generated method stub
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/Images/");
myDir.mkdirs();
if (myDir.exists()){
}
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image"+ n +".jpg";
File file = new File (myDir, fname);
Uri uriSavedImage = Uri.fromFile(file);
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
Intent is = new Intent(CameraClass.this, Display.class);
is.putExtras(basket);
try {
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
fos.write(datas);
fos.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
startActivity(is);
}
};
相机暂停/发布方式
@Override
protected void onPause() {
super.onPause();
releaseCamera();
}
private void releaseCamera() {
// TODO Auto-generated method stub
if (mCamera != null){
mCamera.release();
mCamera = null;
}
}
表面改变方法
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if (surfaceHolder.getSurface() == null) {
}
try {
mCamera.stopPreview();
}
catch (Exception e) {
}
try {
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
}
catch (Exception e) {
Log.d("TAG", "Error starting mCamera preview: " + e.getMessage());
}
Camera.Parameters parameters = mCamera.getParameters();
parameters.set("orientation", "portrait");
if(mCamera != null) {
try {
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
previewing = true;
}
catch (IOException e) {
e.printStackTrace();
}
}
}
表面创建
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera = Camera.open();
camParam = mCamera.getParameters();
Camera.Parameters params = mCamera.getParameters();
String currentversion = android.os.Build.VERSION.SDK;
Log.d("System out", "currentVersion " + currentversion);
int currentInt = android.os.Build.VERSION.SDK_INT;
Log.d("System out", "currentVersion " + currentInt);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
if (currentInt != 7) {
mCamera.setDisplayOrientation(90);
} else {
Log.d("System out", "Portrait " + currentInt);
params.setRotation(90);
mCamera.setParameters(params);
}
}
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
if (currentInt != 7) {
mCamera.setDisplayOrientation(0);
} else {
Log.d("System out", "Landscape " + currentInt);
params.set("orientation", "landscape");
params.set("rotation", 90);
mCamera.setParameters(params);
}
}
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("CAMERA", e.getMessage());
}
}
表面破坏方法
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
设置相机方向方法
public static void setCameraDisplayOrientation(Activity activity, int cameraID, android.hardware.Camera mCamera) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraID, info);
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch(rotation){
case Surface.ROTATION_0: degrees =0;
break;
case Surface.ROTATION_90: degrees = 90;
break;
case Surface.ROTATION_180: degrees = 180;
break;
case Surface.ROTATION_270: degrees = 270;
break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360;
}
else {
result = (info.orientation - degrees + 360) % 360;
}
mCamera.setDisplayOrientation(result);
}
答案 0 :(得分:4)
某些设备在保存时不会旋转图像,而是设置一个EXIF标题,说“嘿,图像查看器!您可以在显示时旋转此图像吗?kthxbye”。
这就是为什么在my CWAC-Camera library中,我会通过旋转来旋转这些图像,因为并非所有图像查看者都会尊重这些EXIF标题。