最近做到和族库相关的功能需要获取到族文件的预览图,在RevitAPI中提供了ElementType.GetPreviewImage方法,但是前提就是你是在Revit里面操作的,并且已经拿到了Symbol对象实例,才可以调用此方法。然后在网上找了另外一种方式,通过读取Revit文件,在REVITPREVIEW4.0字段截取文件信息,将其转换为图片格式。

一、使用RevitAPI中ElementType.GetPreviewImage方法

[Autodesk.Revit.Attributes.Transaction(TransactionMode.Manual)]public class GetThumbnail : IExternalCommand{public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements){var uidoc = commandData.Application.ActiveUIDocument;var doc = uidoc.Document;var elemRef = uidoc.Selection.PickObject(ObjectType.Element);var elem = doc.GetElement(elemRef) as FamilyInstance;var previewImage = elem.Symbol.GetPreviewImage(new Size(100, 100));return Result.Succeeded;}}

二、使用System.IO.Packaging.StorageInfo.GetStreams方法 这种方式可以在不打开Revit文件的情况下,直接读取族文件的方式直接获取到族预览图。

public static object InvokeStorageRootMethod(StorageInfo storageRoot, string methodName, params object[] methodArgs){ BindingFlags bindingFlags = BindingFlags.Static |BindingFlags.Instance |BindingFlags.Public |BindingFlags.NonPublic |BindingFlags.InvokeMethod;Type storageRootType = typeof(StorageInfo).Assembly.GetType("System.IO.Packaging.StorageRoot",true,false); object result = storageRootType.InvokeMember(methodName,bindingFlags,null,storageRoot,methodArgs);return result; }/// <summary>/// 获取缩略图/// </summary>/// <param name="file"></param>/// <param name="savePath"></param>public static void GetImage(string file,string savePath){StorageInfo storageRoot = (StorageInfo)InvokeStorageRootMethod(null,"Open",file,FileMode.Open,FileAccess.Read,FileShare.Read);if (storageRoot == null){return;}byte[] preViewData = null;StreamInfo[] streams = storageRoot.GetStreams();foreach (StreamInfo stream in streams){if (stream.Name.ToUpper().Equals("REVITPREVIEW4.0")){preViewData = ParsePreviewInfo(stream);}}InvokeStorageRootMethod(storageRoot, "Close");// 获取不到信息返回一个100x100的空图片if (preViewData == null || preViewData.Length <= 0){using (Bitmap newBitmap = new Bitmap(100, 100)){newBitmap.Save(savePath);return;}}// 通过Revit元数据读取到PNG图像的开头int startingOffset = GetPngStartingOffset(preViewData);if (startingOffset == 0){using (Bitmap newBitmap = new Bitmap(100, 100)){newBitmap.Save(savePath);return;}}byte[] pngDataBuffer = new byte[preViewData.GetUpperBound(0) - startingOffset + 1];// 将PNG图像数据读入字节数组using (MemoryStream ms = new MemoryStream(preViewData)){ms.Position = startingOffset;ms.Read(pngDataBuffer, 0, pngDataBuffer.Length);}byte[] decoderData = null;// 如果图像数据有效if (pngDataBuffer != null){// 使用内存流对PNG图像数据进行解码// 并将解码后的数据复制到字节数组中using (MemoryStream ms = new MemoryStream(pngDataBuffer)){PngBitmapDecoder decoder = new PngBitmapDecoder(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);decoderData = BitSourceToArray(decoder.Frames[0]);}}// 如果解码的数据有效if ((decoderData != null) && (decoderData.Length > 0)){// 使用另一个内存流创建Bitmap// 然后是一张图片Bitmapusing (MemoryStream ms = new MemoryStream(decoderData)){using (Bitmap newBitmap = new Bitmap((ms))){newBitmap.Save(savePath);return;}}}using (Bitmap newBitmap = new Bitmap(100, 100)){newBitmap.Save(savePath);}}private static byte[] ParsePreviewInfo(StreamInfo streamInfo){byte[] streamData = null;try{using (Stream streamReader = streamInfo.GetStream(FileMode.Open, FileAccess.Read)){streamData = new byte[streamReader.Length];streamReader.Read(streamData, 0, streamData.Length);return streamData;}}catch (Exception ex){throw ex;}finally{streamData = null;}}private static byte[] BitSourceToArray(BitmapSource bitmapSource){BitmapEncoder encoder = new JpegBitmapEncoder();using (MemoryStream ms = new MemoryStream()){encoder.Frames.Add(BitmapFrame.Create(bitmapSource));encoder.Save(ms);return ms.ToArray();}}private static int GetPngStartingOffset(byte[] previewData){bool markerFound = false;int startingOffset = 0;int previousValue = 0;using (MemoryStream ms = new MemoryStream(previewData)){for (int i = 0; i < previewData.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;}

总结

以上两种方式都可以导出预览图,根据不同的场景不同需求自由选择。

