我在Android应用中创建了一个自定义相机活动,但根据拍摄的设备,图像旋转90度时出现问题。这只发生在特定设备上,我似乎无法弄清楚原因。
我在应用中做的是
我在两种不同的设备上测试过,华为手机和三星Galaxy S II。我发现虽然我能够确定手机的方向正确更新并且两者都有默认的纵向方向,但它们需要不同的“mOrientation”值,偏移90度,以便保存时正确定位。
以下是我检查当前方向的方法:
public void onOrientationChanged(int orientation) {
if(cameraPreview.getDeviceDefaultOrientation() == Configuration.ORIENTATION_PORTRAIT){
if (orientation >= 315 || orientation < 45) {
if (mOrientation != ORIENTATION_PORTRAIT_NORMAL) {
mOrientation = ORIENTATION_PORTRAIT_NORMAL;
}
}else if (orientation < 315 && orientation >= 225) {
if (mOrientation != ORIENTATION_LANDSCAPE_NORMAL) {
mOrientation = ORIENTATION_LANDSCAPE_NORMAL;
}
}else if (orientation < 225 && orientation >= 135) {
if (mOrientation != ORIENTATION_PORTRAIT_INVERTED) {
mOrientation = ORIENTATION_PORTRAIT_INVERTED;
}
}else { // orientation <135 && orientation > 45
if (mOrientation != ORIENTATION_LANDSCAPE_INVERTED) {
mOrientation = ORIENTATION_LANDSCAPE_INVERTED;
}
}
}else{
if (orientation >= 315 || orientation < 45) {
if (mOrientation != ORIENTATION_LANDSCAPE_NORMAL) {
mOrientation = ORIENTATION_LANDSCAPE_NORMAL;
}
}else if (orientation < 315 && orientation >= 225) {
if (mOrientation != ORIENTATION_PORTRAIT_INVERTED) {
mOrientation = ORIENTATION_PORTRAIT_INVERTED;
}
}else if (orientation < 225 && orientation >= 135) {
if (mOrientation != ORIENTATION_LANDSCAPE_INVERTED) {
mOrientation = ORIENTATION_LANDSCAPE_INVERTED;
}
}else { // orientation <135 && orientation > 45
if (mOrientation != ORIENTATION_PORTRAIT_NORMAL) {
mOrientation = ORIENTATION_PORTRAIT_NORMAL;
}
}
}
以下是我保存图片的方式:
private PictureCallback myPictureCallback_JPG = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera cam) {
Log.d(TAG, "saving picture");
Log.d(TAG, "portrait image? " + Boolean.toString(cameraPreview.getDeviceDefaultOrientation() == Configuration.ORIENTATION_PORTRAIT));
Log.d(TAG, "mOrientaiton: " + mOrientation);
//Degrees to rotate image by when saving
int degree = 0;
// do not rotate image, just put rotation info in
if(cameraPreview.getDeviceDefaultOrientation() == Configuration.ORIENTATION_PORTRAIT){
switch (mOrientation) {
case ORIENTATION_LANDSCAPE_INVERTED:
Log.d(TAG, "orientation landscape inverted");
degree = 90;
break;
case ORIENTATION_PORTRAIT_NORMAL:
Log.d(TAG, "orientation portrait normal");
degree = 0;
break;
case ORIENTATION_LANDSCAPE_NORMAL:
Log.d(TAG, "orientation landscape normal");
degree = 270;
break;
case ORIENTATION_PORTRAIT_INVERTED:
Log.d(TAG, "orientation portrait inverted");
degree = 180;
break;
}
}else{
switch (mOrientation) {
case ORIENTATION_LANDSCAPE_INVERTED:
degree = 270;
break;
case ORIENTATION_PORTRAIT_NORMAL:
degree = 180;
break;
case ORIENTATION_LANDSCAPE_NORMAL:
degree = 0;
break;
case ORIENTATION_PORTRAIT_INVERTED:
degree = 90;
break;
}
}
Bitmap bMap;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 6;
options.inDither = false; // Disable Dithering mode
options.inPurgeable = true; // Tell to gc that whether it needs free
// memory, the Bitmap can be cleared
options.inInputShareable = true; // Which kind of reference will be
// used to recover the Bitmap
// data after being clear, when
// it will be used in the future
options.inTempStorage = new byte[32 * 1024];
options.inPreferredConfig = Bitmap.Config.RGB_565;
bMap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
if(degree != 0){
bMap = rotate(bMap, degree);
}
//Getting the picture's unique file to be added to the folder
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
/*
* This catches errors when creating the output file to put the picture in
*/
if (pictureFile == null) {
Log.d(TAG,"Error creating media file, check storage permissions");
//After the camera has finished taking the picture
handler.post(new Runnable(){
@Override
public void run() {
//Remove white border from preview
Log.d(TAG, "removing white background from preview");
cameraPreview.setBackgroundResource(0);
}
});
//Setting the onclicklistener back on the shutter
shutter.setOnClickListener(shutterClickListener);
//Restarting the preview as soon as picture is done
camera.startPreview();
Toast.makeText(getApplicationContext(), "Error saving file. Try restarting the camera.", Toast.LENGTH_LONG).show();
return;
}
FileOutputStream out = null;
try {
//Saving the image
out = new FileOutputStream(pictureFile);
bMap.compress(Bitmap.CompressFormat.JPEG, 90, out);
if (bMap != null) {
bMap.recycle();
bMap = null;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
try {
//Assuring we always close the output stream
if(out!=null){
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
myHorizontalLayout.add(Uri.parse(pictureFile.getPath()));
MediaScannerConnection.scanFile(getApplicationContext(), new String[] { Environment.getExternalStorageDirectory().toString() }, null, new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri)
{
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
camera.startPreview();
if(myHorizontalLayout.getItemList().size() == 1){
//Have added the first item to the pictures set check to green
MenuItem check = menu.findItem(R.id.save);
}
//After the camera has finished taking the picture
handler.post(new Runnable(){
@Override
public void run() {
//Remove white border from preview
Log.d(TAG, "removing white background");
cameraPreview.setBackgroundResource(0);
}
});
//Setting the onclicklistener back on the shutter
shutter.setOnClickListener(shutterClickListener);
}
});
}
};
如果有人能帮助我,我将非常感激。此外,如果有人就如何在Android设备上测试相机配置提供一般性建议而不必拥有许多不同品牌的手机,我也会很感激。
答案 0 :(得分:2)
根据拍摄的设备将图像旋转90度存在问题
你的照片可能技术上很好。某些设备本身不会旋转图像,而是设置一个EXIF标题,告诉图像 viewer 旋转图像。并非所有图像查看者都这样做。
此外,如果有人就如何在Android设备上测试相机配置提供一般性建议而不必拥有许多不同品牌的手机,我也会很感激。
依靠somebody else为你做这项工作。 : - )