【问题标题】:RAM saving when loading many Bitmap objects加载许多位图对象时节省 RAM
【发布时间】:2010-07-28 09:30:59
【问题描述】:

从 bmp 或 png(或其他格式)将相同的图像加载到位图中有什么区别吗?原始图像格式是否会影响 RAM 中的Bitmap 对象大小?

有没有办法归档 Bitmap 对象以减少它们对 RAM 资源的消耗?

【问题讨论】:

    标签: c# image bitmap


    【解决方案1】:

    大小仅受文件大小的影响,与格式无关(但显然,某些格式会导致文件比其他格式更小)。

    如果您需要将位图保存为位图,一种存档位图的方法就是压缩它们。或者,将它们转换为另一种包含压缩的图像格式(理想情况下,无损压缩而不是 jpg)。 抱歉,这是在解释归档文件,而不是节省实时内存使用量。

    要停止使用内存的位图对象,您需要释放内存中的项目并在您想再次使用它时重新加载它。或者,虽然我没有这方面的经验,但请查看新的 .NET 4 内存映射文件。

    【讨论】:

    • 那么位图对象大小受原图格式影响?
    • 是的,该文件包含描述图像的字节(加上标题信息等)。 Bitmap 类只是加载这些字节。它还可以处理其他文件格式,因此加载较小的 PNG,比如 200Kb,将导致 200Kb Bitmap(为了参数,不一定是正确的值)。我想说的是Bitmap 类在加载时不会将您的 PNG 转换为位图。
    • 酷。您知道如何在运行时更改格式吗?无需将图像保存到磁盘。确切的任务 - 制作屏幕截图时,我收到 bmp 图像。我需要将其转换为 PNG 以节省 RAM。
    • 在我的脑海中,不,我不记得了 - 问另一个问题:-)
    • 我尝试将原始文件保存到内存流,然后 - 从 ms 恢复新的位图。不幸的是,它并没有带来任何内存节省......
    【解决方案2】:

    有两种方法可以将数据保存在内存中

    1. 在内存中使用 GZipStream 序列化和压缩对象
    2. 将图像保存到临时目录,并在需要时将它们读取到内存中。

    图像对象大小不受原始图像格式的影响。但是保存对象的流的大小 - 确实。

    这是从对象获取流的方法:

     public static Stream GetPNGBitmapStream(Image initial)
        {
            return GetBitmapStream(initial, "image/PNG");
        }
    
        public static Stream GetJPGBitmapStream(Image initial)
        {
            return GetBitmapStream(initial, "image/jpeg");
        }
    
        private static Stream GetBitmapStream(Image initial, string mimeType)
        {
            MemoryStream ms = new MemoryStream();
    
            var qualityEncoder = Encoder.Quality;
            var quality = (long)90;
            var ratio = new EncoderParameter(qualityEncoder, quality);
            var codecParams = new EncoderParameters(1);
            codecParams.Param[0] = ratio;
            ImageCodecInfo[] infos = ImageCodecInfo.GetImageEncoders();
    
            ImageCodecInfo jpegCodecInfo = null;
            for (int i = 0; i < infos.Length; i++)
            {
                if (string.Compare(infos[i].MimeType, mimeType,true) == 0)
                {
                    jpegCodecInfo = infos[i];
                    break;
                }
            }
    
            if (jpegCodecInfo != null)
            {
                initial.Save(ms, jpegCodecInfo, codecParams); 
                MemoryStream ms2 = new MemoryStream(ms.ToArray());
                ms.Close();
                ms.Dispose();
                return ms2;
            }
    
            return null;
        }
    

    【讨论】:

      猜你喜欢
      • 2017-04-18
      • 1970-01-01
      • 2022-01-11
      • 1970-01-01
      • 2016-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多