Сохранить растровое изображение кусками

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

Однажды прочитайте это, прежде чем продолжить

Эффективное отображение растровых изображений

Обработка растровых изображений вне потока пользовательского интерфейса

Загрузить уменьшенную версию в память

Управление растровой памятью

Другие вопросы по тегам