这是我用来将图片保存到Bitmap
的代码。这段代码是基于CyanogenMod的相机应用程序的代码,所以我认为它会正常工作,但不是。关于此问题最重要的一点是,在Nexus 4上进行测试时, Bitmap
正在为使用后置摄像头拍摄的照片正确创建,但使用前置摄像头会产生下面的内容。
我用来创建Bitmap
的代码:
private class XyzPictureCallback implements Camera.PictureCallback {
@Override
public void onPictureTaken (byte [] data, Camera camera) {
Options options = new Options();
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap image = BitmapFactory.decodeByteArray(data, 0, data.length, options);
}
}
我尝试使用不同的Options
(根本没有),但没有帮助。它可能是两个不同相机返回的像素格式,但当我运行getSupportedPictureFormats()
时,它们都返回ImageFormat.JPEG
...
我的想法已经不多了......
我还应该提一下,使用data
直接保存FileOutputStream
正在创建一个合适的JPEG图像。所以问题必须与BitmapFactory
以及我创建Bitmap
。
这是此代码生成的位图:
编辑(24.03.2013):
花了几个小时试图解决这个问题后,我仍然没有真正的解决方法。
我发现只有当我将图片大小(使用Camera.Parameters.setPictureSize(int width, int height)
)设置为可通过调用{{1}获得的前置摄像头可用的最高分辨率时,才会出现此问题。 }。
导致问题的分辨率为1280x960。正如我之前提到的那样,这是最高分辨率。第二个最高的是1280x720,当我使用这个时,输出图片很好。我确实检查了相机吐出的格式,并且它一直是ImageFormat.JPEG所以我不认为像素格式是这里的问题......
编辑(08.03.2013): 打电话给拍照:
Camera.Parameters.getSupportedPictureSizes()
答案 0 :(得分:3)
该相机不支持高度和宽度。这就是为什么它看起来像1280x720设置有效的原因。就像你将星际飞行设置为以你的显示器不支持的分辨率运行一样。
答案 1 :(得分:0)
试试这个
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
imv.setImageBitmap(bmp);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.JPEG, 70, bos);
答案 2 :(得分:0)
您是否尝试将null置于您的选项中?试试这个:
@Override
public void onPictureTaken(final byte[] data, Camera camera) {
Bitmap bm = BitmapFactory.decodeByteArray(data, 0, data.length, null);
try {
FileOutputStream out = new FileOutputStream(Environment.getExternalStorageDirectory().getAbsolutePath()+"/image.jpg");
bm.compress(Bitmap.CompressFormat.JPEG, 95, out);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
答案 3 :(得分:0)
我建议不要在代码中设置图片大小,让相机返回可捕获的最佳图片。检查答案中给出的代码。 https://stackoverflow.com/a/9745780/2107118
答案 4 :(得分:0)
您是否正在设置从后置摄像头到前置摄像头的参数? 要测试的另一件事是前置摄像头,首先尝试不设置任何参数,只需使用默认设置来查看它是否可行。我在三星设备上遇到了类似的问题,但那是后置摄像头。 此外,您可能需要旋转使用前置摄像头拍摄的图像(对于三星设备,后置摄像头也需要)
public static Bitmap rotate(Bitmap bitmap, int degree) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix mtx = new Matrix();
mtx.postRotate(degree);
return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
}
答案 5 :(得分:0)
我可能还应该提到使用a直接保存数据 FileOutputStream正在创建一个合适的JPEG图像。所以问题必须如此 使用BitmapFactory和我创建Bitmap的方式。
相机输出完全处理过的JPEG数据(希望如此),您可以将其写入磁盘。现在你应该尝试一下:
BitmapFactory
处理由图像编辑器保存的原始文件和文件,看看两者中是否有错误的位图。 如果图像有效且BitmapFactory
仍然产生错误的位图,则问题出在BitmapFactory
(不太可能),如果Camera输出的文件无效,则问题出在Camera(更有可能)
答案 6 :(得分:0)
这是我的代码,用于拍照,并将其保存在数据库中,而不会改变其质量。
首先你需要这个变量:
private static final int CAMERA_PIC_REQUEST = 2500;
private Rect Padding = new Rect(-1,-1,-1,-1);
private Matrix matrix = new Matrix();
private Bitmap rotatedBitmap = null;
private Bitmap bm = null;
private Bitmap scaledBitmap= null;
private ExifInterface exif ;
private int rotation=0;
private final BitmapFactory.Options options = new BitmapFactory.Options();
然后根据您的应用(我使用按钮)从按钮,活动或片段设置请求
btn_camera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
}
}
);
现在我正在请求CAMERA 来自片段的_PIC_REQUEST我在OnActivityResult()
上实现了这个代码@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_PIC_REQUEST)
if (data != null) {
imageuri = data.getData();
//Bitmap image = (Bitmap) data.getExtras().get("data");
try {
options.inSampleSize = 2;
exif = new ExifInterface(getRealPathFromURI(imageuri));
rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
rotation = exifToDegrees(rotation);
bm = BitmapFactory.decodeStream(
getActivity().getContentResolver().openInputStream(imageuri),Padding,options);
scaledBitmap = Bitmap.createScaledBitmap(bm, 400,400, true);
if (rotation != 0)
{matrix.postRotate(rotation);}
//matrix.postRotate(180);
rotatedBitmap = Bitmap.createBitmap(scaledBitmap , 0, 0, scaledBitmap .getWidth(), scaledBitmap .getHeight(), matrix, true);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mIvFoto.setImageBitmap(rotatedBitmap);
}
}
旋转和矩阵用于将拍摄的照片缩放到ImageView,因此我可以在保存之前预览照片。这不会影响pic的质量。它只适用于预览位图。所以在ScaledBitmap变量中,你可以看到,当我将PIC的尺寸放到400,400时,你可以放置你想要的图片的尺寸,一定要旋转位图,这样你就可以正确地拍照了即使您以纵向模式拍摄照片。
最后是从相机保存它的路径旋转和获取图片的方法。
private static int exifToDegrees(int exifOrientation) {
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) { return 90; }
else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) { return 180; }
else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) { return 270; }
return 0;
}
private String getRealPathFromURI(Uri contentURI) {
String result;
Cursor cursor =getActivity().getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null) { // Source is Dropbox or other similar local file path
result = contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
result = cursor.getString(idx);
cursor.close();
}
return result;
}
我希望这对你有所帮助。