Android相机参数setPictureSize导致条纹图片 [英] Android Camera Parameter setPictureSize causes streaked picture

查看:473
本文介绍了Android相机参数setPictureSize导致条纹图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图把使用Android相机拍摄照片。我有一个要求,捕捉1600(宽)×1200(H)图像(第三方供应商的要求)。我的code似乎很好地工作了很多手机摄像头,但setPictureSize导致某些手机(三星Galaxy S4,三星Galaxy Note)崩溃,并导致对他人条纹图像(Nexus 7平板电脑)。上至少Nexus的我想要的大小上显示的是getSupportPictureSizes列表

我已经试过指定的方向,但它并没有帮助。以使用默认的图片尺寸画面正常工作。

下面是条纹的示例:

有关我的形象捕获我的1600×1200,JPG,30%的玉米pression的要求,所以我拍摄JPG文件。

我觉得我有三种选择:
1)弄清楚如何捕捉1600×1200尺寸没有崩溃或条纹,或
2)找出如何将默认图片尺寸的大小更改为JPG是1600×1200。
3)别的东西,目前还不清楚我的。

我发现有类似的问题,但不完全一样的其他一些帖子。我在我的努力的事情第二天,但我没有找到一个解决方案。这里有一个发帖称亲近:

<一个href=\"http://stackoverflow.com/questions/15404547/camera-picture-to-bitmap-results-in-messed-up-image\">Camera图片在搞砸图片位图的结果(无的建议,帮助我)

下面是我的code的,对于直到我跑进S4 /注工作的罚款节/ 7的Nexus我已经平添了几分调试code的现在:

  Camera.Parameters参数= mCamera.getParameters();
Camera.Size大小= getBest previewSize(宽度,高度,参数);如果(大小!= NULL){
    INT pictureWidth = 1600;
    INT pictureHeight = 1200;    //测试
    Camera.Size测试= parameters.getPictureSize();
    清单&LT; Camera.Size&GT; testSizes = parameters.getSupportedPictureSizes();
    的for(int i = 0; I&LT; testSizes.size();我++){
        测试= testSizes.get(ⅰ);
    }    测试= testSizes.get(3);
    //得到(3)是1600×1200
    pictureWidth = test.width;
    pictureHeight = test.height;    parameters.setPictureFormat(ImageFormat.JPEG);
    parameters.setPictureSize(pictureWidth,pictureHeight);
    parameters.setJpegQuality(30);
    parameters.set previewSize(size.width,size.height);    //捕捉任何异常
    尝试{
        //确保preVIEW停止
        mCamera.stop preVIEW();        mCamera.setParameters(参数);
        didConfig =真;
    赶上(例外五){
        //一些错误presentation是为简洁,删除
        //因为didConfig未设置为true,将正常失败
    }
}

下面是我的code的,节省了JPG文件的部分:

  PictureCallback jpegCallback =新PictureCallback(){
    公共无效onPictureTaken(字节[]数据,相机摄像头){
        如果(data.length大于0){            字符串文件名=image.jpg的;            档案文件=新的文件(getFilesDir(),文件名);
                串文件路径= file.getAbsolutePath();             布尔goodWrite = FALSE;
             尝试{
                 OutputStream的OS =新的FileOutputStream(文件);
                 os.write(数据);
                 os.close();                goodWrite = TRUE;
            }赶上(IOException异常五){
                 goodWrite = FALSE;
             }             如果(goodWrite){
                //去到preVIEW
             }其他{
                // TODO错误返回到调用活动
             }        }        Log.d(TAGonPictureTaken - JPEG);
    }
};

如何正确设置相机参数,拍照或如何裁剪或调整所产生的照片将是巨大的任何建议。尤其是如果它会与旧相机(API级别8或更高版本)工作!根据需要在图像I只能剪切掉顶部的整个宽度。

谢谢!

编辑:这是我落得这样做:

我开始通过处理Camera.Parameters getSupportedPictureSizes使用的第一个具有的高度和宽度都大于我的期望的尺寸,和相同的宽度:高度比率。我设置相机参数到图片的大小。

然后,一旦图片拍摄:

  BitmapFactory.Options选项=新BitmapFactory.Options();;
options.inPurgeable = TRUE;//字节数组转换为位图,注意让垃圾收集
位图原= BitmapFactory.de codeByteArray的(输入,0,input.length,期权);
//调整位图到我期望的规模
位图大小= Bitmap.createScaledBitmap(原件,1600,1200,真正的);//创建一个新的字节数组输出位图到COM pressed JPG
ByteArrayOutputStream BLOB =新ByteArrayOutputStream();
resized.com preSS(Bitmap.Com pressFormat.JPEG,30,BLOB);//回收内存,因为位图似乎有稍微不同的垃圾回收
original.recycle();
resized.recycle();字节[] =所需blob.toByteArray();

然后,我写出来的预期JPG至要上传的文件。


解决方案

 检测= testSizes.get(3);
//得到(3)是1600×1200

有没有要求阵列有4+元素,更不用说第四个元素是1600×1200。


  

1)弄清楚如何捕捉1600×1200尺寸而不崩溃或裸奔


有不能保证每个设备能够拍摄图片的精确分辨率。你不能指定分辨率任意值 - 它必须是支持的图片尺寸之一。的部分的设备都支持任意值,而其他设备会给你损坏的输出(如这里的情况)或将平了崩溃。​​


  

2)找出如何将默认图片尺寸的大小更改为JPG是1600×1200


我不知道,有一个默认图片大小,除此之外,这样的尺寸将是不可改变的,因为它是默认的。改变画面大小为你上面的选项1。


  

3)别的东西,目前还不清楚我的。


