1

ビットマップ画像をSDカードに保存したいのですが、保存できますが、RAMが少ないためにアクティビティが停止することがあります。

したがって、バイト配列の形式で保存するのではなく、画像をチャンクで保存できますか?

私のコードは以下のようなものです:

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

2 に答える 2

1

この問題を減らすためにできることの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で空き容量があるかどうかを確認したり、空き容量に基づいて画像をSDカードに保存したりすることもできます。空き容量を確保するために、以下の方法を使用しました。

 /**
 * 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.
         }  
于 2013-03-22T04:35:53.593 に答える
1

この問題を解決する最善の方法は、画像のサイズを必要なビューサイズに縮小し、背景スレッドですべての重い作業を行うことです(非同期タスク)。背景スレッドが機能している間は、任意のダミー画像フォームを表示できます。リソースを取得し、画像が適切に処理されたら、ビットマップを前のビットマップに置き換えます。

これを読んだら、先に進む前に

ビットマップを効率的に表示する

UIスレッドからのビットマップの処理

スケールダウンしたバージョンをメモリにロードする

ビットマップメモリ​​の管理

于 2013-03-22T04:23:25.360 に答える