相机预览处于纵向模式,但拍摄的图像已旋转
Posted
技术标签:
【中文标题】相机预览处于纵向模式,但拍摄的图像已旋转【英文标题】:Camera preview is in portrait mode but image captured is rotated 【发布时间】:2013-04-14 06:18:29 【问题描述】:我正在尝试使用相机拍摄照片。默认情况下预览是横向模式,我可以使用将其更改为纵向模式
setCameraDisplayOrientation(this,1, mCamera);
public static void setCameraDisplayOrientation(Activity activity,
int cameraId, android.hardware.Camera camera)
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.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; // compensate the mirror
else // back-facing
result = (info.orientation - degrees + 360) % 360;
camera.setDisplayOrientation(result);
捕获的图像存储在 myImages 文件夹下。但是图像是旋转的。 (看起来图像是在横向模式下拍摄的)
那么如何旋转捕获的图像并保存?
public class MainActivity extends Activity
private static final int REQUEST_CODE = 1;
ImageView imageView;
Button b;
private Camera mCamera;
private CameraPreview mPreview;
private Bitmap bitmap;
private PictureCallback mPicture;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
boolean check =checkCameraHardware(MainActivity.this);
if(check)
mCamera = getCameraInstance();
// mCamera.setDisplayOrientation(90);
setCameraDisplayOrientation(this,
1, mCamera);//requires min sdk 9
// Create an instance of Camera
mPicture = new PictureCallback()
@Override
public void onPictureTaken(byte[] data, Camera camera)
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "MyImages");
if(!imagesFolder.exists())
imagesFolder.mkdirs();
File pictureFile = new File(imagesFolder, "image.jpg");
try
FileOutputStream fos = new FileOutputStream(pictureFile);
System.out.println("hello");
fos.write(data);
fos.close();
catch (FileNotFoundException e)
Log.d("No File", "File not found: " + e.getMessage());
catch (IOException e)
//Log.d(TAG, "Error accessing file: " + e.getMessage());
;
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
b = (Button) findViewById(R.id.button_capture);
b.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
// TODO Auto-generated method stub
mCamera.takePicture(null, null, mPicture);
Toast.makeText(MainActivity.this, "Called",1000).show();
);
public static void setCameraDisplayOrientation(Activity activity,
int cameraId, android.hardware.Camera camera)
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.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; // compensate the mirror
else // back-facing
result = (info.orientation - degrees + 360) % 360;
camera.setDisplayOrientation(result);
private boolean checkCameraHardware(Context context)
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA))
// this device has a camera
Toast.makeText(this, "Phone has camera", Toast.LENGTH_LONG).show();
return true;
else
// no camera on this device
Toast.makeText(this, "Phone has no camera", Toast.LENGTH_LONG).show();
return false;
public static Camera getCameraInstance()
Camera c = null;
try
c = Camera.open(); // attempt to get a Camera instance
catch (Exception e)
// Camera is not available (in use or does not exist)
return c; // returns null if camera is unavailable
@Override
protected void onDestroy()
// TODO Auto-generated method stub
super.onDestroy();
mCamera.release();
CameraPreview 类与开发者网站http://developer.android.com/guide/topics/media/camera.html 相同
注意:我使用的是后置摄像头而不是前置摄像头。
【问题讨论】:
我在另一个帖子***.com/a/34323194/4847767回答了类似的问题 【参考方案1】:我在以人像模式从相机拍照时遇到了同样的问题。下面的代码行解决了我的问题:
public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera)
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.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; // compensate the mirror
else // back-facing
result = (info.orientation - degrees + 360) % 360;
camera.setDisplayOrientation(result);
在surfaceCreated回调中调用setCameraDisplayOrientation()
方法如下:
@Override
public void surfaceCreated(SurfaceHolder holder)
camera = Camera.open();
setCameraDisplayOrientation(getActivity(), CameraInfo.CAMERA_FACING_BACK, camera);
我不得不在相机onPictureTaken()
回调中旋转图像:
camera.takePicture(null, null, new PictureCallback()
@Override
public void onPictureTaken(byte[] data, Camera camera)
if (data != null)
int screenWidth = getResources().getDisplayMetrics().widthPixels;
int screenHeight = getResources().getDisplayMetrics().heightPixels;
Bitmap bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
// Notice that width and height are reversed
Bitmap scaled = Bitmap.createScaledBitmap(bm, screenHeight, screenWidth, true);
int w = scaled.getWidth();
int h = scaled.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(90);
// Rotating Bitmap
bm = Bitmap.createBitmap(scaled, 0, 0, w, h, mtx, true);
else// LANDSCAPE MODE
//No need to reverse width and height
Bitmap scaled = Bitmap.createScaledBitmap(bm, screenWidth,screenHeight , true);
bm=scaled;
photoPreview.setImageBitmap(bm);
isImageCaptured = true;
photoPreview.setVisibility(View.VISIBLE);
surfaceView.setVisibility(View.GONE);
);
【讨论】:
我也对相同的问题应用了相同的解决方案,但在开始时我得到了我们的内存错误。然后我存储压缩位图以摆脱这种情况。但是在我的屏幕上创建新的位图时,这个过程非常慢。半分钟我的应用程序卡在黑屏中。你有什么解决办法吗 @HemantG 你能告诉我我应该在哪里写方向代码,因为我的图片在只有前置摄像头的情况下旋转...... @HemantG 您的解决方案中的一切都很酷,而且肯定会奏效。您在旋转之前缩小位图以避免 OutOfMemory 异常。如果我们保存这个新的位图,那么它将是原始位图的缩小版本。我想以原始分辨率保存位图而不会出现 OutOfMemory 异常。我怎样才能做到这一点?为什么即使预览是纵向的,相机也会给出旋转的图像?请帮帮我。 我正在通过此代码从后置摄像头旋转图像,但在字体摄像头中,图像旋转了 180 度。我该怎么办。【参考方案2】:以下代码适用于前置摄像头。
if (data != null)
try
int screenWidth = getResources().getDisplayMetrics().widthPixels;
int screenHeight = getResources().getDisplayMetrics().heightPixels;
bm = BitmapFactory.decodeByteArray(data, 0,
(data != null) ? data.length : 0);
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(cameraFace, info);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
// Notice that width and height are reversed
// Bitmap scaled = Bitmap.createScaledBitmap(bm,
// screenHeight, screenWidth, true);
// int w = scaled.getWidth();
// int h = scaled.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(90);
if (cameraFace == CameraInfo.CAMERA_FACING_FRONT)
mtx.postRotate(180);
// Rotating Bitmap
bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
bm.getHeight(), mtx, true);
else // LANDSCAPE MODE
Bitmap scaled = Bitmap.createScaledBitmap(bm,
screenWidth, screenHeight, true);
bm = scaled;
catch (Exception e)
catch (Error e)
【讨论】:
【参考方案3】:是的,我尝试了答案中的方式,它适用于后置摄像头,对于前置摄像头,它需要旋转 270 而不是 90。:)
【讨论】:
以上是关于相机预览处于纵向模式,但拍摄的图像已旋转的主要内容,如果未能解决你的问题,请参考以下文章