以块的形式保存位图图像
Posted
技术标签:
【中文标题】以块的形式保存位图图像【英文标题】:Save bitmap image in chunks 【发布时间】:2013-03-11 20:26:06 【问题描述】:我想将位图图像保存在 sd 卡中,我可以保存它,但有时我的活动因内存不足而被杀死。
所以我可以将图像保存在块中,而不是以字节数组的形式保存。
我的代码如下:
try
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
File f = new File(Environment.getExternalStorageDirectory() + File.separator + "temp.jpg");
if (f.exists())
f.delete();
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.flush();
fo.close();
catch (Exception e)
e.printStackTrace();
【问题讨论】:
是否显示任何错误,如果是,请发布您的 logcat。 没有 Grishu,它只会杀死活动并降低活动堆栈中的活动。我已经在具有更多内存的设备中尝试过这个,它工作正常,所以我得出结论,这是内存问题。 查看我的答案并尝试使用它,确保它会对您有所帮助。 我已经对图像进行了缩放。 :( 查看我的更新答案。 【参考方案1】:要减少此问题,您可以做的一件事是调整图像的大小,然后将其保存到内存中。
下面是有帮助的代码。你可以试试下面的方法。
// decodes image and scales it to reduce memory consumption public static Bitmap decodeFile(File p_f) try // decode image size BitmapFactory.Options m_opt = new BitmapFactory.Options(); m_opt.inJustDecodeBounds = true; BitmapFactory.decodeStream(new FileInputStream(p_f), null, m_opt); // Find the correct scale value. It should be the power of 2. final int REQUIRED_SIZE = 70; int m_widthTmp = m_opt.outWidth, m_heightTmp = m_opt.outHeight; int m_scale = 1; while (true) if (m_widthTmp / 2 < REQUIRED_SIZE || m_heightTmp / 2 < REQUIRED_SIZE) break; m_widthTmp /= 2; m_heightTmp /= 2; m_scale *= 2; // decode with inSampleSize BitmapFactory.Options m_o2 = new BitmapFactory.Options(); m_o2.inSampleSize = m_scale; return BitmapFactory.decodeStream(new FileInputStream(p_f), null, m_o2); catch (FileNotFoundException p_e) return null;
已编辑:
您还可以检查 sdcard 中是否有可用空间,并根据可用空间将图像保存到 sdcard。我已经使用以下方法来获取可用空间。
/** * This function find outs the free space for the given path. * * @return Bytes. Number of free space in bytes. */ public static long getFreeSpace() try if (Environment.getExternalStorageDirectory() != null && Environment.getExternalStorageDirectory().getPath() != null) StatFs m_stat = new StatFs(Environment.getExternalStorageDirectory().getPath()); long m_blockSize = m_stat.getBlockSize(); long m_availableBlocks = m_stat.getAvailableBlocks(); return (m_availableBlocks * m_blockSize); else return 0; catch (Exception e) e.printStackTrace(); return 0;
使用上面的如下:
if (fileSize <= getFreeSpace()) //write your code to save the image into the sdcard. else //provide message that there is no more space available.
【讨论】:
Grishu,什么是文件大小?写入文件大小为 0 对吗?filesize
是您拥有的文件。【参考方案2】:
解决此问题的最佳方法是将图像大小缩小到所需的视图大小,并在后台线程(异步任务)上完成所有繁重的工作,当您的后台线程工作时,您可以显示任何虚拟图像表单资源,一旦图像被正确处理,将您的位图替换为前一个。
阅读本文后,再继续
Displaying Bitmaps Efficiently
Processing Bitmaps Off the UI Thread
Load a Scaled Down Version into Memory
Managing Bitmap Memory
【讨论】:
以上是关于以块的形式保存位图图像的主要内容,如果未能解决你的问题,请参考以下文章