摄像机图像在搞砸图像位图结果(Camera picture to Bitmap results in

2019-07-21 14:22发布

这是我的代码,我使用的图像保存到一个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 {
                    ...
            }

}

Answer 1:

高度和宽度不支持该摄像机。 这就是为什么它看起来像这一点,为什么1280×720的设置工作。 这是一样的,如果你设置你的星际争霸在没有你的显示器所支持的分辨率下运行。



Answer 2:

试试这个

Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
imv.setImageBitmap(bmp);

ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.JPEG, 70, bos);


Answer 3:

你尝试把空你的选择? 尝试:

@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();
    }
}


Answer 4:

我建议不设置代码中的图片尺寸,让相机返回它可以捕捉到最佳画面。 请在这里给出的答案代码。 https://stackoverflow.com/a/9745780/2107118



Answer 5:

你是从背部摄像头的参数设置前置摄像头? 另一件事测试是前置摄像头,第一次尝试没有设置任何参数,只使用默认设置,看看它是否会奏效。 我跑进三星设备类似的问题,但是这是为后置摄像头。 您可能还需要旋转前置摄像头拍摄的图像(三星设备后置摄像头需要太)

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);
    }


Answer 6:

我应该还提到,保存数据,直接使用一个FileOutputStream是创造一个合适的JPEG图像。 所以这个问题必须与BitmapFactory和我创建位图的方式。

相机输出完全处理JPEG数据(希望如此),并且可以将其写入到磁盘。 现在,你应该尝试什么:

  1. 转储文件保存到磁盘。
  2. 检查使用该文件验证工具 ,或者在PC上的一些图像编辑器。
  3. 如果图像编辑器中打开图像细腻,从图像编辑器保存副本,使用标准的JPEG轮廓。
  4. BitmapFactory过程中的原始文件和文件的图像编辑器保存的,看看你在这两个得到一个坏的位图。

如果图像是有效的JPEG和BitmapFactory仍然会产生错误的位图,该问题是与BitmapFactory (不太可能),如果由摄像机输出的文件是无效的JPEG,问题是相机(更可能)。



Answer 7:

这是我的代码,我用它来拍照,并将其保存在数据库中,在不改变其质量。

首先,你需要这个变量:

 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;
}

我希望这可以帮助你。



文章来源: Camera picture to Bitmap results in messed up image