Search code examples
androidandroid-sdcardsave-image

Save bitmap image in chunks


I want to save bitmap image in sd card, i am able to save it but some time my activity is killed because of low ram.

So can i save image in chunks rather to save in form of byte array.

My code is like below:

    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();
    }

Solution

  • To reduce this issue one thing you can do is to resize of rescale the image and then after save it into the memory.

    Below is the code which will help . You can try out below method.

      // 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;
    }
    

    EDITED:

    You can also check for whether a space is available in sdcard or not and based on available space you can save the image into sdcard. I have used below method to get the free space available or not.

     /**
     * 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;
        }
    }
    

    Use the above as below:

         if (fileSize <= getFreeSpace())
       {
            //write your code to save the image into the sdcard.
           } 
           else
           {
             //provide message that there is no more space available.
             }