首页 > 代码库 > C#打开tif文件时内存溢出(System.OutOfMemoryException)解决办法
C#打开tif文件时内存溢出(System.OutOfMemoryException)解决办法
前言
原创性声明 此博文的出处 为http://blog.csdn.net/zhujunxxxxx/article/details/40649887如果进行转载请注明出处。本文作者原创,邮箱zhujunxxxxx@163.com,如有问题请联系作者
我在做一个统计图片长和宽的软件时遇到一个问题,本来是用的
Image img = null; img = Image.FromFile(f.FullName); w = img.Width; h = img.Height;
错误问题
程序竟然在创建Image类型时出现内存溢出(System.OutOfMemoryException)
错误代码: System.Drawing.Image myimg=System.Drawing.Image.FromFile(file.FullName);
当打开的文件不是图像文件时会引发的异常:
或者出现 Bitmap System.ArgumentException: 参数无效问题
这其实不是程序的问题,而是系统中内存的问题,或者图片太大了,大于65535像素了。
我测试 2G内存 BitMap最大 5000*5000,反正这个BitMap大小和机器配置有关。
win7 64位 16G内存最大 23200*23200
由于 GDI+ 解码器的限制,如果使用单维大小大于 65,535 像素的 .png 图像文件构造位图,将引发 System.ArgumentException。
获取TIF图片的长和宽
那么我们既然不能通过方面的代码加载Image对象,那么我们就没法获取图片的长度和宽度,我们有没有什么方法可以获取长度呢?
答案是肯定的,我们可以通过读取TIF的文件格式的内容获取它的长度和宽度
TIF和其它格式都是一样的文件的开头都有一段描述文件的信息
我们的方法就是获取文件中所包含长度的那段内容把它读取出来
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using System.IO; namespace ImageSize { public class ReadTIF:IDisposable { #region 读入TIF图像的变量设置 /// <summary> /// 存储读入的TIF图像的宽度 /// </summary> private int Width; /// <summary> /// 存储读入的TIF图像的高度 /// </summary> private int Heigth; /// <summary> /// 存储读入的TIF图像的Directory Entry Count(DE)的个数 /// </summary> private short NumOfDE; /// <summary> /// 存储下一个Directory Entry的偏移值 /// </summary> private int NextOffsetFID; /// <summary> /// 声明一个结构,存储图像文件头Image File Header的信息 /// </summary> struct IFH { public char[] ByteOrder; public short Version; public int OffsetToFirstFID; } /// <summary> /// 声明一个结构,存储Directory Entry /// </summary> struct DE { public short tag; public short type; public int length; public int valueOffset; } #endregion /* * 实例化一个IFH结构的对象 */ private IFH myIFH; /* * 初始化IFH图像文件头 */ public void DefineIFH() { myIFH.ByteOrder = new char[2]; myIFH.ByteOrder[0] = Convert.ToChar(0); myIFH.ByteOrder[1] = Convert.ToChar(0); myIFH.Version = 0; myIFH.OffsetToFirstFID = 0; } public void TifFile(string file) { FileStream stream = new FileStream(file, FileMode.Open, FileAccess.Read); BinaryReader TIFReader = new BinaryReader(stream); DefineIFH();//调用初始化IFH图像文件头 /* * 读取图像文件头内容 */ myIFH.ByteOrder[0] = TIFReader.ReadChar();//1个字节 myIFH.ByteOrder[1] = TIFReader.ReadChar();//1个字节 myIFH.Version = TIFReader.ReadInt16();//2个字节 myIFH.OffsetToFirstFID = TIFReader.ReadInt32();//4个字节 stream.Seek(0, SeekOrigin.Begin);//将文件的指针移到开始位置 stream.Seek(myIFH.OffsetToFirstFID, SeekOrigin.Begin);//将文件的指针移动到第一个IFD的位置处 NumOfDE = TIFReader.ReadInt16();//获取本IFD结构中目录入口DE的个数,2个字节 /* * 获取各个目录项DE的信息 */ DE[] myDE = new DE[NumOfDE]; for (int i = 0; i < NumOfDE; i++) { myDE[i].tag = TIFReader.ReadInt16();//2个字节 myDE[i].type = TIFReader.ReadInt16();//2个字节 myDE[i].length = TIFReader.ReadInt32();//4个字节 myDE[i].valueOffset = TIFReader.ReadInt32();//4个字节 } /* * 读取下一个Directory Entry的偏移值 */ NextOffsetFID = TIFReader.ReadInt32(); /* * 读取图像的宽度、高度 */ for (int i = 0; i < NumOfDE; i++) { if (myDE[i].tag == 256)//图像的宽 { Width = myDE[i].valueOffset; } if (myDE[i].tag == 257)//图像的高 { Heigth = myDE[i].valueOffset; } } TIFReader.Close(); stream.Close(); } //返回宽度 public int GetW() { return Width; } //返回高度 public int GetH() { return Heigth; } public void Dispose() { } } }
使用方法
ReadTIF rt = new ReadTIF(); rt.TifFile(f.FullName); w = rt.GetW(); h = rt.GetH();
C#打开tif文件时内存溢出(System.OutOfMemoryException)解决办法
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。