【问题标题】:Bitmap byte-size after decoding?解码后的位图字节大小?
【发布时间】:2011-01-25 08:09:49
【问题描述】:

如何确定/计算位图的字节大小(使用 BitmapFactory 解码后)? 我需要知道它占用了多少内存空间,因为我正在我的应用程序中进行内存缓存/管理。 (文件大小不够,因为这些是 jpg/png 文件)

感谢您的任何解决方案!

更新:getRowBytes * getHeight 可能会成功。我会以这种方式实现它,直到有人提出反对意见。

【问题讨论】:

    标签: android bitmap


    【解决方案1】:

    getRowBytes() * getHeight() 对我来说似乎工作正常。

    更新我〜2岁的答案: 由于 API 级别 12 位图有一种直接查询字节大小的方法: http://developer.android.com/reference/android/graphics/Bitmap.html#getByteCount%28%29

    ----示例代码

        @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
        protected int sizeOf(Bitmap data) {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
                return data.getRowBytes() * data.getHeight();
            } else {
                return data.getByteCount();
            }
        }
    

    【讨论】:

    • 试过这样: original = BitmapFactory.decodeStream(getAssets().open("hd.jpg"));大小(原始); ByteArrayOutputStream out = new ByteArrayOutputStream(); original.compress(Bitmap.CompressFormat.WEBP, 50, out);位图解码 = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray())); sizeOf(解码);当我在你的方法中调试时,即使第二个图像被压缩,我也会得到相同的字节数!有没有cmets?
    • @TharakaNirmana 位图始终包含未压缩的图像。压缩仅用于缩小图像以保存到文件。
    • 是时候更新和添加getAllocationByteCount()的kitkat方法了。见developer.android.com/reference/android/graphics/…
    • 我有一个图像,但如果我将它运行到两个不同的图像中,那么在两个设备中我得到不同的图像大小有什么原因吗?例如在 Galaxy S Duos 中它提供 656 KB 而在 MOTO G 设备中它返回 1136 KB
    • @Kalpesh 你的三星有一个 hdpi 屏幕和 moto 一个 xhdpi,所以它在这些模型上加载不同大小的资源。查看谷歌显示密度桶文档。
    【解决方案2】:

    最好只使用支持库:

    int bitmapByteCount=BitmapCompat.getAllocationByteCount(bitmap)
    

    但如果你的 Android 项目至少使用 19 的 minSdk(kitkat,意思是 4.4),你可以只使用 bitmap.getAllocationByteCount()

    【讨论】:

    • 我正在使用 BitmapCompat.getAllocationByteCount(scaledBitmap) 获取分配字节数 3145728。但实际大小是 207kB。我做错了什么?
    • @Sniper 实际尺寸是多少?如果您指的是文件大小,那是有道理的,因为文件是压缩的。如今,没有人会将图像放入文件中而不将其编码为 JPG/PNG/WEBP。这些文件不应该采用与解码图像相同的大小。每个图像的估计字节数为 width*height*bytesPerPixel,其中 bytesPerPixel 通常为 4 或 2。这意味着,如果您有 1000x1000 图像,则可能需要大约 4*1000*1000= 4,000,000 字节,这意味着 ~4MB。
    • 我的 onactivityResult 中有一个位图,我想检查图像的大小并检查大小是否大于 5 mb,如果小于 5 mb,则将其发送到我的服务器提示用户拍摄一张新照片。
    • @Sniper 您将图像文件发送到服务器。这通常是 JPEG、PNG、WEBP ......所有这些通常占用不到 5MB 的存储空间,因为它们是压缩的。它们占用的存储空间也几乎总是比位图占用的内存少。只需在使用 file.length : developer.android.com/reference/java/io/File.html#length() 创建文件后检查文件大小。它与位图无关。位图分辨率可能很大也可能很小。你说的是文件本身。
    • 感谢@androiddeveloper 的澄清。
    【解决方案3】:

    这是使用 KitKat 的 getAllocationByteCount() 的 2014 版本,其编写目的是让编译器理解版本逻辑(因此不需要 @TargetApi

    /**
     * returns the bytesize of the give bitmap
     */
    public static int byteSizeOf(Bitmap bitmap) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            return bitmap.getAllocationByteCount();
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
            return bitmap.getByteCount();
        } else {
            return bitmap.getRowBytes() * bitmap.getHeight();
        }
    }
    

    注意getAllocationByteCount()的结果可以大于getByteCount()的结果,如果一个位图被重新用于解码其他较小尺寸的位图,或者通过手动重新配置。

    【讨论】:

    • 是的,毕加索也使用这个函数来计算位图大小。
    • 我正在使用 BitmapCompat.getAllocationByteCount(scaledBitmap) 获取分配字节数 3145728。但实际大小是 207kB。我做错了什么?
    【解决方案4】:
    public static int sizeOf(Bitmap data) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
            return data.getRowBytes() * data.getHeight();
        } else if (Build.VERSION.SDK_INT<Build.VERSION_CODES.KITKAT){
            return data.getByteCount();
        } else{
            return data.getAllocationByteCount();
        }
    }
    

    与@user289463 答案的唯一区别是在KitKat 及以上版本中使用getAllocationByteCount()

    【讨论】:

    • 我正在使用 BitmapCompat.getAllocationByteCount(scaledBitmap) 获取分配字节数 3145728。但实际大小是 207kB。我做错了什么?
    • @Sniper 207kB 的值是压缩文件存储在磁盘上时的大小。当它被加载到内存中时,它会被解压缩并使用你从函数中获得的字节数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-04
    • 1970-01-01
    • 2021-07-18
    相关资源
    最近更新 更多