当前位置: 首页 > 编程语言 > C#

如何防止替换注释改变位置和文字大小?分享

时间:2023-04-10 12:07:52 C#

如何防止替换注释改变位置和文字大小?我正在使用iTextSharp将Typewriter注释替换为具有相同内容和位置的文本框,但一些生成的文本框最终以不同的文本大小出现在不同的位置,尽管hashMap中的数据似乎完全相同。问题是,当我在此示例PDF上创建这些新注释,然后在Adob??eAcrobatXI中查看PDF时,新文本框出现以下问题:我怀疑所有3个问题都是由于我正在创建新的文本框潜在的问题。当我检查hashMap中注释的/Rect键时,它具有与原始freeTextAnnot相同顺序的相同矩形坐标,所以我不明白为什么某些注释最终被替换了。这是我使用现有打字机注释数据创建新文本框的代码。请注意,您需要将inputPath和outputPath设置为PDF的实际位置及其目标路径:usingSystem;使用System.Collections.Generic;使用System.Linq;使用系统文本;使用System.Threading.Tasks;使用iTextSharp;使用iTextSharp.text.pdf;使用System.IO;namespacePDFConverterTester{publicclassPdfModifierTester{publicvoidtestWithPaths(){//设置为测试PDF字符串的位置inputPath=@"C:InputPathBeforeConversionDummy.pdf";//设置为新PDF字符串的目的地outputPath=@"C:OutputPathBeforeConversionDummy.pdf";测试(输入路径,输出路径);}publicvoidtest(stringinputPath,stringoutputPath){PdfReaderpdfReader=newPdfReader(inputPath);PdfStamperpdfStamper=newPdfStamper(pdfReader,newFileStream(outputPath,FileMode.Create));//获取第一页的PdfDictionaryPdfDictionarypageDict=pdfReader.GetPageN(1);//获取注释数组PdfArrayannotArray=pageDict.GetAsArray(PdfName.ANNOTS);//遍历注解数组intsize=annotArray.Size;for(inti=size-1;i>=0;i--){PdfDictionarydict=annotArray.GetAsDict(i);PdfNameITName=dict.GetAsName(newPdfName("IT"));if(ITName!=null){if(ITName.Equals(newPdfName("FreeTextTypewriter"))){PdfAnnotationannot=copyToNewAnnotation_SSCCE(dict,pdfStamper);pdfStamper.AddAnnotation(annot,1);annotArray.Remove(i);}}}pdfStamper.Close();pdfReader.Close();}privatePdfAnnotationcopyToNewAnnotation_SSCCE(PdfDictionaryfreeTextAnnot,PdfStamperpdfStamper){//CreateFreeText()需要矩形iTextSharp.text.Rectanglerect;PdfArrayrectArray=freeTextAnnot.GetAsArray(PdfName.RECT);如果(rectArray==null){rect=null;}else{rect=newiTextSharp.text.Rectangle(getFloat(rectArray,0),getFloat(rectArray,1),getFloat(rectArray,2),getFloat(rectArray,3));}//创建新注释PdfContentBytepcb=newPdfContentByte(pdfStamper.Writer);PdfAnnotationannot=PdfAnnotation.CreateFreeText(pdfStamper.Writer,rect,"",pcb);//在字典中为freeTextAnnot字符串创建所有可能的PdfName键数组pdfNames="AP,BS,C,CA,CL,CONTENTS,CREATIONDATE,DA,DS,F,IT,LE,M,NM,P,POPUP,Q,RC,RD,ROTATE,SUBJ,SUBTYPE,T,TYPE";字符串[]pdfNameArray=pdfNames.Split(',');//遍历键数组,将键值对复制到新注释foreach(stringpdfNameinpdfNameArray){//获取此PdfName的值PdfObjectobj=freeTextAnnot.Get(key);//如果返回值为空,可能键区分大小写if(obj==null){//尝试只将首字母大写,例如“Contents”而不是“CONTENTS”stringfirstCappdfName=char.ToUpper(pdfName[0])+pdfName.Substring(1);key=newPdfName(firstCappdfName);obj=freeTextAnnot.Get(键);}//在新注解中设置键值对annot.Put(key,obj);}//将注释类型更改为文本框annot.Put(PdfName.SUBTYPE,PdfName.FREETEXT);annot.Put(newPdfName("Subj"),newPdfString("文本框"));//设置默认空白边框annot.Put(PdfName.BORDER,newPdfBorderArray(0,0,0));返回注释;}privatefloatgetFloat(PdfArrayarr,intindex){returnfloat.Parse(arr[index].ToString());编辑:似乎部分问题可能出在对pdfStamper.AddAnnotation(annot,1)的调用中,因为在此调用之后,/Rect键值的注释将更改例如:在AddAnnotation()调用之前:{[2401,408.56,2445.64,693]}在调用之后:{[1899,2445.64,2183.44,2401]}所以也许下面的代码来自PdfStamper.AddAnnotation()(链接到源代码),第1463-1493行,我正在研究这种可能性:if(!annot.IsUsed()){PdfRectanglerect=(PdfRectangle)annot.Get(PdfName.RECT);如果(矩形!=null&&(矩形。左!=0||rect.Right!=0||rect.Top!=0||rect.Bottom!=0)){introtation=reader.GetPageRotation(pageN);矩形pageSize=reader.GetPageSizeWithRotation(pageN);switch(rotation){case90:annot.Put(PdfName.RECT,newPdfRectangle(pageSize.Top-rect.Top,rect.Right,pageSize.Top-rect.Bottom,rect.Left));休息;案例180:annot.Put(PdfName.RECT,newPdfRectangle(pageSize.Right-rect.Left,pageSize.Top-rect.Bottom,pageSize.Right-rect.Right,pageSize.Top-rect.Top));休息;270:annot.Put(PdfName.RECT,newPdfRectangle(rect.Bottom,pageSize.Right-rect.Left,rect.Top,pageSize.Right-rect.Right));休息;}}}}你自己发现的原因注意位置和大小变化的原因说明:似乎部分问题可能出在对pdfStamper.AddAnnotation(annot,1)的调用上,因为此调用后/Rect键的注释值发生了变化。..来自PdfStamper.AddAnnotation()(链接到源代码)的代码,第1463-1493行,负责在页面旋转时实际更改注释矩形。这背后的基本原理是,对于旋转的页面,iText试图减轻为绘制直立文本所需的页面内容添加旋转和平移的负担,并将坐标系原点保持在页面左下角的用户肩部,以便用户不必处理页面轮换。因此,它也适用于注释。对于页面内容,PdfStamper属性RotateContents默认为true,允许在明确不需要时关闭此旋转和转换。不幸的是,注释没有类似的属性,它们的位置和大小总是被“修正”,即旋转和平移。解决方法由于页面旋转是iText旋转和平移矩形的触发器,您可以在操作注释之前简单地删除页面旋转,然后再添加它:PdfDictionarypageDict=pdfReader.GetPageN(1);//隐藏页面旋转PdfNumberrotation=pageDict.GetAsNumber(PdfName.ROTATE);pageDict.Remove(PdfName.ROTATE);//获取注释数组PdfArrayannotArray=pageDict.GetAsArray(PdfName.ANNOTS);//遍历注解数组intsize=annotArray.Size;for(inti=size-1;i>=0;i--){...}//如果需要再次添加页面旋转if(rotation!=null)pageDict.Put(PdfName.ROTATE,rotation);pdfStamper.Close();通过此添加,注释保持不变。缺少属性您还观察到:当您右键单击新文本框时,没有可用的属性这是因为您没有更改intent(IT)条目,所以它们仍然包含FreeTextTypewriter,所以Adob??eReader不确定是什么类型对象,所以没有提供属性对话框。如果您还更改了意图://将注释类型更改为文本框annot.Put(PdfName.SUBTYPE,PdfName.FREETEXT);annot.Put(newPdfName("IT"),PdfName.FREETEXT);//你会得到属性对话框。顺便说一句,您的方法getFloat首先导致了我的坐标系中最奇怪的偏移,因为我的语言环境不使用点作为小数点分隔符。我将其更改为此以使其与区域设置无关:privatefloatgetFloat(PdfArrayarr,intindex){returnarr.GetAsNumber(index).FloatValue;是否有其他方法替换原始评论而不是简单地编辑它的特定原因?例如:以上是C#学习教程:如何防止替换注释改变位置和文字大小?如果分享的内容对你有用,需要进一步了解C#学习教程,希望你多多关注---publicvoidAlternativeReplaceFreetextByTextbox(stringInputPath,stringOutputPath){PdfNameIT=newPdfName("IT");PdfNameFREETEXTTYPEWRITER=newPdfName("FreeTextTypewriter");使用(PdfReaderReader=newPdfReader(InputPath)){PdfDictionaryPage=Reader.GetPageN(1);PdfArray注释=Page.GetAsArray(PdfName.ANNOTS);foreach(注释中的PdfObject对象){PdfDictionaryAnnotation=(PdfDictionary)PdfReader.GetPdfObject(Object);PdfNameIntent=Annotation.GetAsName(IT);if(FREETEXTTYPEWRITER.Equals(Intent)){//将注释类型更改为文本框Annotation.Put(IT,PdfName.FREETEXT);}}使用(PdfStamperStamper=newPdfStamper(Reader,newFileStream(OutputPath,FileMode.Create))){}}}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处: