找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 944|回复: 4

[求助] 读取DWG文件的缩略图问题

[复制链接]
发表于 2018-4-4 08:56:46 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
我有两种读DWG文件缩略图的方式
DWG文件2013版本缩略图格式从以前的BMP格式改成了PNG格式
一种只能读取2013以下的BMP缩略图版本
一种能读2013格式的PNG版本,但是读取多个DWG文件的时候比较慢。
而且这两种方式都只能读保存了缩略图的DWG文件,没有保存缩略图的读不到

像有的程序,比如海龙设计软件的图库之类的,读取速度比较快,而且没有保存缩略图的文件也可以读取到预览图,那个似乎是C++写的。

C#要怎么比较完美的读取到预览图
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
 楼主| 发表于 2018-4-4 08:57:48 | 显示全部楼层
本帖最后由 8142556 于 2018-4-4 09:04 编辑

1111111111
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-4-4 09:00:25 | 显示全部楼层
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Drawing.Imaging;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Runtime.InteropServices;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. using System.Windows;
  11. using System.Windows.Media.Imaging;
  12. //调用函数
  13. //int pic_size = 256;
  14. //Bitmap bm = WindowsThumbnailProvider.GetThumbnail(@"G:\李飞\2017方案图\御龙山\S1-1104\Drawing1.dwg", pic_size, pic_size, ThumbnailOptions.None);
  15. //System.Windows.Media.Imaging.BitmapSource bi =
  16. //                 System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bm.GetHbitmap(),
  17. //                    IntPtr.Zero,
  18. //                    Int32Rect.Empty,
  19. //                    BitmapSizeOptions.FromEmptyOptions());
  20. //image.Source = bi;
  21. namespace WFCAD
  22. {
  23.     [Flags]
  24.     public enum ThumbnailOptions
  25.     {
  26.         None = 0x00,
  27.         BiggerSizeOk = 0x01,
  28.         InMemoryOnly = 0x02,
  29.         IconOnly = 0x04,
  30.         ThumbnailOnly = 0x08,
  31.         InCacheOnly = 0x10,
  32.     }
  33.    

  34.     public class WindowsThumbnailProvider
  35.     {
  36.         private const string IShellItem2Guid = "7E9FB0D3-919F-4307-AB2E-9B1860310C93";

  37.         [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  38.         internal static extern int SHCreateItemFromParsingName(
  39.             [MarshalAs(UnmanagedType.LPWStr)] string path,
  40.             // The following parameter is not used - binding context.  
  41.             IntPtr pbc,
  42.             ref Guid riid,
  43.             [MarshalAs(UnmanagedType.Interface)] out IShellItem shellItem);

  44.         [DllImport("gdi32.dll")]
  45.         [return: MarshalAs(UnmanagedType.Bool)]
  46.         internal static extern bool DeleteObject(IntPtr hObject);

  47.         [ComImport]
  48.         [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  49.         [Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")]
  50.         internal interface IShellItem
  51.         {
  52.             void BindToHandler(IntPtr pbc,
  53.                 [MarshalAs(UnmanagedType.LPStruct)]Guid bhid,
  54.                 [MarshalAs(UnmanagedType.LPStruct)]Guid riid,
  55.                 out IntPtr ppv);

  56.             void GetParent(out IShellItem ppsi);
  57.             void GetDisplayName(SIGDN sigdnName, out IntPtr ppszName);
  58.             void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs);
  59.             void Compare(IShellItem psi, uint hint, out int piOrder);
  60.         };

  61.         internal enum SIGDN : uint
  62.         {
  63.             NORMALDISPLAY = 0,
  64.             PARENTRELATIVEPARSING = 0x80018001,
  65.             PARENTRELATIVEFORADDRESSBAR = 0x8001c001,
  66.             DESKTOPABSOLUTEPARSING = 0x80028000,
  67.             PARENTRELATIVEEDITING = 0x80031001,
  68.             DESKTOPABSOLUTEEDITING = 0x8004c000,
  69.             FILESYSPATH = 0x80058000,
  70.             URL = 0x80068000
  71.         }

  72.         internal enum HResult
  73.         {
  74.             Ok = 0x0000,
  75.             False = 0x0001,
  76.             InvalidArguments = unchecked((int)0x80070057),
  77.             OutOfMemory = unchecked((int)0x8007000E),
  78.             NoInterface = unchecked((int)0x80004002),
  79.             Fail = unchecked((int)0x80004005),
  80.             ElementNotFound = unchecked((int)0x80070490),
  81.             TypeElementNotFound = unchecked((int)0x8002802B),
  82.             NoObject = unchecked((int)0x800401E5),
  83.             Win32ErrorCanceled = 1223,
  84.             Canceled = unchecked((int)0x800704C7),
  85.             ResourceInUse = unchecked((int)0x800700AA),
  86.             AccessDenied = unchecked((int)0x80030005)
  87.         }

  88.         [ComImportAttribute()]
  89.         [GuidAttribute("bcc18b79-ba16-442f-80c4-8a59c30c463b")]
  90.         [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
  91.         internal interface IShellItemImageFactory
  92.         {
  93.             [PreserveSig]
  94.             HResult GetImage(
  95.             [In, MarshalAs(UnmanagedType.Struct)] NativeSize size,
  96.             [In] ThumbnailOptions flags,
  97.             [Out] out IntPtr phbm);
  98.         }

  99.         [StructLayout(LayoutKind.Sequential)]
  100.         internal struct NativeSize
  101.         {
  102.             private int width;
  103.             private int height;

  104.             public int Width { set { width = value; } }
  105.             public int Height { set { height = value; } }
  106.         };

  107.         [StructLayout(LayoutKind.Sequential)]
  108.         public struct RGBQUAD
  109.         {
  110.             public byte rgbBlue;
  111.             public byte rgbGreen;
  112.             public byte rgbRed;
  113.             public byte rgbReserved;
  114.         }

  115.         public static BitmapSource WfGetSource(string path)
  116.         {
  117.             int pic_size = 256;
  118.             Bitmap bm = WindowsThumbnailProvider.GetThumbnail(path, pic_size, pic_size, ThumbnailOptions.None);
  119.             System.Windows.Media.Imaging.BitmapSource bi =
  120.                  System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bm.GetHbitmap(),
  121.                     IntPtr.Zero,
  122.                     Int32Rect.Empty,
  123.                     BitmapSizeOptions.FromEmptyOptions());
  124.             return bi;
  125.         }

  126.         /// <summary>
  127.         /// 获得缩略图
  128.         /// </summary>
  129.         /// <param name="fileName">文件名</param>
  130.         /// <param name="width">位图宽</param>
  131.         /// <param name="height">位图高</param>
  132.         /// <param name="options">选项</param>
  133.         /// <returns></returns>
  134.         public static Bitmap GetThumbnail(string fileName, int width, int height, ThumbnailOptions options)
  135.         {
  136.             IntPtr hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options);

  137.             try
  138.             {
  139.                 // return a System.Drawing.Bitmap from the hBitmap  
  140.                 return GetBitmapFromHBitmap(hBitmap);
  141.             }
  142.             finally
  143.             {
  144.                 // delete HBitmap to avoid memory leaks  
  145.                 DeleteObject(hBitmap);
  146.             }
  147.         }

  148.         public static Bitmap GetBitmapFromHBitmap(IntPtr nativeHBitmap)
  149.         {
  150.             Bitmap bmp = Bitmap.FromHbitmap(nativeHBitmap);

  151.             if (Bitmap.GetPixelFormatSize(bmp.PixelFormat) < 32)
  152.                 return bmp;

  153.             return CreateAlphaBitmap(bmp, PixelFormat.Format32bppArgb);
  154.         }

  155.         public static Bitmap CreateAlphaBitmap(Bitmap srcBitmap, PixelFormat targetPixelFormat)
  156.         {
  157.             Bitmap result = new Bitmap(srcBitmap.Width, srcBitmap.Height, targetPixelFormat);

  158.             Rectangle bmpBounds = new Rectangle(0, 0, srcBitmap.Width, srcBitmap.Height);

  159.             BitmapData srcData = srcBitmap.LockBits(bmpBounds, ImageLockMode.ReadOnly, srcBitmap.PixelFormat);

  160.             bool isAlplaBitmap = false;

  161.             try
  162.             {
  163.                 for (int y = 0; y <= srcData.Height - 1; y++)
  164.                 {
  165.                     for (int x = 0; x <= srcData.Width - 1; x++)
  166.                     {
  167.                         Color pixelColor = Color.FromArgb(
  168.                             Marshal.ReadInt32(srcData.Scan0, (srcData.Stride * y) + (4 * x)));

  169.                         if (pixelColor.A > 0 & pixelColor.A < 255)
  170.                         {
  171.                             isAlplaBitmap = true;
  172.                         }

  173.                         result.SetPixel(x, y, pixelColor);
  174.                     }
  175.                 }
  176.             }
  177.             finally
  178.             {
  179.                 srcBitmap.UnlockBits(srcData);
  180.             }

  181.             if (isAlplaBitmap)
  182.             {
  183.                 return result;
  184.             }
  185.             else
  186.             {
  187.                 return srcBitmap;
  188.             }
  189.         }

  190.         private static IntPtr GetHBitmap(string fileName, int width, int height, ThumbnailOptions options)
  191.         {
  192.             IShellItem nativeShellItem;
  193.             Guid shellItem2Guid = new Guid(IShellItem2Guid);
  194.             int retCode = SHCreateItemFromParsingName(fileName, IntPtr.Zero, ref shellItem2Guid, out nativeShellItem);

  195.             if (retCode != 0)
  196.                 throw Marshal.GetExceptionForHR(retCode);

  197.             NativeSize nativeSize = new NativeSize();
  198.             nativeSize.Width = width;
  199.             nativeSize.Height = height;

  200.             IntPtr hBitmap;
  201.             HResult hr = ((IShellItemImageFactory)nativeShellItem).GetImage(nativeSize, options, out hBitmap);

  202.             Marshal.ReleaseComObject(nativeShellItem);

  203.             if (hr == HResult.Ok) return hBitmap;

  204.             throw Marshal.GetExceptionForHR((int)hr);
  205.         }
  206.     }
  207. }
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-4-4 09:04:36 | 显示全部楼层
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Drawing;
  8. using System.Windows;
  9. using System.Windows.Media.Imaging;

  10. namespace WFCAD
  11. {
  12.     class DWGview
  13.     {
  14.         struct BITMAPFILEHEADER
  15.         {
  16.             public short bfType;
  17.             public int bfSize;
  18.             public short bfReserved1;
  19.             public short bfReserved2;
  20.             public int bfOffBits;
  21.         }
  22.         /// <summary>
  23.         /// 这是提取DWG缩略图的方法,返回Image
  24.         /// </summary>
  25.         /// <param name="FileName"></param>
  26.         /// <returns></returns>
  27.         private static Image GetDwgImage(string FileName)
  28.         {
  29.             if (!(File.Exists(FileName)))
  30.             {
  31.                 throw new FileNotFoundException("文件没有被找到");
  32.             }
  33.             FileStream DwgF;  //文件流
  34.             int PosSentinel;  //文件描述块的位置
  35.             BinaryReader br;  //读取二进制文件
  36.             int TypePreview;  //缩略图格式
  37.             int PosBMP;       //缩略图位置
  38.             int LenBMP;       //缩略图大小
  39.             short biBitCount; //缩略图比特深度
  40.             BITMAPFILEHEADER biH; //BMP文件头,DWG文件中不包含位图文件头,要自行加上去
  41.             byte[] BMPInfo;       //包含在DWG文件中的BMP文件体
  42.             MemoryStream BMPF = new MemoryStream(); //保存位图的内存文件流
  43.             BinaryWriter bmpr = new BinaryWriter(BMPF); //写二进制文件类
  44.             Image myImg = null;
  45.             try
  46.             {
  47.                 DwgF = new FileStream(FileName, FileMode.Open, FileAccess.Read);   //文件流
  48.                 br = new BinaryReader(DwgF);
  49.                 DwgF.Seek(13, SeekOrigin.Begin); //从第十三字节开始读取
  50.                 PosSentinel = br.ReadInt32();  //第13到17字节指示缩略图描述块的位置
  51.                 DwgF.Seek(PosSentinel + 30, SeekOrigin.Begin);  //将指针移到缩略图描述块的第31字节
  52.                 TypePreview = br.ReadByte();  //第31字节为缩略图格式信息,2 为BMP格式,3为WMF格式
  53.                 if (TypePreview == 1)
  54.                 {
  55.                 }
  56.                 else if (TypePreview == 2 || TypePreview == 3)
  57.                 {
  58.                     PosBMP = br.ReadInt32(); //DWG文件保存的位图所在位置
  59.                     LenBMP = br.ReadInt32(); //位图的大小
  60.                     DwgF.Seek(PosBMP + 14, SeekOrigin.Begin); //移动指针到位图块
  61.                     biBitCount = br.ReadInt16(); //读取比特深度
  62.                     DwgF.Seek(PosBMP, SeekOrigin.Begin); //从位图块开始处读取全部位图内容备用
  63.                     BMPInfo = br.ReadBytes(LenBMP); //不包含文件头的位图信息
  64.                     br.Close();
  65.                     DwgF.Close();
  66.                     biH.bfType = 19778; //建立位图文件头
  67.                     if (biBitCount < 9)
  68.                     {
  69.                         biH.bfSize = 54 + 4 * (int)(Math.Pow(2, biBitCount)) + LenBMP;
  70.                     }
  71.                     else
  72.                     {
  73.                         biH.bfSize = 54 + LenBMP;
  74.                     }
  75.                     biH.bfReserved1 = 0; //保留字节
  76.                     biH.bfReserved2 = 0; //保留字节
  77.                     biH.bfOffBits = 14 + 40 + 1024; //图像数据偏移
  78.                     //以下开始写入位图文件头
  79.                     bmpr.Write(biH.bfType); //文件类型
  80.                     bmpr.Write(biH.bfSize);  //文件大小
  81.                     bmpr.Write(biH.bfReserved1); //0              
  82.                     bmpr.Write(biH.bfReserved2); //0
  83.                     bmpr.Write(biH.bfOffBits); //图像数据偏移
  84.                     bmpr.Write(BMPInfo); //写入位图
  85.                     BMPF.Seek(0, SeekOrigin.Begin); //指针移到文件开始处
  86.                     myImg = Image.FromStream(BMPF); //创建位图文件对象
  87.                     bmpr.Close();
  88.                     BMPF.Close();
  89.                 }
  90.                 return myImg;
  91.             }
  92.             catch (Exception ex)
  93.             {
  94.                 throw new Exception(ex.Message);
  95.             }
  96.         }

  97.         /// <summary>
  98.         /// 此方法返回Source参数
  99.         /// </summary>
  100.         /// <param name="path"></param>
  101.         /// <returns></returns>
  102.         public static BitmapSource ImgToSource(string path)
  103.         {
  104.             //DWGview vd = new DWGview();
  105.                 System.Drawing.Bitmap bmp = new Bitmap(GetDwgImage(path));
  106.                 System.Windows.Media.Imaging.BitmapSource bi =
  107.                  System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(),
  108.                     IntPtr.Zero,
  109.                     Int32Rect.Empty,
  110.                     BitmapSizeOptions.FromEmptyOptions());
  111.                 return bi;
  112.         }


  113.     }
  114. }
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2018-4-9 14:21:08 | 显示全部楼层
CAD二次开发交流群:709658679
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-9-28 06:23 , Processed in 0.370892 second(s), 36 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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