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