21

当我在将图像保存到 SD 卡之前搜索如何找到图像的大小时,我发现了这个:

bitmap.getByteCount();

但是该方法是在 API 12 中添加的,我正在使用 API 10。所以我再次发现了这一点:

getByteCount() 只是一种方便的方法,它完全按照您在 else 块中放置的操作。换句话说,如果你简单地重写 getSizeInBytes 以始终返回“bitmap.getRowBytes() * bitmap.getHeight()”

这里:

Bitmap getByteCount() 到底在哪里?

所以,通过计算这个bitmap.getRowBytes() * bitmap.getHeight()我得到了价值120000 (117 KB)

其中 SD 卡上的图像大小为1.6 KB.

我错过了什么?还是做错了?

谢谢你

4

7 回答 7

33

你做对了!

确定这些值是否有效的一种快速方法是像这样记录它:

int numBytesByRow = bitmap.getRowBytes() * bitmap.getHeight();
int numBytesByCount = bitmap.getByteCount();
Log.v( TAG, "numBytesByRow=" + numBytesByRow ); 
Log.v( TAG, "numBytesByCount=" + numBytesByCount ); 

这给出了结果:

03-29 17:31:10.493: V/ImageCache(19704): numBytesByRow=270000
03-29 17:31:10.493: V/ImageCache(19704): numBytesByCount=270000

所以两者都在计算相同的数字,我怀疑这是位图的内存大小。 这与磁盘上的JPGPNG不同,因为它是完全未压缩的。


有关更多信息,我们可以查看 AOSP 和示例项目中的源代码。这是Android 开发者文档Caching Bitmaps 中示例项目BitmapFun中使用的文件

AOSP ImageCache.java

/**
 * Get the size in bytes of a bitmap in a BitmapDrawable.
 * @param value
 * @return size in bytes
 */
@TargetApi(12)
public static int getBitmapSize(BitmapDrawable value) {
    Bitmap bitmap = value.getBitmap();

    if (APIUtil.hasHoneycombMR1()) {
        return bitmap.getByteCount();
    }
    // Pre HC-MR1
    return bitmap.getRowBytes() * bitmap.getHeight();
}

如您所见,这是他们使用的相同技术

bitmap.getRowBytes() * bitmap.getHeight();

参考:

于 2013-03-29T21:53:13.957 回答
6

现在我正在使用这个:

ByteArrayOutputStream bao = new ByteArrayOutputStream();
my_bitmap.compress(Bitmap.CompressFormat.PNG, 100, bao);
byte[] ba = bao.toByteArray();
int size = ba.length;

获得总字节数作为大小。因为我在这里得到的值完全匹配 SD 卡上图像的大小(以字节为单位)。

于 2012-09-26T10:41:20.763 回答
2

什么都没有!您的代码片段显示了来自 Android-Source 的确切实现:

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.1_r1/android/graphics/Bitmap.java#Bitmap.getByteCount%28%29

我认为大小的差异是图像压缩(jpg等)的结果。

于 2012-09-25T14:34:39.403 回答
2

这是另一种方法:

public static int getBitmapByteCount(Bitmap bitmap) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1)
        return bitmap.getRowBytes() * bitmap.getHeight();
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
        return bitmap.getByteCount();
    return bitmap.getAllocationByteCount();
}

来自 IDE 的声明getAllocationByteCount()

如果重新使用位图来解码较小尺寸的其他位图,或者通过手动重新配置,这可能大于 getByteCount() 的结果。请参阅 reconfigure(int, int, Bitmap.Config)、setWidth(int)、setHeight(int)、setConfig(Bitmap.Config) 和 BitmapFactory.Options.inBitmap。如果不以这种方式修改位图,则该值将与 getByteCount() 返回的值相同。

于 2015-09-15T06:54:44.603 回答
1

你可以试试这个代码吗

int pixels = bitmap.getHeight() * bitmap.getWidth();
int bytesPerPixel = 0;
switch(bitmap.getConfig()) {
case ARGB_8888:
bytesPerPixel = 4;
break;
case RGB_565:
bytesPerPixel = 2; 
 break;
case ARGB_4444:
bytesPerPixel = 2; 
 break;
case ALPHA_8 :
 bytesPerPixel = 1; 
 break;
}
 int byteCount = pixels / bytesPerPixel;
于 2012-09-26T06:16:45.420 回答
0

sd 卡上的图像有不同的大小,因为它是压缩的。在设备上,它将取决于宽度/高度

于 2013-02-28T18:43:33.087 回答
0

你为什么不尝试在1024之间划分它?获取 KB 而不是 Bytes。

于 2013-08-13T15:46:52.067 回答