问题描述

想做一个族库管理插件,其中有一个功能是预览其缩略图.

解决方案1

revit api中有一个ElementType.GetPreviewImage方法,ElementType的常用子类就是familySymbol

需要注意的是GetPreviewImage返回的是一个Bitmap,在winform中是直接可以用于pictureBox的image控件的,

但是wpf中的image控件的source一般接受的是一个BitmapImage.

bitmap和bitmapimage的区别以及如何相互转换在此不说,搜一搜即可,但要注意一点:

bitmap转换为bitmapImage或者bitmap.save()时,一定要保证创建bitmap的stream没有关闭,也就是说要避免使用using语句!

解决方案2

不使用任何revit api,使用System.IO.Packaging.StorageInfo的GetStreams方法,以下是链接:

https://thebuildingcoder.typepad.com/blog/2010/06/open-revit-ole-storage.html

他提供了一个示例文件的下载:

https://thebuildingcoder.typepad.com/files/openrevitolestorage.zip

简单概括下原理:反射System.IO.Packaging.StorageRoot的Open方法获取rfa文件的package信息,其中有一个叫做RevitPreview4.0的就存储着预览缩略图信息.将其读取为byte[],然后跳过revit的metadata,得到缩略图的原始二进制数据,

接下来就是byte[]转BitmapImage或者Bitmap的问题了,同样的要注意在某些地方避免使用using语句

抛砖引玉的代码

提供如何解析rfa文件和获得其跳过metadata后的起始位置的两个方法的代码:

        /// <summary>///     rfa等格式实际上是一个package,需通过StorageInfo来访问,但是要获得StorageInfo必须///     通过反射调用StorageRoot的一个Open方法来获得之/// </summary>/// <param name="filename"></param>/// <returns></returns>private byte[] ParseRevitPreview4_0(string filename){var srType = typeof(StorageInfo).Assembly.GetType("System.IO.Packaging.StorageRoot");if (srType?.InvokeMember("Open",BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, new object[]{filename,FileMode.Open,FileAccess.Read,FileShare.Read}) is StorageInfo stInfo){foreach (StreamInfo streamInfo in stInfo.GetStreams()){if (streamInfo.Name.Equals("RevitPreview4.0", StringComparison.Ordinal)){using (var reader = streamInfo.GetStream(FileMode.Open, FileAccess.Read)){var imageData = new byte[reader.Length];reader.Read(imageData, 0, imageData.Length);return imageData;}}}}return default;}/// <summary>///     RevitPreview4.0的二进制流中需要跳过revit的一些metadata,来获得图片的起始位置/// </summary>/// <param name="rawData"></param>/// <returns></returns>private int GetPngStartingOffset(byte[] rawData){bool markerFound = false;int startingOffset = 0;int previousValue = 0;using (MemoryStream ms = new MemoryStream(rawData)){for (int i = 0; i < rawData.Length; i++){int currentValue = ms.ReadByte();// possible start of PNG file dataif (currentValue == 137)   // 0x89{markerFound = true;startingOffset = i;previousValue = currentValue;continue;}switch (currentValue){case 80:   // 0x50if (markerFound && (previousValue == 137)){previousValue = currentValue;continue;}markerFound = false;break;case 78:   // 0x4Eif (markerFound && (previousValue == 80)){previousValue = currentValue;continue;}markerFound = false;break;case 71:   // 0x47if (markerFound && (previousValue == 78)){previousValue = currentValue;continue;}markerFound = false;break;case 13:   // 0x0Dif (markerFound && (previousValue == 71)){previousValue = currentValue;continue;}markerFound = false;break;case 10:   // 0x0Aif (markerFound && (previousValue == 26)){return startingOffset;}if (markerFound && (previousValue == 13)){previousValue = currentValue;continue;}markerFound = false;break;case 26:   // 0x1Aif (markerFound && (previousValue == 10)){previousValue = currentValue;continue;}markerFound = false;break;}}}return 0;}

