我正在尝试使用Android相机拍照。我需要捕获一个1600 (w) x 1200 (h)的图像(第三方供应商要求)。我的代码似乎对许多手机相机都有效,但在某些手机上(三星Galaxy S4,三星Galaxy Note)setPictureSize会导致崩溃,在其他手机(Nexus 7平板电脑)上会导致带条纹的图片。至少在Nexus上,我想要的大小出现在getSupportPictureSizes列表中。
我已经尝试指定方向,但没有帮助。使用默认图片大小拍照正常。
这是条带的示例: 对于我的图像捕获,我需要1600x1200像素、jpg格式、30%压缩比的要求,因此我正在捕获JPG文件。我认为我有三个选择: 1)找出如何在没有崩溃或条纹的情况下捕获1600x1200大小的图像; 2)找出如何将默认图片大小更改为1600x1200的JPG格式; 3)其他我目前不知道的方法。
我发现一些其他帖子存在类似的问题,但并不完全相同。我已经尝试了两天,但没有找到解决方案。这里是一个接近解决的帖子: Camera picture to Bitmap results in messed up image(没有一个建议对我有用)
这是我的代码部分,在遇到S4/Note/Nexus 7之前它很好用。我现在添加了一些调试代码:
任何有关如何正确设置相机参数以拍摄照片,或如何裁剪或调整所得照片的建议都将非常有用。特别是如果它能与旧相机(API级别8或更高)兼容!基于需要使用图片的全宽,我只能从顶部裁剪。
谢谢!
编辑:这是我最终采取的做法:
我首先处理了Camera.Parameters getSupportedPictureSizes,选择第一个高度和宽度均大于我的所需尺寸,并且具有相同宽高比的图像尺寸。然后我将相机参数设置为该图片大小。
然后一旦拍摄完成:
然后我将所需的 jpg 写入文件以进行上传。
我已经尝试指定方向,但没有帮助。使用默认图片大小拍照正常。
这是条带的示例: 对于我的图像捕获,我需要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 写入文件以进行上传。
createBitmap()
和createScaledBitmap()
可以处理这个问题。 - CommonsWare