明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 38481|回复: 61

[图形系统] 转发 完美解决VB.NET窗体中预览DWG图形(附完整代码)

  [复制链接]
发表于 2006-5-20 00:32:00 | 显示全部楼层 |阅读模式
本帖最后由 作者 于 2006-5-26 13:45:16 编辑

转发,试过了效果一级棒。大家快下下去研究研究。

终于解决了一个困扰许久的关于DWG文件的难题,还没完善,欢迎批评,高分相送
为了找一个合适的预览DWG文件的控件,不知道搜索了多少次,都没有满意的结果,R2002自带的控件无法预览R2004格式的文件,最近花了几天时间,终于解决了这个困扰好久了难题,直接从DWG文件中提取位图放在PictureBox中预览。唯一留下的遗憾是当文件被其它进程打开时,会导致程序返回速度太慢,不知道各位是否有好的方法解决这一问题(或是有什么办法可以强行打开正被其它进程打开的文件)。现将代码及注释贴出来,要知道我是刚学VB.Net的,而且纯属业余爱好。

    Private Structure BITMAPFILEHEADER
        Dim bfType As Short
        Dim bfSize As Integer
        Dim bfReserved1 As Short
        Dim bfReserved2 As Short
        Dim bfOffBits As Integer
    End Structure

Public Function GetDwgImage(ByVal FileName As String) As Image
        If Not File.Exists(FileName) Then Exit Function
        Dim DwgF As FileStream    '文件流
        Dim PosSentinel As Integer  '文件描述块的位置
        Dim br As BinaryReader  '读取二进制文件
        Dim TypePreview As Integer '缩略图格式
        Dim PosBMP As Integer '缩略图位置
        Dim LenBMP As Integer '缩略图大小
        Dim biBitCount As Short '缩略图比特深度
        Dim biH As BITMAPFILEHEADER 'BMP文件头,DWG文件中不包含位图文件头,要自行加上去
        Dim BMPInfo() As Byte  '包含在DWG文件中的BMP文件体
        Dim BMPF As New MemoryStream  '保存位图的内存文件流
        Dim bmpr As New BinaryWriter(BMPF) '写二进制文件类
        Dim myImg As Image
        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格式
            Select Case TypePreview
                Case 1

                Case 2, 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()
                    With biH  '建立位图文件头
                        .bfType = &H4D42
                        If biBitCount < 9 Then .bfSize = 54 + 4 * (2 ^ biBitCount) + LenBMP Else .bfSize = 54 + LenBMP
                        .bfReserved1 = 0 '保留字节
                        .bfReserved2 = 0 '保留字节
                        .bfOffBits = 14 + &H28 + 1024 '图像数据偏移
                    End With
                    '以下开始写入位图文件头
                    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 = Image.FromStream(BMPF) '创建位图文件对象
                    Return myImg
                    bmpr.Close()
                    BMPF.Close()
            End Select
        Catch ex As Exception
            Return Nothing
        End Try

      
    End Function

这个程序涉及到了DWG文件的内部格式。编出来的人很了不起。

评分

参与人数 1威望 +1 金钱 +10 贡献 +5 激情 +5 收起 理由
mccad + 1 + 10 + 5 + 5 【精华】好文章

查看全部评分

 楼主| 发表于 2006-5-26 13:58:00 | 显示全部楼层