作者:LIN JIASHUO
来源:在.NET Core上部署WordPress – LINJIASHUO
链接:LINJIASHUO BlOG

Revit获取族预览图相关推荐

  1. linux 获取网站预览图,Shell脚本实现获取网页快照并生成缩略图 -电脑资料

    这篇文章主要介绍了Shell脚本实现获取网页快照并生成缩略图,本文获取网页快照使用phantomjs.生成缩略图使用ImageMagick,需要的朋友可以参考下 获取网页快照并生成缩略图可分两步进行: ...

  2. 如何将php改成mp4,PHP 将视频转成 MP4 并获取视频预览图(用到ffmpeg)

    搜索热词 下面是编程之家 jb51.cc 通过网络收集整理的代码片段. 编程之家小编现在分享给大家,也给大家做个参考. flv_convert_get_thumb('input.avi','outpu ...

  3. Android 10.0获取本地视频及其预览图

    打开本地视频选择器 private void openLocalVideo(){Intent intent = new Intent();intent.setAction(Intent.ACTION_ ...

  4. java 视频预览_java在上传视频时生成预览图

    在圣品上传时往往需要生成一张预览图(缩略图),如果在非特殊情况下让用户单独上传,会造成工作压力,此时可以用视频中某一帧作为封面图,实现方式如下: public class ImageUtil { /* ...

  5. 使用mplayer做影片预览图

    影片预览图就是从整部影片中截取若干张图以求反映整部影片的全貌.就像下面这张图(来自<灌篮高手>剧场版中的那部 湘北 VS 绿风) -- ./sd.jpg -- mplayer是一款在GNU ...

  6. Unity编辑器扩展-生成prefab的预览图并保存为图片

    Project视图里的prefab文件都是一个蓝色的正方体,我想给它们加个预览图,暂时不知道怎么改Project视图的,但反正我想像NGUI那样有个专门的窗口存放一些常用的prefab,所以做成了如下 ...

  7. H5 Vue 视频 video 支持预览图 poster

    最近项目上要求文章中插入视频,并且视频需要支持预览图,给用户更好的视觉效果.本来以为加上poster就够了,但是没想到 ios 微信内置浏览器会有如下这种效果,很影响视觉体验. 优化步骤: 1.上传视 ...

  8. C# Winform 相册功能,图片缩放,拖拽,预览图分页

    效果 1.图片放大,缩小,拖拽功能 2.添加图片,分页功能 一.前言 在一些项目中也会用到预览图片的功能,至于为什么有一个添加图片的按钮,是因为有些项目,比如视觉相关的项目,摄像头拍摄图片,然后显示在 ...

  9. 如何生成IStyleGalleryItem和ISymbol对象的预览图(转载)

    http://blog.csdn.net/giselite/article/details/8451877 来看一下ArcMap的符号选择器: ArcMap的符号选择器都提供了符号的预览图,另一个预览 ...

最新文章

  1. 计算机对口升学可以报考的学校,对口升学可以报考的学校都在这里,赶快来收藏吧...
  2. 虚拟环境安装Scrapy框架
  3. 《你必须知道的.NET》书中对OCP(开放封闭)原则的阐述
  4. 清华大学李雅哲计算机,研究生教育动态 - 清华大学.pdf
  5. ONNX: export failure: Exporting the operator silu to ONNX opset version 12 is not suppo
  6. 飞桨PaddlePaddle 英特尔神经计算棒 联合优化AI算法CPU部署性能,推动产业低成本智能化升级
  7. 怎样建网站?(超详细)
  8. leetcode714
  9. wps单独文档无法连接服务器,为什么wps没有云服务器
  10. 互联网时代创业推荐三本书
  11. 振作起来,开始认真搞了
  12. 知识图谱·概念与技术--第1章学习笔记--知识图谱概述--知识图谱的概念,与传统语义网络的区别
  13. Lepus监控redis
  14. 2023考研常识知识之五类数学有哪些区别
  15. 读伤寒杂病论随想(转)
  16. selinux造成虚拟目录文件无法访问
  17. 不讲武德(手动狗头):面试官上来就甩给我几道多线程代码题叫我手撕,我心里拔凉拔凉的~~~
  18. BZOJ1791 基环树直径
  19. Session有什么重大BUG,微软提出了什么方法加以解决?
  20. 【供应链案例】解读联合利华供应链体系,看日化巨头如何高效运转复杂且庞大的供应链

热门文章

  1. java比较复数是否相等_通过重载运算符“= =”,实现判断两个复数是否相等的运算(若相等返回1,否则返回0)。重载前置“++”运算符,使虚部和实部分别加1。...
  2. 单元测试基础上篇——几大常用框架对比
  3. PHP实现QQ快速登录的方法
  4. Python采集天天基金数据,帮你掌握最新基金动向
  5. TestNG框架的环境搭建
  6. winform ListBox设置文字颜色
  7. SoO of EBGP
  8. 数据结构与算法概念解析
  9. Java实现二分法排序
  10. 华为S系列S2750S5700S6700交换机配置指南-接口管理