Сохранить растровое изображение кусками
Я хочу сохранить растровое изображение на 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();
}
2 ответа
Чтобы уменьшить эту проблему, вы можете изменить размер изображения, а затем сохранить его в памяти.
Ниже приведен код, который поможет. Вы можете попробовать метод ниже.
// 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. }
Лучший способ решить эту проблему - уменьшить размер изображения до требуемого размера представления и выполнить всю тяжелую работу в фоновом потоке (Async Task), пока работает фоновый поток, вы можете показать любую фиктивную форму изображения. ресурс, и как только изображение будет правильно обработано, замените ваше растровое изображение на предыдущее.
Однажды прочитайте это, прежде чем продолжить
Эффективное отображение растровых изображений
Обработка растровых изображений вне потока пользовательского интерфейса