自已再顶一下,此帖完美解决了在窗体中预览DWG文件有方案。不仅适用于VB也适用于别的`编程语言。从网上淘下这个帖子后我如获至宝。以最快的速度拿出不与大家共享。也幸亏这样。淘下来的第二天我的电脑硬盘坏了。只有网上保存了这一份。原来在网上的贴子我再也找不出不了。呵。。。。。

好人有好报!

回复 支持 1 反对 0

使用道具 举报

发表于 2019-9-5 11:17:34 | 显示全部楼层
谢谢楼主的资源,翻译成C#的:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6. using System.Drawing;

  7. namespace Changfeng.AcadNetLib
  8. {
  9.     public class AcadUtility
  10.     {
  11.         public struct BITMAPFILEHEADER
  12.         {
  13.             public short bfType;
  14.             public int bfSize;
  15.             public short bfReserved1;
  16.             public short bfReserved2;
  17.             public int bfOffBits;
  18.         }

  19.         public static Image GetDwgImage(string FileName)
  20.         {
  21.             if (!File.Exists(FileName)) return default(Image);

  22.             FileStream DwgF =null;
  23.             BinaryReader br =null;

  24.             //文件描述块的位置
  25.             int PosSentinel = 0;

  26.             //缩略图格式
  27.             int TypePreview = 0;

  28.             //缩略图位置
  29.             int PosBMP = 0;

  30.             //缩略图大小
  31.             int LenBMP = 0;

  32.             //缩略图比特深度
  33.             short biBitCount = 0;

  34.             //BMP文件头,DWG文件中不包含位图文件头,要自行加上去
  35.             BITMAPFILEHEADER biH = new BITMAPFILEHEADER();
  36.             byte[] BMPInfo = null; //包含在DWG文件中的BMP文件体
  37.             MemoryStream BMPF = new MemoryStream(); //保存位图的内存文件流
  38.             BinaryWriter bmpr = new BinaryWriter(BMPF); //写二进制文件类
  39.             Image myImg = default(Image);
  40.             try
  41.             {
  42.                 DwgF = new FileStream(FileName, FileMode.Open, FileAccess.Read); //文件流
  43.                 br = new BinaryReader(DwgF);
  44.                 DwgF.Seek(13, SeekOrigin.Begin); //从第十三字节开始读取

  45.                 PosSentinel = br.ReadInt32(); //第13到17字节指示缩略图描述块的位置

  46.                 DwgF.Seek(PosSentinel + 30, SeekOrigin.Begin); //将指针移到缩略图描述块的第31字节

  47.                 TypePreview = br.ReadByte(); //第31字节为缩略图格式信息,2 为BMP格式,3为WMF格式
  48.                 switch (TypePreview)
  49.                 {
  50.                     case 1:
  51.                         break;

  52.                     case 2:
  53.                     case 3:
  54.                         PosBMP = br.ReadInt32(); //DWG文件保存的位图所在位置
  55.                         LenBMP = br.ReadInt32(); //位图的大小
  56.                         DwgF.Seek(PosBMP + 14, SeekOrigin.Begin); //移动指针到位图块
  57.                         biBitCount = br.ReadInt16(); //读取比特深度
  58.                         DwgF.Seek(PosBMP, SeekOrigin.Begin); //从位图块开始处读取全部位图内容备用
  59.                         BMPInfo = br.ReadBytes(LenBMP); //不包含文件头的位图信息
  60.                         br.Close();
  61.                         DwgF.Close();
  62.                         biH.bfType = (short)(0x4D42);
  63.                         if (biBitCount < 9)
  64.                         {
  65.                             biH.bfSize = System.Convert.ToInt32(54 + 4 * (Math.Pow(2, biBitCount)) + LenBMP);
  66.                         }
  67.                         else
  68.                         {
  69.                             biH.bfSize = 54 + LenBMP;
  70.                         }
  71.                         biH.bfReserved1 = (short)0; //保留字节
  72.                         biH.bfReserved2 = (short)0; //保留字节
  73.                         biH.bfOffBits = 14 + 0x28 + 1024; //图像数据偏移
  74.                         //以下开始写入位图文件头
  75.                         bmpr.Write(biH.bfType); //文件类型
  76.                         bmpr.Write(biH.bfSize); //文件大小
  77.                         bmpr.Write(biH.bfReserved1); //0
  78.                         bmpr.Write(biH.bfReserved2); //0
  79.                         bmpr.Write(biH.bfOffBits); //图像数据偏移
  80.                         bmpr.Write(BMPInfo); //写入位图


  81.                         BMPF.Seek(0, SeekOrigin.Begin); //指针移到文件开始处

  82.                         myImg = (Image)(Image.FromStream(BMPF)); //创建位图文件对象
  83.                         return myImg;
  84.                     //        bmpr.Close();
  85.                     //        BMPF.Close();

  86.                     default:
  87.                         break;
  88.                 }
  89.             }
  90.             catch (Exception)
  91.             {
  92.                 return null;
  93.             }


  94.             return null;

  95.         }



  96.     }
  97. }

发表于 2023-12-28 02:08:59 | 显示全部楼层
Leo1980 发表于 2019-9-5 11:17
谢谢楼主的资源,翻译成C#的:

好东西  研究研究
发表于 2006-5-22 19:31:00 | 显示全部楼层
楼主真牛,这么难的问题也能搞定。
 楼主| 发表于 2006-5-25 12:42:00 | 显示全部楼层
我上机试用了,的确好用。这为我们编制VB。NET程序扫清了一大障碍。大家可以试试。
发表于 2006-5-27 19:18:00 | 显示全部楼层

楼主能找到这篇文章,也了不起,能拿出来分享,更了不起。

顺便问是在哪个网站有这种宝贝文章的?

 楼主| 发表于 2006-5-28 22:55:00 | 显示全部楼层
我也想再去一下那个网站,可惜再也找不到了。我用GOOGLE搜的。
发表于 2006-6-2 15:48:00 | 显示全部楼层
我找这样的文章找了好久了,首先谢谢楼主的与大家分享~~可是上面的代码怎么用呢?我是新手,请大家帮忙~
发表于 2006-6-4 20:31:00 | 显示全部楼层

谢谢楼主啊!

 

发表于 2006-6-7 12:45:00 | 显示全部楼层
谢谢推荐!
 楼主| 发表于 2006-6-30 23:36:00 | 显示全部楼层
再来跟一个。好帖不能沉下去。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-25 04:38 , Processed in 0.193992 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表