对于支持的分辨率越大两轴装置,拍摄一张照片在该决议中,然后再剪裁到1600×1200。

对于所有其他设备,其中一个或两个轴比预期小,拍照以任何分辨率适合你(最大,最匹配的4:3纵横比等),然后伸展/作物去1600×1200。

I am trying to take a picture using the Android camera. I have a requirement to capture a 1600 (w) x 1200 (h) image (3rd party vendor requirement). My code seems to work fine for many phone cameras but the setPictureSize causes a crash on some phones (Samsung Galaxy S4, Samsung Galaxy Note) and causes a streaked picture on others (Nexus 7 Tablet). On at least the Nexus the size I desire is showing up in the getSupportPictureSizes list.

I have tried specifying the orientation but it didn't help. Taking the picture with the default picture size works fine.

Here is an example of the streaking:

For my image capture I have a requirement of 1600x1200, jpg, 30% compression, so I am capturing a JPG file.

I think I have three choices: 1) Figure out how to capture the 1600x1200 size without a crash or streaking, or 2) Figure out how to change the size of the default picture size to a JPG that is 1600x1200. 3) Something else that is currently unknown to me.

I have found some other postings that have similar issues but not quite the same. I am in my 2nd day of trying things but am not finding a solution. Here is one posting that got close:

Camera picture to Bitmap results in messed up image (none of the suggestions helped me)

Here is the section of my code that worked fine for until I ran into the S4/Note/Nexus 7. I have added a bit of debugging code for now:

Camera.Parameters parameters = mCamera.getParameters();
Camera.Size size = getBestPreviewSize(width, height, parameters);

if (size != null) {
    int pictureWidth = 1600;
    int pictureHeight = 1200;

    // testing
    Camera.Size test = parameters.getPictureSize();
    List<Camera.Size> testSizes = parameters.getSupportedPictureSizes();
    for ( int i = 0; i < testSizes.size(); i++ ) {
        test = testSizes.get(i);
    }

    test = testSizes.get(3);
    // get(3) is 1600 x 1200
    pictureWidth = test.width;
    pictureHeight = test.height;

    parameters.setPictureFormat(ImageFormat.JPEG);
    parameters.setPictureSize(pictureWidth, pictureHeight);
    parameters.setJpegQuality(30);
    parameters.setPreviewSize(size.width, size.height);

    // catch any exception
    try {
        // make sure the preview is stopped
        mCamera.stopPreview();

        mCamera.setParameters(parameters);
        didConfig = true;
    catch(Exception e) {
        // some error presentation was removed for brevity
        // since didConfig not set to TRUE it will fail gracefully
    }
}

Here is the section of my code that saves the JPG file:

PictureCallback jpegCallback = new PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
        if ( data.length > 0 ) {

            String fileName = "image.jpg";

            File file = new File(getFilesDir(), fileName);
                String filePath = file.getAbsolutePath();

             boolean goodWrite = false;
             try {
                 OutputStream os = new FileOutputStream(file);
                 os.write(data);
                 os.close();

                goodWrite = true;
            } catch (IOException e) {
                 goodWrite = false;
             }

             if ( goodWrite ) {
                // go on to the Preview
             } else {
                // TODO return an error to the calling activity
             }

        }

        Log.d(TAG, "onPictureTaken - jpeg");
    }
};

Any suggestions on how to correctly set up the camera parameters for taking photos or how to crop or resize the resulting photo would be great. Especially if it will work with older cameras (API level 8 or later)! Based on needing the full width of the picture I can only crop off the top.

Thanks!

EDIT: Here is what I ended up doing:

I started by processing the Camera.Parameters getSupportedPictureSizes to use the first one that had the height and width both greater than my desired size, AND the same width:height ratio. I set the Camera parameters to that picture size.

Then once the picture was taken:

BitmapFactory.Options options = new BitmapFactory.Options();;
options.inPurgeable = true;

// convert the byte array to a bitmap, taking care to allow for garbage collection
Bitmap original = BitmapFactory.decodeByteArray(input , 0, input.length, options);
// resize the bitmap to my desired scale 
Bitmap resized = Bitmap.createScaledBitmap(original, 1600, 1200, true);

// create a new byte array and output the bitmap to a compressed JPG
ByteArrayOutputStream blob = new ByteArrayOutputStream();
resized.compress(Bitmap.CompressFormat.JPEG, 30, blob);

// recycle the memory since bitmaps seem to have slightly different garbage collection
original.recycle();
resized.recycle();

byte[] desired = blob.toByteArray();

Then I write out the desired jpg to a file for upload.

解决方案

test = testSizes.get(3);
// get(3) is 1600 x 1200

There is no requirement that the array have 4+ elements, let alone that the fourth element be 1600x1200.

1) Figure out how to capture the 1600x1200 size without a crash or streaking

There is no guarantee that every device is capable of taking a picture with that exact resolution. You cannot specify arbitrary values for the resolution -- it must be one of the supported picture sizes. Some devices support arbitrary values, while other devices will give you corrupted output (as is the case here) or will flat-out crash.

2) Figure out how to change the size of the default picture size to a JPG that is 1600x1200

I am not aware that there is a "default picture size", and, beyond that, such a size will be immutable, since it is the default. Changing the picture size is your option #1 above.

3) Something else that is currently unknown to me.

For devices that support a resolution that is bigger on both axes, take a picture in that resolution, then crop to 1600x1200.

For all other devices, where one or both axes are smaller than desired, take a picture in whatever resolution suits you (largest, closest match to 4:3 aspect ratio, etc.), and then stretch/crop to get to 1600x1200.

这篇关于Android相机参数setPictureSize导致条纹图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