PdfiumViewer组件扩展(Pdfium.Net.Free)--注解
1.PdfiumViewer组件扩展(Pdfium.Net.Free)--概述2.PdfiumViewer组件扩展(Pdfium.Net.Free)--快速入门3.PdfiumViewer组件扩展(Pdfium.Net.Free)--PDF预览器框选4.PdfiumViewer组件扩展(Pdfium.Net.Free)--打开大文件处理5.PdfiumViewer组件扩展(Pdfium.Net.Free)--加载字体6.PdfiumViewer组件扩展(Pdfium.Net.Free)--创建字符子集7.PdfiumViewer组件扩展(Pdfium.Net.Free)--添加文本8.PdfiumViewer组件扩展(Pdfium.Net.Free)--添加图片9.PdfiumViewer组件扩展(Pdfium.Net.Free)--添加水印10.PdfiumViewer组件扩展(Pdfium.Net.Free)--删除或编辑pdf内容11.PdfiumViewer组件扩展(Pdfium.Net.Free)--PDF操作12.PdfiumViewer组件扩展(Pdfium.Net.Free)--签名
13.PdfiumViewer组件扩展(Pdfium.Net.Free)--注解
14.PdfiumViewer组件扩展(Pdfium.Net.Free)--可视化编辑pdf15.什么是转换矩阵以及如何使用它16.Pdfium.Net.Free 添加 bblanchon.PDFium nuget方式项目地址:
Pdfium.Net:https://github.com/1000374/Pdfium.Net
PdfiumViewer:https://github.com/1000374/PdfiumViewer
pdf的注解分很多类型,请查看以下枚举值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | public enum FpdfAnnotSubtypes { //Unknown annotation. UNKNOWN = 0, //Text annotation type. TEXT = 1, //Link annotation type. LINK = 2, //Free text annotation type. FREETEXT = 3, //Line annotation type. LINE = 4, //Square annotatotion type. SQUARE = 5, //Circle annotation type. CIRCLE = 6, //Polygon annotation type. POLYGON = 7, //Plyline annotation type. POLYLINE = 8, //Highlight annotation type. HIGHLIGHT = 9, //Underline annotation type. UNDERLINE = 10, //Squiggle annotation type. SQUIGGLY = 11, //Strikeout annotation type. STRIKEOUT = 12, //Rubber stamp annotation type. STAMP = 13, //Caret annotation type. CARET = 14, //Ink annotation type. INK = 15, //Popup annotation type. POPUP = 16, //File attachment annotation type. FILEATTACHMENT = 17, //Sound annotation type. SOUND = 18, //Movie annotation type. MOVIE = 19, //Widget annotation type. WIDGET = 20, //Screen annotation type. SCREEN = 21, //Printer mark annotation type. PRINTERMARK = 22, //Trap network annotation type. TRAPNET = 23, //Watermark annotation type. WATERMARK = 24, THREED = 25, //Rich media annotation type RICHMEDIA = 26, XFAWIDGET = 27, REDACT = 28 } |
可通过封装的方法获取常用的注解:
1 2 3 4 5 6 | var pathPdf = "./Pdfium.NetTests/resources/annotation_highlight_long_content.pdf" ; using ( var doc = PdfDocument.Load( new MemoryStream(File.ReadAllBytes(pathPdf)))) { var page0 = doc.Pages[0]; var links = page0.GetPageLinks(); } |
也可通过以下方法自行遍历获取,此代码为示例代码、在pdf预览中很多交互未实现或者合并实现,比如填充(WIDGET)pdf等交互,感兴趣的 可以自行研究
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | var pathPdf = "./Pdfium.NetTests/resources/annotation_highlight_long_content.pdf" ; using ( var doc = PdfDocument.Load( new MemoryStream(File.ReadAllBytes(pathPdf)))) { var page0 = doc.Pages[0]; var pageText0 = page0.PageText; var form = doc.PdfForm; var annotCount = page0.PageGetAnnotCount(); for ( int i = 0; i < annotCount; i++) { var annot = page0.PageGetAnnot(i); var subType = annot.Subtype; var rect = annot.Rect; //无用 var flag = annot.Flags; var boo = annot.IsSupportedSubtype(subType); switch (subType) { case FpdfAnnotSubtypes.HIGHLIGHT: { var higthLight = new AnnotData(); var keys = new string [] { FpdfAnnotationKeys.kAuthorKey, FpdfAnnotationKeys.kContents }; foreach ( var key in keys) { var types = annot.GetValueType(key); switch (types) { case FpdfObjectTypes.FPDF_OBJECT_STRING: if (key.Equals(FpdfAnnotationKeys.kAuthorKey)) higthLight.Author = annot.GetStringValue(key); else higthLight.Content = annot.GetStringValue(key); break ; case FpdfObjectTypes.FPDF_OBJECT_NUMBER: if (annot.GetNumberValue(key, out float values)) { if (key.Equals(FpdfAnnotationKeys.kAuthorKey)) higthLight.Author = values.ToString(); else higthLight.Content = values.ToString(); } break ; } } if (annot.GetColor(FpdfAnnotColorType.Color, out uint r, out uint g, out uint b, out uint a)) higthLight.BackColor = Color.FromArgb(( int )a, ( int )r, ( int )g, ( int )b); var attcount = annot.AttachmentPointsCount; for ( int j = 0; j < ( int )attcount; j++) { var quad_points = new FS_QUADPOINTSF(); if (annot.GetAttachmentPoints(( ulong )j, quad_points)) { } } var index = pageText0.GetCharIndexAtPos(rect.Left, rect.Top, Math.Abs(rect.Right - rect.Left), Math.Abs(rect.Top - rect.Bottom)); var fontName = pageText0.GetFontInfo(index, out FpdfFxfontFlags flags); var fontSize = pageText0.GetFontSize(index); higthLight.FontName = fontName; higthLight.FontSize = fontSize; } break ; case FpdfAnnotSubtypes.LINK: { var flink = annot.GetLink(); var action = flink.GetAction(); var acType = action.GetActionType(); switch (acType) { case FpdfActionTypes.UNSUPPORTED: { var dest = doc.LinkGetDest(flink); var targetPage = doc.DestGetDestPageIndex(dest); var uri = doc.ActionGetURIPath(action); } break ; case FpdfActionTypes.GOTO: { var dest = doc.ActionGetDest(action); var targetPage = doc.DestGetDestPageIndex(dest); var uri = doc.ActionGetURIPath(action); } break ; case FpdfActionTypes.REMOTEGOTO: break ; case FpdfActionTypes.URI: { var uri = doc.ActionGetURIPath(action); } break ; case FpdfActionTypes.LAUNCH: { var filePath = action.GetFilePath(); // new RectangleF(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top) } break ; case FpdfActionTypes.EMBEDDEDGOTO: { var dest = doc.ActionGetDest(action); var view = dest.GetDestView( out uint paraNum, out float paras); var filePath = action.GetFilePath(); } break ; } } break ; case FpdfAnnotSubtypes.WIDGET: { var formflag = form.AnnotGetFormFieldFlags(annot); var formName = form.AnnotGetFormFieldName(annot); var formValue = form.AnnotGetFormFieldValue(annot); var fontsize = form.AnnotGetFontSize(annot); var optionCount = form.AnnotGetOptionCount(annot); for ( int ni = 0; ni < optionCount; ni++) { var lable = form.AnnotGetOptionLabel(annot, ni); var iselect = form.AnnotIsOptionSelected(annot, ni); } } break ; case FpdfAnnotSubtypes.POPUP: { // Attempting to retrieve |annot|'s "IRT"-linked annotation would fail, // since "IRT" is not a key in |annot|'s dictionary. var kIRTKey = "IRT" ; if (annot.HasKey(kIRTKey)) { var linked = annot.GetLinkedAnnot(kIRTKey); } if (annot.HasKey(FpdfAnnotationKeys.kP)) { var types = annot.GetValueType(FpdfAnnotationKeys.kP); switch (types) { case FpdfObjectTypes.FPDF_OBJECT_STRING: var strValue = annot.GetStringValue(FpdfAnnotationKeys.kP); break ; case FpdfObjectTypes.FPDF_OBJECT_NUMBER: var numValue = annot.GetNumberValue(FpdfAnnotationKeys.kP, out float values); break ; } } } break ; case FpdfAnnotSubtypes.SQUARE: break ; } } } |
注解预览展示:现在交互支持打开url、页面跳转、打开内置链接、鼠标悬浮标注展示注释
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!