使用itextsharp突出显示PDF文件时,数字超出范围错误

本文关键字:数字 范围 错误 文件 itextsharp 显示 PDF 使用 | 更新日期: 2023-09-27 18:33:02

我使用以下问题的答案中的代码突出显示了pdf中的单词:[使用itextsharp突出显示pdf中的单词,而不是在浏览器中显示突出显示的单词]2

但是打开此pdf时,我收到"数字超出范围错误"。

   private void hightlightPDFText()
{
    try
    {
        string[] highlightText = new string[] { "EXTENSIONAL", "geology" };
        string inputFile = Server.MapPath("~/pdf/") + "101111j174754572003tb00036x.pdf";
        string outputFile = Server.MapPath("~/pdf/") + "101111j174754572003tb00036x_Highlighted.pdf";
        // get input document            
        highlightPDFAnnotation(inputFile, outputFile, highlightText);
    }
    catch (Exception ex)
    {
        Response.Write(ex.Message);
    }
}
private void highlightPDFAnnotation(string inputFile, string outputFile, string[] highlightText)
{
    try
    {
        PdfReader reader = new PdfReader(inputFile);
        using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
        {
            using (PdfStamper stamper = new PdfStamper(reader, fs))
            {
                myLocationTextExtractionStrategy strategy = new myLocationTextExtractionStrategy();
                int pageCount = reader.NumberOfPages;
                for (int pageno = 1; pageno <= pageCount; pageno++)
                {

                    string currentText = PdfTextExtractor.GetTextFromPage(reader, pageno, strategy);
                    for (int i = 0; i < highlightText.Length; i++)
                    {
                        List<iTextSharp.text.Rectangle> MatchesFound = strategy.GetTextLocations(highlightText[i].Trim(), StringComparison.CurrentCultureIgnoreCase);
                        foreach (Rectangle rect in MatchesFound)
                        {
                            float[] quad = { rect.Left, rect.Bottom, rect.Right, rect.Bottom, rect.Left, rect.Top, rect.Right, rect.Top };
                            //Create our hightlight
                            PdfAnnotation highlight = PdfAnnotation.CreateMarkup(stamper.Writer, rect, null, PdfAnnotation.MARKUP_HIGHLIGHT, quad);
                            //Set the color
                            highlight.Color = BaseColor.YELLOW;
                            PdfAppearance appearance = PdfAppearance.CreateAppearance(stamper.Writer, rect.Width, rect.Height);
                            PdfGState state = new PdfGState();
                            state.BlendMode = new PdfName("Multiply");
                            appearance.SetGState(state);
                            appearance.Rectangle(0, 0, rect.Width, rect.Height);
                            appearance.SetColorFill(BaseColor.YELLOW);
                            appearance.Fill();
                            highlight.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, appearance);
                            stamper.AddAnnotation(highlight, pageno);
                        }
                    }
                }
            }
        }
        reader.Close();
        File.Copy(outputFile, inputFile, true);
        File.Delete(outputFile);
    }
    catch (Exception ex)
    {
        throw;
    }
}

使用itextsharp突出显示PDF文件时,数字超出范围错误

我可以重现该问题。这不是iTextSharp的问题,而是我之前回答OP使用的代码的问题;此外,在此答案中,第三方 Jcis 提供的 myLocationTextExtractionStrategy 类可能存在问题,或者仅仅是我翻译的 VB 到 C# 转换器中的问题,不必混合使用 VB 和 C#。此外,OP 的代码中存在导致标记过多的问题。

从这里开始highlightPDFAnnotation问题

在该方法中,我使用

myLocationTextExtractionStrategy strategy = new myLocationTextExtractionStrategy();

无需任何进一步初始化,但需要初始化一个成员:

strategy.UndercontentHorizontalScaling = 100;

如果无法做到这一点,则很遗憾,该策略将使用 0 默认值。结果,所有字符串宽度计算都乘以 0...

完成这个答案后,我将修复该答案中的代码。

myLocationTextExtractionStrategy中的问题,至少在我的 C# 版本中是这样

我使用的 C# 翻译中GetStringWidth myLocationTextExtractionStrategy方法

定义为
private float GetStringWidth(string str, float curFontSize, float pSingleSpaceWidth, DocumentFont pFont)
{
    char[] chars = str.ToCharArray();
    float totalWidth = 0;
    float w = 0;
    foreach (char c in chars) {
        w = pFont.GetWidth(c) / 1000;
        totalWidth += (w * curFontSize + this.UndercontentCharacterSpacing) * this.UndercontentHorizontalScaling / 100;
    }
    return totalWidth;
}

