Android相机参数setPictureSize会导致条纹图片

时间:2014-04-04 14:29:26

标签: android image-processing android-camera

我正在尝试使用Android相机拍照。我需要捕获1600(w)x 1200(h)图像(第三方供应商要求)。我的代码似乎适用于许多手机摄像头,但是setPictureSize会导致某些手机(三星Galaxy S4,三星Galaxy Note)崩溃并导致其他手机(Nexus 7平板电脑)出现条纹图像。至少在Nexus上,我想要的大小显示在getSupportPictureSizes列表中。

我已尝试指定方向,但它没有帮助。使用默认图片尺寸拍摄照片效果很好。

这是裸奔的一个例子:

enter image description here

对于我的图像捕获,我需要1600x1200,jpg,30%压缩,所以我正在捕获JPG文件。

我想我有三个选择: 1)弄清楚如何在没有碰撞或条纹的情况下捕获1600x1200尺寸,或者 2)弄清楚如何将默认图片大小的大小更改为1600x1200的JPG。 3)我目前不知道的其他东西。

我发现其他一些帖子有类似的问题,但不完全相同。我正在尝试第二天,但我找不到解决方案。这是一篇贴近的帖子:

Camera picture to Bitmap results in messed up image(这些建议都没有帮助我)

以下是我的代码部分,在我遇到S4 / Note / Nexus 7之前一直运行良好。我现在添加了一些调试代码:

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

以下是保存JPG文件的代码部分:

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

有关如何正确设置相机参数以拍摄照片或如何裁剪或调整结果照片大小的任何建议都会很棒。特别是如果它适用于较旧的相机(API等级8或更高版本)!基于需要图片的整个宽度,我只能裁掉顶部。

谢谢!

编辑:这是我最终做的事情:

我开始处理Camera.Parameters getSupportedPictureSizes以使用第一个高度和宽度都大于我想要的大小,以及相同的宽度:高度比。我将相机参数设置为该图片大小。

然后拍完照片后:

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

然后我将所需的jpg写入文件进行上传。

1 个答案:

答案 0 :(得分:4)

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

不要求阵列有4个以上的元素,更不用说第四个元素是1600x1200。

  

1)弄清楚如何在没有碰撞或条纹的情况下捕捉1600x1200尺寸

无法保证每台设备都能够以精确的分辨率拍摄照片。您无法为分辨率指定任意值 - 它必须是支持的图片大小之一。 某些设备支持任意值,而其他设备会为您提供损坏的输出(如此处所示)或将导致崩溃。

  

2)弄清楚如何将默认图片大小的大小更改为1600x1200的JPG

我不知道存在“默认图片大小”,除此之外,这样的大小将是不可变的,因为它是默认的。更改图片大小是您上面的选项#1。

  

3)我目前还不知道的其他事情。

对于支持两个轴上较大分辨率的设备,请以该分辨率拍摄照片,然后裁剪为1600x1200。

对于其中一个或两个轴小于所需的所有其他设备,请拍摄适合您的分辨率(最大,最接近4:3宽高比等),然后拉伸/裁剪到达1600×1200。