【问题标题】:Save bitmap image in chunks以块的形式保存位图图像
【发布时间】:2023-04-07 22:45:01
【问题描述】:

我想将位图图像保存在 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,它只会杀死活动并降低活动堆栈中的活动。我已经在具有更多内存的设备中尝试过这个,它工作正常,所以我得出结论,这是内存问题。
  • 查看我的答案并尝试使用它,确保它会对您有所帮助。
  • 我已经对图像进行了缩放。 :(
  • 查看我的更新答案。

标签: android android-sdcard save-image


【解决方案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

【讨论】:

    猜你喜欢
    • 2018-02-19
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    • 2016-01-05
    • 2017-07-19
    • 2016-05-19
    相关资源
    最近更新 更多