我正在构建一个应用程序,我可以处理 10000X5000像素的超大图像。当我尝试在ImageView上显示此类图像时,应用程序崩溃了。 我无法进行位图采样,因为我无法改变图像的大小。
一项简单的工作是选择10000X5000像素的图像并将其显示在ImageView中。
目前,我正在使用简单的代码来实现此目的,应用程序正在崩溃。
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
// Get the cursor
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
// Move to first row
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imgDecodableString = cursor.getString(columnIndex);
cursor.close();
ImageView imgView = (ImageView) findViewById(R.id.imgView);
// Set the Image in ImageView after decoding the String
imgView.setImageBitmap(BitmapFactory
.decodeFile(imgDecodableString));
Exception是OutOfMemory
E / AndroidRuntime:致命异常:主要 流程:com.example.star.largeiamgesdemo,
PID:21155 java.lang.OutOfMemoryError:无法分配200000012字节 分配4194208个空闲字节和123MB直到OOM
像MemoryMapFile
之类的东西可以做到这一点,但文件没有为FileChannel
更新
我无法缩小图像,同时显示因为我必须编辑它们(即用户可以在图像上写一些东西,或将其他图像作为水印放在它们上面)
由于
答案 0 :(得分:3)
正如你所说:
我无法进行位图采样,因为我无法改变图像的大小。
所以,减少图像大小或在显示之前对其进行采样,是不行的。我认为下面是一个解决方案。
由于Android的dalvik限制,您可以使用最大堆大小。超过它时,发生崩溃。
为了绕过dalvik限制,您可以使用jni从本机堆中申请内存。您必须在jni中使用or
。您可以在SurfaceView上选择显示图像,然后通过libjpeg
获取Surface对象,将其传递给jni,然后使用holder.getSurface()
lib解码图像并显示它。接下来是一些示例代码,调用libjpeg
函数来显示大图像。
showJPG()
希望能帮到你!
答案 1 :(得分:0)
很明显,您必须缩小图片尺寸,否则您的手机无法呈现图片以显示在ImageView
中。因此,您需要缩小图像,以便可以在ImageView
。
int imageScaleWidth = 480; // Change the width
Bitmap bitmapImage = BitmapFactory.decodeFile(imgDecodableString); // imgDecodableString is your image path.
int imageScaleHeigth = (int) ( bitmapImage.getHeight() * (imageScaleWidth / bitmapImage.getWidth()) );
Bitmap scaled = Bitmap.createScaledBitmap(bitmapImage, imageScaleWidth , imageScaleHeigth , true);
imgView.setImageBitmap(scaled);
答案 2 :(得分:0)
您应该阅读"高效加载大型位图"
上的Android文档特别是,你提到你不能用于"位图采样"但请注意,Android允许您读取图像文件大小,然后计算适用于可用大小的采样。 Android将只加载采样位图,这很好,因为屏幕分辨率不足以正确显示这样的图像。
另外,请务必考虑方法decodeSampledBitmapFromResource
以获取缩略图。
https://developer.android.com/training/displaying-bitmaps/load-bitmap.html#load-bitmap
最后,如果需要,请务必使用largeHeap
Manifest
属性 - 并根据文档查看其他内存优化技术: