Android摄像头参数setPictureSize导致条纹图片

Android摄像头参数setPictureSize导致条纹图片,android,image-processing,android-camera,Android,Image Processing,Android Camera,我正在尝试用安卓相机拍照。我需要拍摄1600(宽)x1200(高)的图像(第三方供应商要求)。我的代码对于许多手机摄像头来说似乎工作正常,但setPictureSize会在某些手机(三星Galaxy S4、三星Galaxy Note)上导致崩溃,并在其他手机(Nexus 7平板电脑)上导致条纹图片。至少在Nexus上,我想要的大小显示在getSupportPictureSizes列表中 我试着指定方向,但没有帮助。使用默认图片大小拍摄图片效果良好 以下是条纹的一个示例: 对于我的图像捕获,我需

我正在尝试用安卓相机拍照。我需要拍摄1600(宽)x1200(高)的图像(第三方供应商要求)。我的代码对于许多手机摄像头来说似乎工作正常,但setPictureSize会在某些手机(三星Galaxy S4、三星Galaxy Note)上导致崩溃,并在其他手机(Nexus 7平板电脑)上导致条纹图片。至少在Nexus上,我想要的大小显示在getSupportPictureSizes列表中

我试着指定方向,但没有帮助。使用默认图片大小拍摄图片效果良好

以下是条纹的一个示例:

对于我的图像捕获,我需要1600x1200,jpg,30%的压缩,所以我要捕获一个jpg文件

我想我有三个选择: 1) 了解如何在不发生碰撞或条纹的情况下捕获1600x1200尺寸,或 2) 了解如何将默认图片大小更改为1600x1200的JPG。 3) 我目前还不知道的其他事情

我发现其他一些帖子也有类似的问题,但并不完全相同。我在尝试的第二天,但没有找到解决办法。这里有一个帖子很接近:

(这些建议对我都没有帮助)

这是我的代码中在遇到S4/Note/nexus7之前一直运行良好的部分。我现在添加了一些调试代码:

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
    }
}
任何关于如何正确设置拍照相机参数或如何裁剪或调整结果照片大小的建议都将非常有用。尤其是如果它将与旧相机(API级别8或更高版本)一起使用!基于需要图片的全宽,我只能从顶部裁剪

谢谢

编辑:以下是我最后做的事情:

我从处理相机开始。参数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写入一个文件以供上传

test = testSizes.get(3);
// get(3) is 1600 x 1200
阵列不需要4+个元素,更不用说第四个元素是1600x1200

1) 了解如何在不发生碰撞或条纹的情况下捕获1600x1200大小的图像

并不能保证每台设备都能拍摄到精确分辨率的照片。您不能为分辨率指定任意值——它必须是受支持的图片大小之一。一些设备支持任意值,而其他设备将提供损坏的输出(这里就是这种情况)或将彻底崩溃

2) 了解如何将默认图片大小更改为1600x1200的JPG

我不知道有一个“默认图片大小”,除此之外,这个大小将是不变的,因为它是默认的。更改图片大小是您的选择#1以上

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

对于在两个轴上都支持更高分辨率的设备,请以该分辨率拍照,然后裁剪到1600x1200


对于所有其他设备,如果一个或两个轴都小于所需的尺寸,请以适合您的分辨率(最大、最接近4:3纵横比等)拍摄一张照片,然后拉伸/裁剪到1600x1200。

奇怪的是,1600x1200尺寸被列为支持的图片尺寸,但我的输出仍然损坏。由于供应商要求,我无法拉伸或收缩一个方向(请检查图像捕获以获取押金)。我可以根据用户在预览窗口中对齐图像的方式裁剪顶部。我是否需要使用位图进行图像处理,然后转换为jpg?(默认大小是指更改任何设置之前getPictureSize()中的大小。)@Gravioid:“奇怪的是,1600x1200大小被列为支持的图片大小,但我仍然得到损坏的输出”——这当然是可能的。我通常关注最高的相机分辨率,当然也有一些设备会报告分辨率有缺陷的输出。“由于供应商的要求,我无法拉伸或收缩一个方向”-那么你就不能编写你的应用程序,因为没有要求相机在任何给定轴上支持1600或1200像素。@Gravioid:此外,我对你为什么担心“条纹”感到困惑。据你自己承认,你的应用程序在某些设备上崩溃。相比之下,条纹图像是一个积极的结果。谢谢你提供的好信息。我担心的是崩溃发生在一款非常流行的三星Galaxy S4手机上,我不愿意说我的应用程序不支持这款手机。我宁愿找到一个解决方案,工作的S4以及所有的手机已经工作。Nexus7平板电脑上出现了裸奔/损坏,虽然比崩溃要好,但仍然不是一个可用的结果(我碰巧拥有Nexus,但没有S4)。如果我使用可能的最高分辨率,或者当前设置的分辨率,如果它与4:3的比例匹配,那么有没有关于如何达到1600x1200的建议?@gravioid:“我不愿意说我的应用程序不支持手机”——你的供应商需要接受现实,不是每个摄像头都会屈服于他们的意愿。裁剪和/或缩放是不可避免的。“关于如何达到1600x1200有什么建议吗?”——正如我在回答中提到的,您必须进行裁剪或缩放。有
createBitmap()
createScaledBitmap()
可以处理这个问题。
test = testSizes.get(3);
// get(3) is 1600 x 1200