2

在使用BitmapFactory.Options.inSampleSize. 问题是存储位图的文件大小至少是原始文件大小的两倍。我进行了很多搜索,但找不到如何处理这个问题,因为我不希望它发生以提高内存效率(后来我重用存储的位图)。这是我描述的方法:

private Bitmap decodeFileToPreferredSize(File f) {
    Bitmap b = null;
    try {
        // Decode image size
        Log.i("Bitmap", "Imported image size: " + f.length() + " bytes");
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;

        BitmapFactory.decodeFile(f.getAbsolutePath(), o);

        //Check if the user has defined custom image size
        int scale = 1;
        if(pref_height != -1 && pref_width != -1) {

            if (o.outHeight > pref_height || o.outWidth > pref_width) {

                scale = (int) Math.pow(
                        2,
                        (int) Math.round(Math.log(pref_width
                                / (double) Math.max(o.outHeight, o.outWidth))
                                / Math.log(0.5)));
            }
        }

        // Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        b = BitmapFactory.decodeFile(f.getAbsolutePath(), o2);
        String name = "Image_" + System.currentTimeMillis() + ".jpg";
        File file = new File(Environment.getExternalStorageDirectory(), name);
        FileOutputStream out = new FileOutputStream(file);
        b.compress(Bitmap.CompressFormat.JPEG, 100, out);
        out.close();
        Log.i("Bitmap", "Exported image size: " + file.length() + " bytes");

    } catch (Exception e) {
        b = null;
    }

    return b;
}

更新我看到了两个图像文件的密度。来自相机意图的那个具有 72 dpi 的宽度和高度密度。从我上面的方法创建的图像文件的宽度和高度密度为 96 dpi。这解释了为什么使用我的上述方法将来自相机的 0.5 MB 图像的大小调整为大约 2.5 MB,因为重新缩放因子是 (96/72) * 2 ~= 2.5。出于某种原因,我创建的位图没有采用来自相机的图像的密度。我试图用 BitmapFactory.Options.inDensity 的所有变化来设置密度,但没有运气。我也尝试改变位图密度,bitmap.setDensity(int dpi);但仍然没有效果。所以,我的新问题是是否有办法在存储图像时定义位图的密度。

提前致谢。

4

3 回答 3

2

我有一个类似的问题。当我从网上下载图像时,它们在 SD 上使用的空间比从浏览器下载到我的 PC 时更多。我认为问题只是 BitmapFactory 以某种非优化格式保存图像。

我的解决方法是使用以下而不是位图工厂:

    try {
        try {
            is = yourinputstream;
            // Consider reading stream twice and return the bitmap.

            os = youroutputstream;

            byte data[] = new byte[4096];
            int count;
            while ((count = is.read(data)) != -1) {
                os.write(data, 0, count);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(is != null) {
                is.close();
            }
            if(os != null) {
                os.close();
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
于 2012-07-12T10:35:54.407 回答
2

你说得对,问题出在密度变化上。

该线程揭示了一个解决方案:BitmapFactory 返回比源更大的图像

在解码之前也禁用inScaled

options.inSampleSize = 2; //or however you desire, power of 2
options.inScaled = false;

这将保持密度不变,您将看到您正在寻找的尺寸减小。

于 2016-12-21T00:44:57.310 回答
0

当 时BitmapFactory.Options.inSampleSize = 0.5,它是 100% / 0.5 = 200%。
我想你想要的是BitmapFactory.Options.inSampleSize = 2100% / 2 = 50%

于 2012-07-12T08:47:52.580 回答