Android 在C#中使用BitmapFactory.DecodeFile时内存占用更大(对于微小的图像,内存更大)

Android 在C#中使用BitmapFactory.DecodeFile时内存占用更大(对于微小的图像,内存更大),android,image,memory,bitmap,xamarin.android,Android,Image,Memory,Bitmap,Xamarin.android,我只是想看看是否有人注意到,当将图像加载到内存中时,完全相同的C代码使用更多的内存来保存图像(大约是Java中的1.5倍) 此Java代码导致总内存大小105.5 MB: Bitmap[] bitmaps = new Bitmap[100]; for (int i = 0; i < 100; i++) { String root = Environment.getExternalStorageDirectory().getAbsolutePath(); String im

我只是想看看是否有人注意到,当将图像加载到内存中时,完全相同的C代码使用更多的内存来保存图像(大约是Java中的1.5倍)

此Java代码导致总内存大小105.5 MB

Bitmap[] bitmaps = new Bitmap[100];

for (int i = 0; i < 100; i++)
{
    String root = Environment.getExternalStorageDirectory().getAbsolutePath();
    String imagePath = "/evolution/threesixty/216/Edaphosaurus_001.jpg";

    bitmaps[i] = BitmapFactory.decodeFile(root + imagePath);
}
Bitmap[] bitmaps = new Bitmap[100];

for (int i = 0; i < 100; i++)
{
    string root = Environment.ExternalStorageDirectory.AbsolutePath;
    string imagePath = "/evolution/threesixty/216/Edaphosaurus_001.jpg";

    bitmaps[i] = BitmapFactory.DecodeFile(root + imagePath);
}  
Bitmap[]位图=新位图[100];
对于(int i=0;i<100;i++)
{
字符串root=Environment.getExternalStorageDirectory().getAbsolutePath();
字符串imagePath=“/evolution/threesixty/216/Edaphosaurus_001.jpg”;
位图[i]=位图工厂.decodeFile(root+imagePath);
}
此C#代码导致148.1 MB

Bitmap[] bitmaps = new Bitmap[100];

for (int i = 0; i < 100; i++)
{
    String root = Environment.getExternalStorageDirectory().getAbsolutePath();
    String imagePath = "/evolution/threesixty/216/Edaphosaurus_001.jpg";

    bitmaps[i] = BitmapFactory.decodeFile(root + imagePath);
}
Bitmap[] bitmaps = new Bitmap[100];

for (int i = 0; i < 100; i++)
{
    string root = Environment.ExternalStorageDirectory.AbsolutePath;
    string imagePath = "/evolution/threesixty/216/Edaphosaurus_001.jpg";

    bitmaps[i] = BitmapFactory.DecodeFile(root + imagePath);
}  
Bitmap[]位图=新位图[100];
对于(int i=0;i<100;i++)
{
字符串root=Environment.ExternalStorageDirectory.AbsolutePath;
字符串imagePath=“/evolution/threesixty/216/Edaphosaurus_001.jpg”;
位图[i]=位图工厂.DecodeFile(root+imagePath);
}  
有人知道为什么吗?我知道.NET包装器可能会使用多一点来保存额外的绑定数据或东西,但肯定不会那么多

另外,作为一个附带问题:
每个映像在磁盘上只有60KB,为什么内存中的版本1MB?我知道我的装载方法不进行任何取样/密度检查,但这不是目的。基于Mono for Android邮件列表的回复,肯定会加载:

正在加载的图像是jpg压缩的。位图是一个 未压缩格式。谷歌搜索显示了一个典型的JPEG 压缩比为10:1到20:1,不会丢失明显的图像 质量。60KB->1MB在该范围内

还有一个:

将位图加载到内存会对其进行解压缩,具体取决于 加载位图配置时,它将占用比其本身更多的内存 磁盘上的压缩大小

在看了这些关于压缩的信息之后(我不知道我脑子里在想什么,因为我意识到压缩会使内存中的图像变小,以便保存和加载,然后将其解压缩到内存中),我现在明白了事情是如何工作的;) 当保存为位图时,图像被解压缩到几乎2MB,如果我查看Irfanview中的图像属性


因此,我现在要做的是将样本大小设置为
2
,并使用
Bitmap.Config.Rgb565
。这将图像的总大小减少到30 MB左右,这是更好的方式。虽然质量不太好,但我可以在用户不知道的情况下加载更高分辨率的图像。

根据Mono for Android邮件列表的回复:

正在加载的图像是jpg压缩的。位图是一个 未压缩格式。谷歌搜索显示了一个典型的JPEG 压缩比为10:1到20:1,不会丢失明显的图像 质量。60KB->1MB在该范围内

还有一个:

将位图加载到内存会对其进行解压缩,具体取决于 加载位图配置时,它将占用比其本身更多的内存 磁盘上的压缩大小

在看了这些关于压缩的信息之后(我不知道我脑子里在想什么,因为我意识到压缩会使内存中的图像变小,以便保存和加载,然后将其解压缩到内存中),我现在明白了事情是如何工作的;) 当保存为位图时,图像被解压缩到几乎2MB,如果我查看Irfanview中的图像属性


因此,我现在要做的是将样本大小设置为
2
,并使用
Bitmap.Config.Rgb565
。这将图像的总大小减少到30 MB左右,这是更好的方式。虽然质量不太好,但我可以在用户不知道的情况下,在需要时加载更高分辨率的图像。

您的148.1 MB的100幅图像的数字正是我所期望的数字。994 x 748给出743512像素;假设您使用的是每像素2字节的格式(对于图像而言,这是非常低的质量,FWIW-RGB565格式在几十年前就应该在国际上被禁止),那么每幅图像的容量为1.481 MB。这当然比磁盘上的映像大小大得多,因为映像文件是压缩的


我不知道为什么Java版本只会消耗105.5MB;据我所知,没有一种位图格式每像素使用1.333字节。很可能您读取的内存使用错误,或者Java运行时正在将一些图像缓存到磁盘,而不是将它们保留在内存中。

您的100个图像的148.1 MB的数字正是我所期望的数字。994 x 748给出743512像素;假设您使用的是每像素2字节的格式(对于图像而言,这是非常低的质量,FWIW-RGB565格式在几十年前就应该在国际上被禁止),那么每幅图像的容量为1.481 MB。这当然比磁盘上的映像大小大得多,因为映像文件是压缩的

我不知道为什么Java版本只会消耗105.5MB;据我所知,没有一种位图格式每像素使用1.333字节。很可能您读取的内存使用错误,或者Java运行时正在将一些图像缓存到磁盘,而不是将它们保存在内存中。

Visit:对于邮件列表线程。Visit:对于邮件列表线程。