Android摄像头以错误方向保存图像
我有一个相机应用程序,只使用肖像模式(通过android清单文件限制)。下面的代码是我的SurfaceView用于相机Android摄像头以错误方向保存图像,android,camera,orientation,surfaceview,Android,Camera,Orientation,Surfaceview,我有一个相机应用程序,只使用肖像模式(通过android清单文件限制)。下面的代码是我的SurfaceView用于相机 public class CameraPreview extends SurfaceView implements SensorEventListener, SurfaceHolder.Callback { private SurfaceHolder mSurfaceHolder; private Camera mCamera; private Acti
public class CameraPreview extends SurfaceView implements SensorEventListener, SurfaceHolder.Callback {
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
private Activity mActivity;
private static boolean DEBUGGING = true;
private static final String LOG_TAG = "CameraPreviewSample";
private static final String CAMERA_PARAM_ORIENTATION = "orientation";
private static final String CAMERA_PARAM_LANDSCAPE = "landscape";
private static final String CAMERA_PARAM_PORTRAIT = "portrait";
protected List<Camera.Size> mPreviewSizeList;
protected List<Camera.Size> mPictureSizeList;
protected Camera.Size mPreviewSize;
protected Camera.Size mPictureSize;
// Constructor that obtains context and camera
@SuppressWarnings("deprecation")
public CameraPreview(Context context, Camera camera) {
super(context);
mActivity=(Activity)context;
mCamera = camera;
this.mCamera = camera;
this.mSurfaceHolder = this.getHolder();
this.mSurfaceHolder.addCallback(this);
this.mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (IOException e) {
// left blank for now
}
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
mCamera.stopPreview();
mCamera.release();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
if (mSurfaceHolder.getSurface() == null) {
// preview surface does not exist
return;
}
try {
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (Exception e) {
// intentionally left blank for a test
}
try {
Camera.Parameters cameraParams = mCamera.getParameters();
boolean portrait = isPortrait();
configureCameraParameters(cameraParams, portrait);
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d("CameraView", "Error starting camera preview: " + e.getMessage());
}
}
protected void configureCameraParameters(Camera.Parameters cameraParams, boolean portrait) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { // for 2.1 and before
if (portrait) {
cameraParams.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_PORTRAIT);
} else {
cameraParams.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_LANDSCAPE);
}
} else { // for 2.2 and later
int angle;
Display display = mActivity.getWindowManager().getDefaultDisplay();
switch (display.getRotation()) {
case Surface.ROTATION_0: // This is display orientation
angle = 90; // This is camera orientation
break;
case Surface.ROTATION_90:
angle = 0;
break;
case Surface.ROTATION_180:
angle = 270;
break;
case Surface.ROTATION_270:
angle = 180;
break;
default:
angle = 90;
break;
}
Log.v(LOG_TAG, "angle: " + angle);
mCamera.setDisplayOrientation(angle);
}
cameraParams.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
cameraParams.setPictureSize(mPictureSize.width, mPictureSize.height);
if (DEBUGGING) {
Log.v(LOG_TAG, "Preview Actual Size - w: " + mPreviewSize.width + ", h: " + mPreviewSize.height);
Log.v(LOG_TAG, "Picture Actual Size - w: " + mPictureSize.width + ", h: " + mPictureSize.height);
}
mCamera.setParameters(cameraParams);
}
public boolean isPortrait() {
return (mActivity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(SensorEvent arg0) {
// TODO Auto-generated method stub
}
}
非常感谢您的帮助。以下是我解决问题的方法(包括保存图像的完整实现)。在纵向模式下拍摄的图像将旋转90度
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
public class ImageTakeAndShow extends Activity {
private static final int ACTION_TAKE_PHOTO = 1;
private static final String BITMAP_STORAGE_KEY = "viewbitmap";
private static final String IMAGEVIEW_VISIBILITY_STORAGE_KEY = "imageviewvisibility";
//private ImageView mImageView;
private Bitmap mImageBitmap;
private String mCurrentPhotoPath;
private static final String JPEG_FILE_PREFIX = "IMG_";
private static final String JPEG_FILE_SUFFIX = ".jpg";
TelephonyManager myPhonenumber;
static String device_id;
double latitude ,longitude;
Button Btn;
File f;
//save picture
private File getAlbumDir() {
File file = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
file = Environment.getExternalStorageDirectory().getAbsoluteFile();
file = new File(Environment.getExternalStorageDirectory()
+ File.separator + "Snap/Capture_Image");
Log.e("file", file.toString());
if (file != null) {
if (! file.mkdirs()) {
if (! file.exists()){
Log.d("Camera", "failed to create directory");
return null;
}
}
}
} else {
Log.v(getString(R.string.app_name), "External storage is not mounted READ/WRITE.");
}
return file;
}
//create file name
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = JPEG_FILE_PREFIX + timeStamp + "_";
File albumF = getAlbumDir();
File imageF = File.createTempFile(imageFileName, JPEG_FILE_SUFFIX, albumF);
return imageF;
}
private File setUpPhotoFile() throws IOException {
File f = createImageFile();
mCurrentPhotoPath = f.getAbsolutePath();
return f;
}
//set picture width and height and rotate 90 degrees
private void setPic() {
/* Get the size of the image */
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth/2;
int photoH = bmOptions.outHeight/2;
Log.e("photoW", Integer.valueOf(photoW).toString());
Log.e("photoH", Integer.valueOf(photoH).toString());
int scaleFactor = 1;
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
try{
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath);
bitmap = Bitmap.createScaledBitmap(bitmap, 800, 600, true);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
File f = new File(mCurrentPhotoPath.toString());
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, 800,640,matrix, true);
FileOutputStream fos2 = new FileOutputStream(mCurrentPhotoPath.toString());
rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos2);
fos2.close();
}catch (Exception e) {
e.printStackTrace();
}catch (OutOfMemoryError o) {
o.printStackTrace();
}
}
private void galleryAddPic() {
Intent mediaScanIntent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE");
f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
Log.e("path f", f.toString());
}
//Camera activity
private void dispatchTakePictureIntent(int actionCode) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
switch(actionCode) {
case ACTION_TAKE_PHOTO:
File f = null;
try {
f = setUpPhotoFile();
mCurrentPhotoPath = f.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
} catch (IOException e) {
e.printStackTrace();
f = null;
mCurrentPhotoPath = null;
}
break;
default:
break;
}
startActivityForResult(takePictureIntent, actionCode);
}
private void handleBigCameraPhoto() {
if (mCurrentPhotoPath != null) {
setPic();
galleryAddPic();
mCurrentPhotoPath = null;
}
}
Button.OnClickListener mTakePicOnClickListener =
new Button.OnClickListener() {
@Override
public void onClick(View v) {
dispatchTakePictureIntent(ACTION_TAKE_PHOTO);
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myPhonenumber = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
device_id = myPhonenumber.getDeviceId();
mImageBitmap = null;
dispatchTakePictureIntent(ACTION_TAKE_PHOTO);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case ACTION_TAKE_PHOTO: {
if (resultCode == RESULT_OK) {
handleBigCameraPhoto();
final Intent intent = new Intent(getApplicationContext(), Image_Priview.class);
intent.putExtra("image parth", f.toString());
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
new Handler().postDelayed(new Runnable() {
public void run() {
}
}, 1000);
}else if (resultCode == RESULT_CANCELED){
File file = new File(mCurrentPhotoPath);
file.delete();
finish();
}
break;
}
}
}
// Some lifecycle callbacks so that the image can survive orientation change
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putParcelable(BITMAP_STORAGE_KEY, mImageBitmap);
outState.putBoolean(IMAGEVIEW_VISIBILITY_STORAGE_KEY, (mImageBitmap != null) );
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mImageBitmap = savedInstanceState.getParcelable(BITMAP_STORAGE_KEY);
}
public static boolean isIntentAvailable(Context context, String action) {
final PackageManager packageManager = context.getPackageManager();
final Intent intent = new Intent(action);
List<ResolveInfo> list =
packageManager.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}
}
import java.io.ByteArrayOutputStream;
导入java.io.File;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.text.simpleDataFormat;
导入java.util.Date;
导入java.util.List;
导入android.app.Activity;
导入android.content.Context;
导入android.content.Intent;
导入android.content.pm.PackageManager;
导入android.content.pm.ResolveInfo;
导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
导入android.graphics.Matrix;
导入android.net.Uri;
导入android.os.Bundle;
导入android.os.Environment;
导入android.os.Handler;
导入android.provider.MediaStore;
导入android.telephony.TelephonyManager;
导入android.util.Log;
导入android.view.view;
导入android.widget.Button;
导入android.widget.ImageView;
导入android.widget.Toast;
公共类ImageTakeAndShow扩展活动{
私人静态最终int动作拍摄照片=1;
私有静态最终字符串位图\u存储\u KEY=“viewbitmap”;
私有静态最终字符串IMAGEVIEW\u VISIBILITY\u STORAGE\u KEY=“imageviewvisibility”;
//私有图像视图mImageView;
私有位图;
私有字符串mCurrentPhotoPath;
私有静态最终字符串JPEG\u文件\u前缀=“IMG\uU”;
私有静态最终字符串JPEG_FILE_SUFFIX=“.jpg”;
电话管理员myPhonenumber;
静态字符串设备标识;
双纬度,经度;
按钮Btn;
文件f;
//保存图片
私有文件getAlbumDir(){
File=null;
if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
file=Environment.getExternalStorageDirectory().getAbsoluteFile();
file=新文件(Environment.getExternalStorageDirectory()
+File.separator+“捕捉/捕捉图像”);
Log.e(“file”,file.toString());
如果(文件!=null){
如果(!file.mkdirs()){
如果(!file.exists()){
Log.d(“摄像机”,“创建目录失败”);
返回null;
}
}
}
}否则{
Log.v(getString(R.string.app_name),“外部存储未以读/写方式装入”);
}
返回文件;
}
//创建文件名
私有文件createImageFile()引发IOException{
//创建图像文件名
字符串时间戳=新的SimpleDateFormat(“yyyyMMdd_HHmmss”)。格式(新日期();
字符串imageFileName=JPEG\u文件\u前缀+时间戳+“\u”;
文件albumF=getAlbumDir();
File imageF=File.createTempFile(imageFileName,JPEG\u File\u后缀,albumF);
返回图像f;
}
私有文件setUpPhotoFile()引发IOException{
文件f=createImageFile();
mCurrentPhotoPath=f.getAbsolutePath();
返回f;
}
//设置图片宽度和高度并旋转90度
私有void setPic(){
/*获取图像的大小*/
BitmapFactory.Options bmOptions=新的BitmapFactory.Options();
bmOptions.inJustDecodeBounds=true;
解码文件(mCurrentPhotoPath,bmOptions);
int photoW=bmOptions.outWidth/2;
int photoH=bmOptions.outHeight/2;
Log.e(“photoW”,Integer.valueOf(photoW.toString());
Log.e(“photoH”,Integer.valueOf(photoH.toString());
int scaleFactor=1;
bmOptions.inJustDecodeBounds=false;
bmOptions.inSampleSize=scaleFactor;
bmOptions.inpurgable=true;
试一试{
位图位图=位图工厂.decodeFile(mCurrentPhotoPath);
位图=位图。createScaledBitmap(位图,800,600,true);
ByteArrayOutputStream字节=新建ByteArrayOutputStream();
bitmap.compress(bitmap.CompressFormat.JPEG,100,字节);
文件f=新文件(mCurrentPhotoPath.toString());
FileOutputStream fo=新的FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
矩阵=新矩阵();
矩阵旋转后(90);
位图旋转位图=位图.createBitmap(位图,0,0,800640,矩阵,真);
FileOutputStream fos2=新的FileOutputStream(mCurrentPhotoPath.toString());
旋转位图.compress(Bitmap.CompressFormat.JPEG,90,fos2);
fos2.close();
}捕获(例外e){
e、 printStackTrace();
}捕获(OutOfMemoryO错误){
o、 printStackTrace();
}
}
私有void galleryAddPic(){
Intent mediaScanIntent=newintent(“android.Intent.action.MEDIA\u SCANNER\u SCAN\u文件”);
f=新文件(mCurrentPhotoPath);
uricontenturi=Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
这是sendBroadcast(mediaScanIntent);
Log.e(“路径f”,f.toString());
}
//摄像机活动
私有无效DispatchTakePictureContent(int操作代码){
Intent takePictureIntent=新的意图(MediaStore.ACTION\u IMAGE\u CAPTURE);
转换
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
public class ImageTakeAndShow extends Activity {
private static final int ACTION_TAKE_PHOTO = 1;
private static final String BITMAP_STORAGE_KEY = "viewbitmap";
private static final String IMAGEVIEW_VISIBILITY_STORAGE_KEY = "imageviewvisibility";
//private ImageView mImageView;
private Bitmap mImageBitmap;
private String mCurrentPhotoPath;
private static final String JPEG_FILE_PREFIX = "IMG_";
private static final String JPEG_FILE_SUFFIX = ".jpg";
TelephonyManager myPhonenumber;
static String device_id;
double latitude ,longitude;
Button Btn;
File f;
//save picture
private File getAlbumDir() {
File file = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
file = Environment.getExternalStorageDirectory().getAbsoluteFile();
file = new File(Environment.getExternalStorageDirectory()
+ File.separator + "Snap/Capture_Image");
Log.e("file", file.toString());
if (file != null) {
if (! file.mkdirs()) {
if (! file.exists()){
Log.d("Camera", "failed to create directory");
return null;
}
}
}
} else {
Log.v(getString(R.string.app_name), "External storage is not mounted READ/WRITE.");
}
return file;
}
//create file name
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = JPEG_FILE_PREFIX + timeStamp + "_";
File albumF = getAlbumDir();
File imageF = File.createTempFile(imageFileName, JPEG_FILE_SUFFIX, albumF);
return imageF;
}
private File setUpPhotoFile() throws IOException {
File f = createImageFile();
mCurrentPhotoPath = f.getAbsolutePath();
return f;
}
//set picture width and height and rotate 90 degrees
private void setPic() {
/* Get the size of the image */
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth/2;
int photoH = bmOptions.outHeight/2;
Log.e("photoW", Integer.valueOf(photoW).toString());
Log.e("photoH", Integer.valueOf(photoH).toString());
int scaleFactor = 1;
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
try{
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath);
bitmap = Bitmap.createScaledBitmap(bitmap, 800, 600, true);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
File f = new File(mCurrentPhotoPath.toString());
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, 800,640,matrix, true);
FileOutputStream fos2 = new FileOutputStream(mCurrentPhotoPath.toString());
rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos2);
fos2.close();
}catch (Exception e) {
e.printStackTrace();
}catch (OutOfMemoryError o) {
o.printStackTrace();
}
}
private void galleryAddPic() {
Intent mediaScanIntent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE");
f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
Log.e("path f", f.toString());
}
//Camera activity
private void dispatchTakePictureIntent(int actionCode) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
switch(actionCode) {
case ACTION_TAKE_PHOTO:
File f = null;
try {
f = setUpPhotoFile();
mCurrentPhotoPath = f.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
} catch (IOException e) {
e.printStackTrace();
f = null;
mCurrentPhotoPath = null;
}
break;
default:
break;
}
startActivityForResult(takePictureIntent, actionCode);
}
private void handleBigCameraPhoto() {
if (mCurrentPhotoPath != null) {
setPic();
galleryAddPic();
mCurrentPhotoPath = null;
}
}
Button.OnClickListener mTakePicOnClickListener =
new Button.OnClickListener() {
@Override
public void onClick(View v) {
dispatchTakePictureIntent(ACTION_TAKE_PHOTO);
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myPhonenumber = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
device_id = myPhonenumber.getDeviceId();
mImageBitmap = null;
dispatchTakePictureIntent(ACTION_TAKE_PHOTO);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case ACTION_TAKE_PHOTO: {
if (resultCode == RESULT_OK) {
handleBigCameraPhoto();
final Intent intent = new Intent(getApplicationContext(), Image_Priview.class);
intent.putExtra("image parth", f.toString());
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
new Handler().postDelayed(new Runnable() {
public void run() {
}
}, 1000);
}else if (resultCode == RESULT_CANCELED){
File file = new File(mCurrentPhotoPath);
file.delete();
finish();
}
break;
}
}
}
// Some lifecycle callbacks so that the image can survive orientation change
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putParcelable(BITMAP_STORAGE_KEY, mImageBitmap);
outState.putBoolean(IMAGEVIEW_VISIBILITY_STORAGE_KEY, (mImageBitmap != null) );
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mImageBitmap = savedInstanceState.getParcelable(BITMAP_STORAGE_KEY);
}
public static boolean isIntentAvailable(Context context, String action) {
final PackageManager packageManager = context.getPackageManager();
final Intent intent = new Intent(action);
List<ResolveInfo> list =
packageManager.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}
}