这是我的代码,我使用的图像保存到一个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
。
这是此代码生成位图:
编辑(2013年3月24日):
花几个小时试图解决这一问题后,我仍然没有真正解决这一点。 所有我调查的结果是,当我将图像尺寸设置(使用问题只发生Camera.Parameters.setPictureSize(int width, int height)
以尽可能高的分辨率,可用于前置摄像头我已经通过调用获得Camera.Parameters.getSupportedPictureSizes()
引起该问题的解决是1280×960。 正如我前面提到它的最高分辨率。 第二个最高为1280x720,当我用这一个输出画面精细。 我做了检查相机吐出的格式和它的ImageFormat.JPEG所有的时间,所以我不认为像素格式是这里的问题...
编辑(2013年8月3日):调用takePicture:
private class XyzAutoFocusCallback implements Camera.AutoFocusCallback {
@Override
public void onAutoFocus(boolean success, Camera camera) {
if (takingPicture) {
camera.takePicture(null, null, myPictureCallback);
} else {
...
}
}
高度和宽度不支持该摄像机。 这就是为什么它看起来像这一点,为什么1280×720的设置工作。 这是一样的,如果你设置你的星际争霸在没有你的显示器所支持的分辨率下运行。
试试这个
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
imv.setImageBitmap(bmp);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.JPEG, 70, bos);
你尝试把空你的选择? 尝试:
@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();
}
}
我建议不设置代码中的图片尺寸,让相机返回它可以捕捉到最佳画面。 请在这里给出的答案代码。 https://stackoverflow.com/a/9745780/2107118
你是从背部摄像头的参数设置前置摄像头? 另一件事测试是前置摄像头,第一次尝试没有设置任何参数,只使用默认设置,看看它是否会奏效。 我跑进三星设备类似的问题,但是这是为后置摄像头。 您可能还需要旋转前置摄像头拍摄的图像(三星设备后置摄像头需要太)
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);
}
我应该还提到,保存数据,直接使用一个FileOutputStream是创造一个合适的JPEG图像。 所以这个问题必须与BitmapFactory和我创建位图的方式。
相机输出完全处理JPEG数据(希望如此),并且可以将其写入到磁盘。 现在,你应该尝试什么:
- 转储文件保存到磁盘。
- 检查使用该文件验证工具 ,或者在PC上的一些图像编辑器。
- 如果图像编辑器中打开图像细腻,从图像编辑器保存副本,使用标准的JPEG轮廓。
- 有
BitmapFactory
过程中的原始文件和文件的图像编辑器保存的,看看你在这两个得到一个坏的位图。
如果图像是有效的JPEG和BitmapFactory
仍然会产生错误的位图,该问题是与BitmapFactory
(不太可能),如果由摄像机输出的文件是无效的JPEG,问题是相机(更可能)。
这是我的代码,我用它来拍照,并将其保存在数据库中,在不改变其质量。
首先,你需要这个变量:
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变量,你可以看到,当CreatingScaledBitmap,我把事先知情同意的尺寸,以400,400你可以把你想要你的PIC的尺寸,一定要旋转位图,这样你就可以得到的图片正确,即使你把在纵向模式下的照片。
最后,方法旋转和正从相机将其保存路径的画面。
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;
}
我希望这可以帮助你。