我正在尝试使用相机拍摄照片。默认情况下预览是横向模式,我可以使用
将其更改为纵向模式 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
相同注意:我使用后置摄像头而不是前置摄像头。
答案 0 :(得分:33)
在纵向模式下从相机拍照时我遇到了同样的问题。下面的代码行解决了我的问题:
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);
}
});
答案 1 :(得分:1)
以下代码适用于前置摄像头。
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) {
}
}
答案 2 :(得分:1)
是的,我在答案中尝试了这种方式,它适用于后置摄像头,对于前置摄像头,它需要旋转270而不是90. :)