我正在尝试为Android应用程序创建自定义相机。我已经通过自己的客户界面成功获取了相机进行拍照并保存。SurfaceView预览也将以“纵向”模式显示(需要)。我的问题是,保存图片后,它们不会以拍摄照片时相机所处的方向显示。我知道这里有一些与我的问题非常相似的问题,但是他们无法帮助我。我用于测试此功能的电话(当然是在仿真器之外)是HTC Evo 4G。下面是我的代码分解。非常感谢您提供的任何帮助!请注意,我将所有这些都放在一个类中,并将图像另存为文件而不是位图。
表现
按钮点击
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); }
CommonsWare.. 5
某些设备在保存图像时不会旋转图像,而是设置一个EXIF标头,上面写着“嘿,图像查看器!您能像在显示图像时旋转该图像吗?kthxbye”。
这就是为什么在我的CWAC-Camera库中,我会通过旋转来旋转那些图像,因为并非所有图像查看器都会尊重那些EXIF标头。
某些设备在保存图像时不会旋转图像,而是设置一个EXIF标头,上面写着“嘿,图像查看器!您能像在显示图像时旋转该图像吗?kthxbye”。
这就是为什么在我的CWAC-Camera库中,我会通过旋转来旋转那些图像,因为并非所有图像查看器都会尊重那些EXIF标头。