Bitmap读取本地高分辨率图片报内存不足的解决方案

Posted AlbertSmith

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bitmap读取本地高分辨率图片报内存不足的解决方案相关的知识,希望对你有一定的参考价值。

 #region getThumImage 生成缩略图
         /// <summary>
         /// 生成缩略图
         /// </summary>
         /// <param name="sourceFile">原始图片文件</param>
         /// <param name="quality">质量压缩比</param>
         /// <param name="multiple">收缩倍数</param>
         /// <param name="outputFile">输出文件名</param>
         /// <param name="DPI">水平分辨率、垂直分辨率</param>
         /// <returns>成功返回true,失败则返回false</returns>
         public bool getThumImage(String sourceFile, long quality, int multiple, String outputFile, int DPI)
         
             try
             
                 long imageQuality = quality;
                 Bitmap sourceImage = new Bitmap(sourceFile);
                 ImageCodecInfo myImageCodecInfo = GetEncoderInfo("image/jpeg");
                 System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
                 EncoderParameters myEncoderParameters = new EncoderParameters(1);
                 EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, imageQuality);
                 myEncoderParameters.Param[0] = myEncoderParameter;
                 float xWidth = sourceImage.Width;
                 float yWidth = sourceImage.Height;
                 Bitmap newImage = new Bitmap((int)(xWidth / multiple), (int)(yWidth / multiple));
                 newImage.SetResolution(DPI, DPI);
                 Graphics g = Graphics.FromImage(newImage);
 
                 g.DrawImage(sourceImage, 0, 0, xWidth / multiple, yWidth / multiple);
                 sourceImage.Dispose();
                 g.Dispose();
                 newImage.Save(outputFile, myImageCodecInfo, myEncoderParameters);
                 return true;
             
             catch
             
                 return false;
             
         
         #endregion getThumImage

改进后代码

 #region getThumImage 生成缩略图
         /// <summary>
         /// 生成缩略图
         /// </summary>
         /// <param name="sourceFile">原始图片文件</param>
         /// <param name="quality">质量压缩比</param>
         /// <param name="multiple">收缩倍数</param>
         /// <param name="outputFile">输出文件名</param>
         /// <param name="DPI">水平分辨率、垂直分辨率</param>
         /// <returns>成功返回true,失败则返回false</returns>
         public bool getThumImage(String sourceFile, long quality, int multiple, String outputFile, int DPI)
         
             try
             
                 long imageQuality = quality;
                 #region 用流方式来读取图片,避开内存不足问题。
                 FileStream fileStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);//打开文件
                 byte[] bytes = new byte[fileStream.Length];//读取文件的byte[]
                 fileStream.Read(bytes, 0, bytes.Length);
                 fileStream.Close();
                 Stream stream = new MemoryStream(bytes);//把byte[]转换成Stream
                 stream.Read(bytes, 0, bytes.Length);
                 stream.Seek(0, SeekOrigin.Begin);//设置当前流的位置为流的开始                
                 Bitmap sourceImage = new Bitmap((Image)new Bitmap(stream));
                 #endregion
                 ImageCodecInfo myImageCodecInfo = GetEncoderInfo("image/jpeg");
                 System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
                 EncoderParameters myEncoderParameters = new EncoderParameters(1);
                 EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, imageQuality);
                 myEncoderParameters.Param[0] = myEncoderParameter;
                 float xWidth = sourceImage.Width;
                 float yWidth = sourceImage.Height;
                 Bitmap newImage = new Bitmap((int)(xWidth / multiple), (int)(yWidth / multiple));
                 newImage.SetResolution(DPI, DPI);
                 Graphics g = Graphics.FromImage(newImage);
 
                 g.DrawImage(sourceImage, 0, 0, xWidth / multiple, yWidth / multiple);
                 sourceImage.Dispose();
                 g.Dispose();
                 newImage.Save(outputFile, myImageCodecInfo, myEncoderParameters);
                 return true;
             
             catch (Exception ex)
             
                 GC.Collect();
                 string message = ex.Message;
                 MessageBox.Show("Error: " + message);
                 return false;
             
             finally
             
                 GC.Collect();
             
         
         #endregion getThumImage

主要改进是在下面这段用流的方式来读取文件,主要可以绕过内存不足的报错

 #region 用流方式来读取图片,避开内存不足问题。
 FileStream fileStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);//打开文件
 byte[] bytes = new byte[fileStream.Length];//读取文件的byte[]
 fileStream.Read(bytes, 0, bytes.Length);
 fileStream.Close();
 Stream stream = new MemoryStream(bytes);//把byte[]转换成Stream
 stream.Read(bytes, 0, bytes.Length);
 stream.Seek(0, SeekOrigin.Begin);//设置当前流的位置为流的开始
 Bitmap sourceImage = new Bitmap((Image)new Bitmap(stream));
 #endregion

 

以上是关于Bitmap读取本地高分辨率图片报内存不足的解决方案的主要内容,如果未能解决你的问题,请参考以下文章

PHP处理高分辨率图片的问题

Android知识要点整理----Bitmap图片处理和展示

Android压缩图片和libjpeg库

Android Bitmap占用内存计算公式

Android内存优化五:Bitmap优化

图片Bitmap在本地的存储与读取 File