两种方式获取revit族文件预览缩略图相关推荐

  1. jvm两种方式获取对象所占用的内存

    在开发过程中,我们有时需要来获取某个对象的大小,以方便我们参考,来决定开发的技术方案.jvm中提供了两种方式来获取一个对象的大小. 通过Instrumentation来计算对象的大小 编写计算代码: ...

  2. shell和javaAPI两种方式创建hbase表并预分区

    在hbase里面,如果我们建表不预分区,那么一个表的数据都会被一个region处理,如果数据过多就会执行region的split,如果数据量很大这样会很费性能,所以最好我们先根据业务的数据量在建表的时 ...

  3. 使用两种方式,Android 发送文件到指定邮箱(带多个附件)

    第一种方法,调用系统的邮件软件来发送 众所周知在Android中调用其他程序进行相关处理,都是使用的Intent.当然,Email也不例外. 在Android中,调用Email有三种类型的Intent ...

  4. Webpack/Vue-cli两种方式加载markdown文件并实现代码高亮

    准备的资源: highlight.js : 实现代码高亮,通过npm install highlight.js -D安装 vue-markdown-loader:解析md文件的必备loader,通过n ...

  5. android手机两种方式获取IP地址

    http://www.cnblogs.com/android100/p/Android-get-ip.html 1.使用WIFI 首先设置用户权限 Xml代码   <uses-permissio ...

  6. java 实现BufferedImage和ImageReader两种方式获取图片宽高、判断图片类型、获取图片大小工具类代码以及测试响应结果

    源码: import org.springframework.web.multipart.MultipartFile;import javax.imageio.ImageIO; import java ...

  7. springMVC两种方式实现多文件上传及效率比较

    springMVC实现多文件上传的方式有两种,一种是我们经常使用的以字节流的方式进行文件上传,另外一种是使用springMVC包装好的解析器进行上传.这两种方式对于实现多文件上传效率上却有着很大的差距 ...

  8. 获取checkbox选中状态的两种方式_张童瑶的博客

    获取checkbox选中状态的两种方式 获取checkbox选中状态的两种方式 第一种方式 第二种方式 我的其他文章 我的其他网站 获取checkbox选中状态的两种方式 我在开发项目的时候遇到这个问 ...

  9. 【Android】Android 彩信发送的两种方式+源代码

    Android  彩信发送的两种方式 第一种:直接调用彩信发送接口 实现代码如下, Intent intent = new Intent(Intent.ACTION_SEND); intent.add ...

  10. Delphi 读取文本文件的两种方式

    用两种方式读取文本文件:文件流读取和文件变量读取 一.文件流方式 {*******************************************************} {功能:读取文本文 ...

最新文章

  1. 为什么说能源管理是分布式光伏发电的突破口?
  2. 对接口运用扩展方法 Applying Extension Methods to an Interface 精通ASP-NET-MVC-5-弗瑞曼 Listing 4-15...
  3. 邮件实用技巧一:如何让你的邮件畅通全球
  4. 厉害了,ES 如何做到几十亿数据检索 3 秒返回!
  5. mysql中varchar与integer的互转
  6. JAVA程序设计----多线程(上)
  7. display:block的注意
  8. 如何在 C# 中使用 RabbitMQ
  9. DirectX 矩阵
  10. kafka partition分配_logstash消费kafka数据,partition分配不均衡
  11. 百战程序员JavaWeb系列教程-监听器视频教程
  12. 中国(龙港)首届 “港为人先”全球创新创业大赛
  13. 计算机excel按F4是那个公式,excel中键盘F4到底怎么用?_excle 中的f4
  14. yum.repos.d没有这个文件和目录解决方法
  15. 爱帮网CEO刘建国:垂直化是搜索发展的趋势
  16. Joan Baez - Jackaroe
  17. Windows下迁移nexus
  18. Anaconda安装教程(超详细)
  19. excel表显示与服务器通信失败,安装通用Excel服务器端,在连接数据库的时候提示:“用户 'sa' 登录失败。原因: 未与信任 SQL Server 连接相关联”...
  20. PHPCMS教程,手把手教你建网站

热门文章

  1. 【Keil5】关于keli5使用ST-link下载的配置方法
  2. 高德sdk定位当前位置_高德地图定位,获取当前位置坐标
  3. 计算机组成原理讲义 微盘,计算机组成原理课件.pdf
  4. 计算机2017语言排名,2017计算机编程语言排行榜 java依然独占鳌头
  5. Java发送邮件换行问题
  6. JMETER安装与配置教程
  7. 计算机软考网络工程师历年真题,2019上半年软考网络工程师考试下午真题
  8. 迅雷网速测试器 - 下载速率测试记录
  9. Redis势不可挡系列之概念剖析
  10. 深入理解Nginx:(1)初探Nginx 之一