解码后的位图字节大小?

Posted

技术标签:

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

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

感谢您的任何解决方案!

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

【问题讨论】:

【参考方案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 的值是压缩文件存储在磁盘上时的大小。当它被加载到内存中时,它会被解压缩并使用你从函数中获得的字节数。

以上是关于解码后的位图字节大小?的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin 安卓。将字节数组转换为位图。 Skia 解码器返回 false

Android位图解码A

有时位图解码返回 SkImageDecoder::Factory 返回 null 并显示损坏的图像

SDWebImage 中的图片解码

HarmonyOS之深入解析图像的位图操作和属性解码

在 onPictureTaken 之后旋转 JPEG 的字节数组