我正在尝试解码在Android设备上拍摄的图像而不会耗尽设备上的内存,我终于遇到了this指南并跟着它导致了这3种方法:
public static FileDescriptor getDescriptorFromFile(File file, Context context) throws FileNotFoundException {
Uri photoUri = Uri.fromFile(file);
ContentResolver resolver = context.getContentResolver();
ParcelFileDescriptor pfd = resolver.openFileDescriptor(photoUri, "r");
FileDescriptor fd = pfd.getFileDescriptor();
return fd;
}
public static Bitmap decodeSampledBitmap(FileDescriptor descriptor, int reqWidth, int reqHeight) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(descriptor, null, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFileDescriptor(descriptor, null, options);
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
这些方法的用法如下:
ImageView imageView = (ImageView) findViewById(R.id.photo_taken);
int width = imageView.getMeasuredWidth();
int height = imageView.getMeasuredHeight();
final FileDescriptor fd = CameraUtils.getDescriptorFromFile(filePath, this);
Bitmap bitmap = CameraUtils.decodeSampledBitmap(fd, 250, 250);
imageView.setImageBitmap(bitmap);
理想情况下,我希望将250个值设置为视图的宽度和高度,但是当我制作它们时,任何更大的decodeSampleBitmap()都会返回null并且我不能为我的生活找出原因吗?
非常感谢您对此问题的任何帮助。
修改
现在我已经使我的捕获图像变得更大了,我再次必须使这些值更小,以便它不会返回null。现在值不能大于150,150
答案 0 :(得分:0)
所以我设法通过简单地从
切换来解决这个问题BitmapFactory.decodeFileDescriptor(descriptor, null, options);
为:
BitmapFactory.decodeStream(fileInputStream, null, options);
我不知道为什么这会产生如此大的差异但确实如此,图像输出的质量是完美的,几乎没有质量损失,没有内存问题。
我的完整代码如下:
解码:
public static Bitmap decodeSampledBitmap(File file, int reqWidth, int reqHeight) throws FileNotFoundException {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inPreferredConfig = Bitmap.Config.RGB_565;
BitmapFactory.decodeStream(new FileInputStream(file), null, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeStream(new FileInputStream(file), null, options);
}
计算样本量:
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
使用:
ImageView imageView = (ImageView) findViewById(R.id.photo_taken);
int width = imageView.getMeasuredWidth();
int height = imageView.getMeasuredHeight();
File file = //get your file
Bitmap bitmap = CameraUtils.decodeSampledBitmap(file, height, width);
imageView.setImageBitmap(bitmap);
注意:我使用height作为宽度,反之亦然,因为我稍后将位图旋转90度。