不幸的是,pFont.GetWidth(c)被定义为返回一个int;因此,除法pFont.GetWidth(c) / 1000是作为整数运算执行的,所以几乎所有时间的结果都是0(因为字形宽度通常在0到1000之间(。必须将此行更正为:

w = pFont.GetWidth(c) / 1000.0f;

原始 VB 版本如下所示:

Private Function GetStringWidth(ByVal str As String, ByVal curFontSize As Single, ByVal pSingleSpaceWidth As Single, ByVal pFont As DocumentFont) As Single
    Dim chars() As Char = str.ToCharArray()
    Dim totalWidth As Single = 0
    Dim w As Single = 0
    For Each c As Char In chars
        w = pFont.GetWidth(c) / 1000
        totalWidth += (w * curFontSize + Me.UndercontentCharacterSpacing) * Me.UndercontentHorizontalScaling / 100
    Next
    Return totalWidth
End Function

我不知道 VB 足够好,无法判断这里的 w = pFont.GetWidth(c) / 1000 是计算为浮点运算还是整数运算。在后一种情况下,这也表明这里有问题。

问题的影响

有趣的是,这两个问题具有相同的效果:GetStringWidth总是返回 0。此方法在GetRectangleFromText用于计算校正因子:

'Text Width in User Space Units
Dim LineRealWidth As Single = LastChunk.PosRight - FirstChunk.PosLeft
'Text Width in Text Units
Dim LineTextWidth As Single = GetStringWidth(sTextinChunks, LastChunk.curFontSize, LastChunk.charSpaceWidth,  ThisPdfDocFonts.Values.ElementAt(LastChunk.FontIndex))
'TransformationValue value for Interpolation
Dim TransformationValue As Single = LineRealWidth / LineTextWidth

因此,TransformationValue最终是无穷大。

这个TransformationValue后来在某些特殊情况下乘以偏移量,从而产生如下矩形:

/Rect[259.2 679.86 -9223372036854775808 692.58]

这超出了Adobe Reader的范围。

OP 代码中的另一个问题

但是在这个问题中,OP 的代码中也存在一个真正的问题,他使用了一个全局策略对象

myLocationTextExtractionStrategy strategy = new myLocationTextExtractionStrategy();
int pageCount = reader.NumberOfPages;
for (int pageno = 1; pageno <= pageCount; pageno++)
{
    string currentText = PdfTextExtractor.GetTextFromPage(reader, pageno, strategy);

不幸的是,该策略会记住它解析的所有内容。因此,在处理页面时,代码认为其内容是当前页面之前所有页面的聚合内容。

所以它应该是

int pageCount = reader.NumberOfPages;
for (int pageno = 1; pageno <= pageCount; pageno++)
{
    myLocationTextExtractionStrategy strategy = new myLocationTextExtractionStrategy();
    strategy.UndercontentHorizontalScaling = 100;
    string currentText = PdfTextExtractor.GetTextFromPage(reader, pageno, strategy);

现在它对我有用。

附录:C# 中的完整myLocationTextExtractionStrategy

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
// how to highlight a text or word in a pdf file using iTextsharp?
// https://stackoverflow.com/questions/6523243/how-to-highlight-a-text-or-word-in-a-pdf-file-using-itextsharp
//
// myLocationTextExtractionStrategy has been shared by Jcis in his answer
// https://stackoverflow.com/a/11076968/1729265
// as VB class. This has been translated to C# using Telerik with some minor
// translation glitch fixes.
namespace iTextSharp_Playground.Content
{
    public class myLocationTextExtractionStrategy : ITextExtractionStrategy
    {
        private float _UndercontentCharacterSpacing = 0;
        private float _UndercontentHorizontalScaling = 0;
        private SortedList<string, DocumentFont> ThisPdfDocFonts;
        public static bool DUMP_STATE = false;
        //* a summary of all found text 
        private List<TextChunk> locationalResult = new List<TextChunk>();
        //*
        //         * Creates a new text extraction renderer.
        //         
        public myLocationTextExtractionStrategy()
        {
            ThisPdfDocFonts = new SortedList<string, DocumentFont>();
        }
        //*
        //         * @see com.itextpdf.text.pdf.parser.RenderListener#beginTextBlock()
        //         
        public virtual void BeginTextBlock()
        {
        }
        //*
        //         * @see com.itextpdf.text.pdf.parser.RenderListener#endTextBlock()
        //         
        public virtual void EndTextBlock()
        {
        }
        //*
        //         * @param str
        //         * @return true if the string starts with a space character, false if the string is empty or starts with a non-space character
        //         
        private bool StartsWithSpace(String str)
        {
            if (str.Length == 0) {
                return false;
            }
            return str[0] == ' ';
        }
        //*
        //         * @param str
        //         * @return true if the string ends with a space character, false if the string is empty or ends with a non-space character
        //         
        private bool EndsWithSpace(String str)
        {
            if (str.Length == 0) {
                return false;
            }
            return str[str.Length - 1] == ' ';
        }
        public float UndercontentCharacterSpacing {
            get { return _UndercontentCharacterSpacing; }
            set { _UndercontentCharacterSpacing = value; }
        }
        public float UndercontentHorizontalScaling
        {
            get { return _UndercontentHorizontalScaling; }
            set { _UndercontentHorizontalScaling = value; }
        }
        public virtual String GetResultantText()
        {
            if (DUMP_STATE) {
                DumpState();
            }
            locationalResult.Sort();
            StringBuilder sb = new StringBuilder();
            TextChunk lastChunk = null;
            foreach (TextChunk chunk in locationalResult) {
                if (lastChunk == null) {
                    sb.Append(chunk.text);
                } else {
                    if (chunk.SameLine(lastChunk)) {
                        float dist = chunk.DistanceFromEndOf(lastChunk);
                        if (dist < -chunk.charSpaceWidth) {
                            sb.Append(' ');
                            // we only insert a blank space if the trailing character of the previous string wasn't a space, and the leading character of the current string isn't a space
                        } else if (dist > chunk.charSpaceWidth / 2f && !StartsWithSpace(chunk.text) && !EndsWithSpace(lastChunk.text)) {
                            sb.Append(' ');
                        }
                        sb.Append(chunk.text);
                    } else {
                        sb.Append((char)10);
                        sb.Append(chunk.text);
                    }
                }
                lastChunk = chunk;
            }
            return sb.ToString();
        }
        public List<iTextSharp.text.Rectangle> GetTextLocations(string pSearchString, System.StringComparison pStrComp)
        {
            List<iTextSharp.text.Rectangle> FoundMatches = new List<iTextSharp.text.Rectangle>();
            StringBuilder sb = new StringBuilder();
            List<TextChunk> ThisLineChunks = new List<TextChunk>();
            bool bStart = false;
            bool bEnd = false;
            TextChunk FirstChunk = null;
            TextChunk LastChunk = null;
            string sTextInUsedChunks = null;
            foreach (TextChunk chunk in locationalResult) {
                if (ThisLineChunks.Count > 0 && !chunk.SameLine(ThisLineChunks[ThisLineChunks.Count-1]))
                {
                    if (sb.ToString().IndexOf(pSearchString, pStrComp) > -1) {
                        string sLine = sb.ToString();
                        //Check how many times the Search String is present in this line:
                        int iCount = 0;
                        int lPos = 0;
                        lPos = sLine.IndexOf(pSearchString, 0, pStrComp);
                        while (lPos > -1) {
                            iCount += 1;
                            if (lPos + pSearchString.Length > sLine.Length)
                                break; // TODO: might not be correct. Was : Exit Do
                            else
                                lPos = lPos + pSearchString.Length;
                            lPos = sLine.IndexOf(pSearchString, lPos, pStrComp);
                        }
                        //Process each match found in this Text line:
                        int curPos = 0;
                        for (int i = 1; i <= iCount; i++) {
                            string sCurrentText = null;
                            int iFromChar = 0;
                            int iToChar = 0;
                            iFromChar = sLine.IndexOf(pSearchString, curPos, pStrComp);
                            curPos = iFromChar;
                            iToChar = iFromChar + pSearchString.Length - 1;
                            sCurrentText = null;
                            sTextInUsedChunks = null;
                            FirstChunk = null;
                            LastChunk = null;
                            //Get first and last Chunks corresponding to this match found, from all Chunks in this line
                            foreach (TextChunk chk in ThisLineChunks) {
                                sCurrentText = sCurrentText + chk.text;
                                //Check if we entered the part where we had found a matching String then get this Chunk (First Chunk)
                                if (!bStart && sCurrentText.Length - 1 >= iFromChar) {
                                    FirstChunk = chk;
                                    bStart = true;
                                }
                                //Keep getting Text from Chunks while we are in the part where the matching String had been found
                                if (bStart & !bEnd) {
                                    sTextInUsedChunks = sTextInUsedChunks + chk.text;
                                }
                                //If we get out the matching String part then get this Chunk (last Chunk)
                                if (!bEnd && sCurrentText.Length - 1 >= iToChar) {
                                    LastChunk = chk;
                                    bEnd = true;
                                }
                                //If we already have first and last Chunks enclosing the Text where our String pSearchString has been found 
                                //then it's time to get the rectangle, GetRectangleFromText Function below this Function, there we extract the pSearchString locations
                                if (bStart & bEnd) {
                                    FoundMatches.Add(GetRectangleFromText(FirstChunk, LastChunk, pSearchString, sTextInUsedChunks, iFromChar, iToChar, pStrComp));
                                    curPos = curPos + pSearchString.Length;
                                    bStart = false;
                                    bEnd = false;
                                    break; // TODO: might not be correct. Was : Exit For
                                }
                            }
                        }
                    }
                    sb.Clear();
                    ThisLineChunks.Clear();
                }
                ThisLineChunks.Add(chunk);
                sb.Append(chunk.text);
            }
            return FoundMatches;
        }
        private iTextSharp.text.Rectangle GetRectangleFromText(TextChunk FirstChunk, TextChunk LastChunk, string pSearchString, string sTextinChunks, int iFromChar, int iToChar, System.StringComparison pStrComp)
        {
            //There are cases where Chunk contains extra text at begining and end, we don't want this text locations, we need to extract the pSearchString location inside
            //for these cases we need to crop this String (left and Right), and measure this excedent at left and right, at this point we don't have any direct way to make a
            //Transformation from text space points to User Space units, the matrix for making this transformation is not accesible from here, so for these special cases when
            //the String needs to be cropped (Left/Right) We'll interpolate between the width from Text in Chunk (we have this value in User Space units), then i'll measure Text corresponding
            //to the same String but in Text Space units, finally from the relation betweeenthese 2 values I get the TransformationValue I need to use for all cases
            //Text Width in User Space Units
            float LineRealWidth = LastChunk.PosRight - FirstChunk.PosLeft;
            //Text Width in Text Units
            float LineTextWidth = GetStringWidth(sTextinChunks, LastChunk.curFontSize, LastChunk.charSpaceWidth, ThisPdfDocFonts.Values[LastChunk.FontIndex]);
            //TransformationValue value for Interpolation
            float TransformationValue = LineRealWidth / LineTextWidth;
            //In the worst case, we'll need to crop left and right:
            int iStart = sTextinChunks.IndexOf(pSearchString, pStrComp);
            int iEnd = iStart + pSearchString.Length - 1;
            string sLeft = null;
            if (iStart == 0)
                sLeft = null;
            else
                sLeft = sTextinChunks.Substring(0, iStart);
            string sRight = null;
            if (iEnd == sTextinChunks.Length - 1)
                sRight = null;
            else
                sRight = sTextinChunks.Substring(iEnd + 1, sTextinChunks.Length - iEnd - 1);
            //Measure cropped Text at left:
            float LeftWidth = 0;
            if (iStart > 0) {
                LeftWidth = GetStringWidth(sLeft, LastChunk.curFontSize, LastChunk.charSpaceWidth, ThisPdfDocFonts.Values[LastChunk.FontIndex]);
                LeftWidth = LeftWidth * TransformationValue;
            }
            //Measure cropped Text at right:
            float RightWidth = 0;
            if (iEnd < sTextinChunks.Length - 1) {
                RightWidth = GetStringWidth(sRight, LastChunk.curFontSize, LastChunk.charSpaceWidth, ThisPdfDocFonts.Values[LastChunk.FontIndex]);
                RightWidth = RightWidth * TransformationValue;
            }
            //LeftWidth is the text width at left we need to exclude, FirstChunk.distParallelStart is the distance to left margin, both together will give us this LeftOffset
            float LeftOffset = FirstChunk.distParallelStart + LeftWidth;
            //RightWidth is the text width at right we need to exclude, FirstChunk.distParallelEnd is the distance to right margin, we substract RightWidth from distParallelEnd to get RightOffset
            float RightOffset = LastChunk.distParallelEnd - RightWidth;
            //Return this Rectangle
            return new iTextSharp.text.Rectangle(LeftOffset, FirstChunk.PosBottom, RightOffset, FirstChunk.PosTop);
        }
        private float GetStringWidth(string str, float curFontSize, float pSingleSpaceWidth, DocumentFont pFont)
        {
            char[] chars = str.ToCharArray();
            float totalWidth = 0;
            float w = 0;
            foreach (char c in chars) {
                w = pFont.GetWidth(c) / 1000f;
                totalWidth += (w * curFontSize + this.UndercontentCharacterSpacing) * this.UndercontentHorizontalScaling / 100;
            }
            return totalWidth;
        }
        private void DumpState()
        {
            foreach (TextChunk location in locationalResult) {
                location.PrintDiagnostics();
                Console.WriteLine();
            }
        }
        public virtual void RenderText(TextRenderInfo renderInfo)
        {
            LineSegment segment = renderInfo.GetBaseline();
            TextChunk location = new TextChunk(renderInfo.GetText(), segment.GetStartPoint(), segment.GetEndPoint(), renderInfo.GetSingleSpaceWidth());
            var _with1 = location;
            //Chunk Location:
//          Debug.Print(renderInfo.GetText);
            _with1.PosLeft = renderInfo.GetDescentLine().GetStartPoint()[Vector.I1];
            _with1.PosRight = renderInfo.GetAscentLine().GetEndPoint()[Vector.I1];
            _with1.PosBottom = renderInfo.GetDescentLine().GetStartPoint()[Vector.I2];
            _with1.PosTop = renderInfo.GetAscentLine().GetEndPoint()[Vector.I2];
            //Chunk Font Size: (Height)
            _with1.curFontSize = _with1.PosTop - segment.GetStartPoint()[Vector.I2];
            //Use Font name  and Size as Key in the SortedList
            string StrKey = renderInfo.GetFont().PostscriptFontName + _with1.curFontSize.ToString();
            //Add this font to ThisPdfDocFonts SortedList if it's not already present
            if (!ThisPdfDocFonts.ContainsKey(StrKey))
                ThisPdfDocFonts.Add(StrKey, renderInfo.GetFont());
            //Store the SortedList index in this Chunk, so we can get it later
            _with1.FontIndex = ThisPdfDocFonts.IndexOfKey(StrKey);
            locationalResult.Add(location);
        }
        //*
        //         * Represents a chunk of text, it's orientation, and location relative to the orientation vector
        //         
        public class TextChunk : IComparable<TextChunk>
        {
            //* the text of the chunk 
            internal String text;
            //* the starting location of the chunk 
            internal Vector startLocation;
            //* the ending location of the chunk 
            internal Vector endLocation;
            //* unit vector in the orientation of the chunk 
            internal Vector orientationVector;
            //* the orientation as a scalar for quick sorting 
            internal int orientationMagnitude;
            //* perpendicular distance to the orientation unit vector (i.e. the Y position in an unrotated coordinate system)
            //             * we round to the nearest integer to handle the fuzziness of comparing floats 
            internal int distPerpendicular;
            //* distance of the start of the chunk parallel to the orientation unit vector (i.e. the X position in an unrotated coordinate system) 
            internal float distParallelStart;
            //* distance of the end of the chunk parallel to the orientation unit vector (i.e. the X position in an unrotated coordinate system) 
            internal float distParallelEnd;
            //* the width of a single space character in the font of the chunk 
            internal float charSpaceWidth;
            private float _PosLeft;
            private float _PosRight;
            private float _PosTop;
            private float _PosBottom;
            private float _curFontSize;
            private int _FontIndex;
            public int FontIndex {
                get { return _FontIndex; }
                set { _FontIndex = value; }
            }
            public float PosLeft {
                get { return _PosLeft; }
                set { _PosLeft = value; }
            }
            public float PosRight {
                get { return _PosRight; }
                set { _PosRight = value; }
            }
            public float PosTop {
                get { return _PosTop; }
                set { _PosTop = value; }
            }
            public float PosBottom {
                get { return _PosBottom; }
                set { _PosBottom = value; }
            }
            public float curFontSize {
                get { return _curFontSize; }
                set { _curFontSize = value; }
            }
            public TextChunk(String str, Vector startLocation, Vector endLocation, float charSpaceWidth)
            {
                this.text = str;
                this.startLocation = startLocation;
                this.endLocation = endLocation;
                this.charSpaceWidth = charSpaceWidth;
                Vector oVector = endLocation.Subtract(startLocation);
                if (oVector.Length == 0) {
                    oVector = new Vector(1, 0, 0);
                }
                orientationVector = oVector.Normalize();
                orientationMagnitude = Convert.ToInt32(Math.Truncate(Math.Atan2(orientationVector[Vector.I2], orientationVector[Vector.I1]) * 1000));
                Vector origin = new Vector(0, 0, 1);
                distPerpendicular = Convert.ToInt32((startLocation.Subtract(origin)).Cross(orientationVector)[Vector.I3]);
                distParallelStart = orientationVector.Dot(startLocation);
                distParallelEnd = orientationVector.Dot(endLocation);
            }
            public void PrintDiagnostics()
            {
                Console.WriteLine("Text (@" + Convert.ToString(startLocation) + " -> " + Convert.ToString(endLocation) + "): " + text);
                Console.WriteLine("orientationMagnitude: " + orientationMagnitude);
                Console.WriteLine("distPerpendicular: " + distPerpendicular);
                Console.WriteLine("distParallel: " + distParallelStart);
            }
            //*
            //             * @param as the location to compare to
            //             * @return true is this location is on the the same line as the other
            //             
            public bool SameLine(TextChunk a)
            {
                if (orientationMagnitude != a.orientationMagnitude) {
                    return false;
                }
                if (distPerpendicular != a.distPerpendicular) {
                    return false;
                }
                return true;
            }
            //*
            //             * Computes the distance between the end of 'other' and the beginning of this chunk
            //             * in the direction of this chunk's orientation vector.  Note that it's a bad idea
            //             * to call this for chunks that aren't on the same line and orientation, but we don't
            //             * explicitly check for that condition for performance reasons.
            //             * @param other
            //             * @return the number of spaces between the end of 'other' and the beginning of this chunk
            //             
            public float DistanceFromEndOf(TextChunk other)
            {
                float distance = distParallelStart - other.distParallelEnd;
                return distance;
            }
            //*
            //             * Compares based on orientation, perpendicular distance, then parallel distance
            //             * @see java.lang.Comparable#compareTo(java.lang.Object)
            //             
            public int CompareTo(TextChunk rhs)
            {
                if (object.ReferenceEquals(this, rhs)) {
                    return 0;
                }
                // not really needed, but just in case
                int rslt = 0;
                rslt = CompareInts(orientationMagnitude, rhs.orientationMagnitude);
                if (rslt != 0) {
                    return rslt;
                }
                rslt = CompareInts(distPerpendicular, rhs.distPerpendicular);
                if (rslt != 0) {
                    return rslt;
                }
                // note: it's never safe to check floating point numbers for equality, and if two chunks
                // are truly right on top of each other, which one comes first or second just doesn't matter
                // so we arbitrarily choose this way.
                rslt = distParallelStart < rhs.distParallelStart ? -1 : 1;
                return rslt;
            }
            //*
            //             *
            //             * @param int1
            //             * @param int2
            //             * @return comparison of the two integers
            //             
            private static int CompareInts(int int1, int int2)
            {
                return int1 == int2 ? 0 : int1 < int2 ? -1 : 1;
            }
        }
        //*
        //         * no-op method - this renderer isn't interested in image events
        //         * @see com.itextpdf.text.pdf.parser.RenderListener#renderImage(com.itextpdf.text.pdf.parser.ImageRenderInfo)
        //         * @since 5.0.1
        //         
        public void RenderImage(ImageRenderInfo renderInfo)
        {
            // do nothing
        }
    }
}
//=======================================================
//Service provided by Telerik (www.telerik.com)
//Conversion powered by NRefactory.
//Twitter: @telerik
//Facebook: facebook.com/telerik
//=======================================================
由于

我的 <50 次代表,这是作为答案发布的,但实际上它是一个评论。

感谢 mkl 为我指出正确的方向,但是当考虑到这一点时,问题仍然存在(我在 VB 中工作(。

对于某些PDF(来自扫描的类似文档列表(,我也收到错误,结果发现pFont.GetWidth调用为每个字符返回零,因此GetStringWidth的结果也返回零。

我注意到我可以一次传递整个字符串或一个字符的 GetWidth,结果是相同的 - 当它起作用时,当我不得到零时,它工作得很好。

我下载了最新的 ITEXT (5-5-10-0(,问题仍然存在 - 由于这个问题很少发生,我暂时求助于 getstringwidth 的输出,如果它要变为零,那么我根据平均值估计响应,交叉检查它是否太高而不是 pSingleSpaceWidth 值。

我知道这很差,但我的要求不高,很少发生,我没有时间或必要的知识(Itext/PDF(来研究如何准确地获得等效的GetWidth结果。

我确实

希望这些信息对某人有所帮助,如果有人确实拥有改进/修复这个想法所需的知识,我就是全神贯注的。