最近剛剛接觸CAD二次開發,記錄下開發的過程。查閱很多資料。
C#讀取DWG文件
struct BITMAPFILEHEADER
{
public short bfType;
public int bfSize;
public short bfReserved1;
public short bfReserved2;
public int bfOffBits;
}
public static System.Drawing.Image GetDwgImage(string FileName)
{
if (!(File.Exists(FileName)))
{
throw new FileNotFoundException("文件沒有被找到");
}
FileStream DwgF=null; //文件流
int PosSentinel; //文件描述塊的位置
BinaryReader br=null; //讀取二進制文件
int TypePreview; //縮略圖格式
int PosBMP; //縮略圖位置
int LenBMP; //縮略圖大小
short biBitCount; //縮略圖比特深度
BITMAPFILEHEADER biH; //BMP文件頭,DWG文件中不包含位圖文件頭,要自行加上去
byte[] BMPInfo; //包含在DWG文件中的BMP文件體
MemoryStream BMPF = new MemoryStream(); //保存位圖的內存文件流
BinaryWriter bmpr = new BinaryWriter(BMPF); //寫二進制文件類
System.Drawing.Image myImg = null;
try
{
DwgF = new FileStream(FileName, FileMode.Open, FileAccess.Read); //文件流
br = new BinaryReader(DwgF);
DwgF.Seek(13, SeekOrigin.Begin); //從第十三字節開始讀取
PosSentinel = br.ReadInt32(); //第13到17字節指示縮略圖描述塊的位置
DwgF.Seek(PosSentinel + 30, SeekOrigin.Begin); //將指針移到縮略圖描述塊的第31字節
TypePreview = br.ReadByte(); //第31字節爲縮略圖格式信息,2 爲BMP格式,3爲WMF格式
if (TypePreview == 1)
{
}
else if (TypePreview == 2 || TypePreview == 3)
{
PosBMP = br.ReadInt32(); //DWG文件保存的位圖所在位置
LenBMP = br.ReadInt32(); //位圖的大小
DwgF.Seek(PosBMP + 14, SeekOrigin.Begin); //移動指針到位圖塊
biBitCount = br.ReadInt16(); //讀取比特深度
DwgF.Seek(PosBMP, SeekOrigin.Begin); //從位圖塊開始處讀取全部位圖內容備用
BMPInfo = br.ReadBytes(LenBMP); //不包含文件頭的位圖信息
br.Close();
DwgF.Close();
biH.bfType = 19778; //建立位圖文件頭
if (biBitCount < 9)
{
biH.bfSize = 54 + 4 * (int)(Math.Pow(2, biBitCount)) + LenBMP;
}
else
{
biH.bfSize = 54 + LenBMP;
}
biH.bfReserved1 = 0; //保留字節
biH.bfReserved2 = 0; //保留字節
biH.bfOffBits = 14 + 40 + 1024; //圖像數據偏移
//以下開始寫入位圖文件頭
bmpr.Write(biH.bfType); //文件類型
bmpr.Write(biH.bfSize); //文件大小
bmpr.Write(biH.bfReserved1); //0
bmpr.Write(biH.bfReserved2); //0
bmpr.Write(biH.bfOffBits); //圖像數據偏移
bmpr.Write(BMPInfo); //寫入位圖
BMPF.Seek(0, SeekOrigin.Begin); //指針移到文件開始處
myImg = System.Drawing.Image.FromStream(BMPF); //創建位圖文件對象
bmpr.Close();
BMPF.Close();
}
return myImg;
}
catch (EndOfStreamException)
{
throw new EndOfStreamException("文件不是標準的DWG格式文件,無法預覽!");
}
catch (IOException ex)
{
if (ex.Message == "試圖將文件指針移到文件開頭之前。/r/n")
{
throw new IOException("文件不是標準的DWG格式文件,無法預覽!");
}
else if (ex.Message == "文件“" + FileName + "”正由另一進程使用,因此該進程無法訪問該文件。")
{
//複製文件,繼續預覽
File.Copy(FileName, Application.StartupPath + @"/linshi.dwg", true);
Image image = GetDwgImage(Application.StartupPath + @"/linshi.dwg");
File.Delete(Application.StartupPath + @"/linshi.dwg");
return image;
}
else
{
throw new Exception(ex.Message);
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
if (DwgF != null)
{
DwgF.Close();
}
if (br != null)
{
br.Close();
}
bmpr.Close();
BMPF.Close();
}
}
讀取出來的背景色爲白色,效果比較差,很多顏色顯示不出來,當時認爲顯示DWG文件出錯誤了,問了些高手,(呵呵,別人告訴自己本身取出的就是白色背景,需要自己改變背景色,在此鄙視一下自己)所以繼續用C#操作返回的IMAGE對象,改變背景色
/// <summary>
///顯示DWG文件
/// </summary>
/// <param name="Pwidth">要顯示的寬度</param>
/// <param name="PHeight">要顯示的高度</param>
/// <returns></returns>
public static System.Drawing.Image ShowDWG(int Pwidth,int PHeight,string FilePath)
{
System.Drawing.Image image = GetDwgImage(FilePath);
Bitmap bitmap = new Bitmap(image);
int Height = bitmap.Height;
int Width = bitmap.Width;
Bitmap newbitmap = new Bitmap(Width, Height);
Bitmap oldbitmap = (Bitmap)bitmap;
Color pixel;
for (int x = 1; x < Width; x++)
{
for (int y = 1; y < Height; y++)
{
pixel = oldbitmap.GetPixel(x, y);
int r = pixel.R, g = pixel.G, b = pixel.B;
if (pixel.Name == "ffffffff" || pixel.Name == "ff000000")
{
r = 255 - pixel.R;
g = 255 - pixel.G;
b = 255 - pixel.B;
}
newbitmap.SetPixel(x, y, Color.FromArgb(r, g, b));
}
}
Bitmap bt = new Bitmap(newbitmap, Pwidth, PHeight);
return newbitmap;
}