C# PDFsharp DrawString文本对于某些PDF不可见

C# PDFsharp DrawString文本对于某些PDF不可见,c#,pdf,pdfsharp,C#,Pdf,Pdfsharp,我正在使用的系统是带有特定信息的邮票PDF。它通过在文档的右上角创建一个浅绿色文本框来实现。然后,它在绿色空间的顶部绘制一个特定的字符串。这适用于数千个PDF,但对于其中一个PDF,即使框已绘制,文本也不可见。我仍然可以选择文本并将其复制到其他内容,但它在PDF中不可见 不幸的是,我无法共享PDF,但它是PDF 1.4。这是什么原因造成的 加盖印花守则: private static XGraphics drawString(XGraphics xgr, PdfPage page, st

我正在使用的系统是带有特定信息的邮票PDF。它通过在文档的右上角创建一个浅绿色文本框来实现。然后,它在绿色空间的顶部绘制一个特定的字符串。这适用于数千个PDF,但对于其中一个PDF,即使框已绘制,文本也不可见。我仍然可以选择文本并将其复制到其他内容,但它在PDF中不可见

不幸的是,我无法共享PDF,但它是PDF 1.4。这是什么原因造成的

加盖印花守则:

    private static XGraphics drawString(XGraphics xgr, PdfPage page, string printString, int pageNumber = 0)
    {
        XFont font = new XFont("Verdana", 10, XFontStyle.BoldItalic);

        var textSize = xgr.MeasureString(printString, font);
        var width = textSize.Width;
        var height = textSize.Height;

        double xMin = 0;
        double yMin = 0;

        if (page.Rotate == 90)
        {
            xMin = page.Height - textSize.Width;
            var state = xgr.Save();
            xgr.DrawRectangle(XBrushes.LimeGreen, xMin, yMin, width, height);
            xgr.Restore(state);
            xgr.DrawString(printString, font, XBrushes.Black, new XRect(0, 0, page.Height, page.Width), topRight()); 
        }
        else 
        {
            xMin = page.Width - textSize.Width;
            var state = xgr.Save();
            xgr.DrawRectangle(XBrushes.LimeGreen, xMin, yMin, width, height);
            xgr.Restore(state);
            xgr.DrawString(printString, font, XBrushes.Black, new XRect(0, 0, page.Width, page.Height), topRight()); 
        }

        return xgr;
    }

    private static XStringFormat topRight()
    {
        XStringFormat format = new XStringFormat();
        format.Alignment = XStringAlignment.Far;
        format.LineAlignment = XLineAlignment.Near;
        return format;
    }
我已经尝试在xgr上使用Dipose()并在每次绘制操作之前重新初始化它。我已尝试在绘图操作之间保存和恢复xgr的状态,如代码中所示。我也尝试过各种字体和字体大小,但运气也不好


让我知道PDF的哪些元数据是相关的,我将与大家分享。

下面是我用来隐藏文档中的内容、编辑文档并再次保存的代码。如果对你有帮助,请告诉我

private PdfDocument FormatPdfDocument(PdfDocument document, List<string> packingTypes, string carrierName)
{
    XFont PackingTypeFont = new XFont("Calibri", 10, XFontStyle.Bold);
    var i = 0;
    foreach (PdfPage page in document.Pages)
    {
        using (var gfx = XGraphics.FromPdfPage(page))
        {
            var packingType = packingTypes.ElementAtOrDefault(i++) ?? "PackingType Not Found";
            if (carrierName == "xxxx")
            {
                var packingTypeBounds = new XRect(64, 62, 200, 12);
                gfx.DrawRectangle(XBrushes.White, packingTypeBounds);
                gfx.DrawString(packingType, PackingTypeFont, XBrushes.Black, packingTypeBounds, XStringFormats.TopLeft);

                var logoBounds = new XRect(0, 0, 130, 50);
                gfx.DrawRectangle(XBrushes.White, logoBounds);
            }
            else if (carrierName == "yyyy")
            {
                var packingTypeBounds = new XRect(200, 0, 200, 12);
                gfx.DrawString(packingType, PackingTypeFont, XBrushes.Black, packingTypeBounds, XStringFormats.TopLeft);
            }
            else if (carrierName == "zzzz")
            {
                var packingTypeBounds = new XRect(410, 20, 200, 12);
                var state = gfx.Save();
                gfx.RotateAtTransform(90, new XPoint { X = 410, Y = 20 });
                gfx.DrawString(packingType, PackingTypeFont, XBrushes.Black, packingTypeBounds, XStringFormats.TopLeft);
                gfx.Restore(state);
            }
        }
    }    
    return document;
}
private PdfDocument FormatPdfDocument(PdfDocument文档、列表打包类型、字符串载体名称)
{
XFont PackingTypeFont=新XFont(“Calibri”,10,XFontStyle.Bold);
var i=0;
foreach(document.Pages中的PdfPage页)
{
使用(var gfx=XGraphics.FromPdfPage(第页))
{
var packingType=packingTypes.ElementAtOrDefault(i++)??“未找到packingType”;
如果(carrierName==“xxxx”)
{
var packingTypeBounds=新的XRect(64,62,200,12);
gfx.DrawRectangle(XBrushes.White,packingTypeBounds);
gfx.DrawString(packingType,PackingTypeFont,XBrushes.Black,packingtypeboonds,XStringFormats.TopLeft);
var logobunds=新的XRect(0,0,130,50);
gfx.DrawRectangle(XBrushes.White,logobouts);
}
否则如果(carrierName==“yyyy”)
{
var packingTypeBounds=新的XRect(200,0,200,12);
gfx.DrawString(packingType,PackingTypeFont,XBrushes.Black,packingtypeboonds,XStringFormats.TopLeft);
}
else if(carrierName==“zzzz”)
{
var packingTypeBounds=新的XRect(410,20,200,12);
var state=gfx.Save();
旋转变换(90,新的X点{X=410,Y=20});
gfx.DrawString(packingType,PackingTypeFont,XBrushes.Black,packingtypeboonds,XStringFormats.TopLeft);
gfx.恢复(状态);
}
}
}    
归还文件;
}

到目前为止,这对我来说很好,没有任何问题。

一些可能的原因可以回答您的问题“什么会导致这种情况?”:

您使用的是最新版本的PDFsharp 1.50 beta 3b吗? IIRC 1.32中存在一个错误,可能导致意外行为,因为某些属性未重置。
因为你看到了矩形,这可能就是原因

由于您看到了矩形,这可能不适用:
修改现有页面有两种方式:“追加”和“预结束”。您的代码片段没有显示如何执行此操作。 使用“prepend”可以将石灰矩形隐藏在白色填充矩形下。在AdobeReaderwithActiveTransparencyGrid中观看PDF,并检查是否看到矩形所在的网格

由于您看到了矩形,这可能不适用:
也许你的文字放错位置了。选中要修改的PDF页面的MediaBox和CropBox设置。页面通常从(0,0)开始,但您不能确定。
在PDF文件中找到文本,并将文本位置与MediaBox和CropBox进行比较


这可能是PDFsharp中的未知错误。如果你找不到一个PDF文件来复制你可以分享的问题,那么修复这个错误将非常困难。但也许上面的一个选择会带来成功。

所以我设法找到了一种方法让它发挥作用。我在文档上运行了两次加盖印花的过程,效果如预期。幸运的是,加盖两次戳不会影响正常工作的常规文档。

使用PdfSharp 1.5 GDI,我也遇到了这个问题。一些PDF可以,其他PDF可以有1或2个页面,然后其他PDF没有可以的页面。可以选择文本,但无法看到文本。更改renderMode可修复此问题

在PdfGraphicsState.cs中,有一个条件可以检查_realizedRenderingMode!=renderMode。但是,默认情况下,_realizedRenderingMode和renderMode为0,因此它不会进入代码块,也不会出现更改renderMode的方法,除非将字体更改为斜体、粗体、删除线或下划线:

    int _realizedRenderingMode;  // Reference: TABLE 5.2  Text state operators / Page 398

    public void RealizeFont(XFont font, XBrush brush, int renderingMode)
    {
        const string format = Config.SignificantFigures3;

        // So far rendering mode 0 (fill text) and 2 (fill, then stroke text) only.
        RealizeBrush(brush, _renderer._colorMode, renderingMode, font.Size); // _renderer.page.document.Options.ColorMode);

        // Realize rendering mode.
        if (_realizedRenderingMode != renderingMode)
        {
            _renderer.AppendFormatInt("{0} Tr\n", renderingMode);
            _realizedRenderingMode = renderingMode;
        }
删除该条件就足以解决问题,但是对于xgraphicsdpfrenderer.cs中的BT(开始文本),渲染模式似乎只需要一次

    internal void BeginTextMode()
    {
        if (_streamMode != StreamMode.Text)
        {
            _streamMode = StreamMode.Text;
            _content.Append("BT\n");
            // Text matrix is empty after BT
            _gfxState.RealizedTextPosition = new XPoint();
            _gfxState.ItalicSimulationOn = false;
        }
    }
因此,我最终修改了XGraphics以包含XGraphicsPdfRendererOptions,并将变量传递给各种方法,以便在不考虑位置的情况下对其进行更改:

    private XGraphicsPdfRendererOptions _renderOptions { get; set; }
    public XGraphicsPdfRendererOptions RenderOptions
    {
        get
        {
            if (_renderOptions == null)
            {
                _renderOptions = new XGraphicsPdfRendererOptions();
            }

            return _renderOptions;
        }
        set
        {
            _renderOptions = value;
        }
    }
请记住,renderMode最初是基于字体是斜体、粗体、删除线还是下划线,在xGraphicspFrenderer.cs中,我并不真正了解这些字体与renderMode的关系:

            //bool bold = (font.Style & XFontStyle.Bold) != 0;
        //bool italic = (font.Style & XFontStyle.Italic) != 0;
        bool italicSimulation = (font.GlyphTypeface.StyleSimulations & XStyleSimulations.ItalicSimulation) != 0;
        bool boldSimulation = (font.GlyphTypeface.StyleSimulations & XStyleSimulations.BoldSimulation) != 0;
        bool strikeout = (font.Style & XFontStyle.Strikeout) != 0;
        bool underline = (font.Style & XFontStyle.Underline) != 0;

        Realize(font, brush, boldSimulation ? 2 : 0);
类和枚举:

public class XGraphicsPdfRendererOptions
{
    public XGraphicsPdfRenderMode RenderMode { get; set; }
    public bool IncludeRenderModeForPage { get; set; }
    public bool IncludeRenderModeForObject { get; set; }
}

public enum XGraphicsPdfRenderMode
{
    Text_Render_Mode_Fill = 0,
    Text_Render_Mode_Stroke = 1,
    Text_Render_Mode_Fill_Stroke = 2,
    Text_Render_Mode_Invisible = 3
}
用法:

gfx.RenderOptions = new XGraphicsPdfRendererOptions() { RenderMode = XGraphicsPdfRenderMode.Text_Render_Mode_Fill, IncludeRenderModeForPage = true };

我已经在不同的项目中多次遇到这个问题。我发现最简单的修复方法是处理
XGraphics
对象,然后使用当前的
PdfPage
实例重新实例化它

 PdfSharp.Pdf.PdfPage Page = Document.AddPage();

 PdfSharp.Drawing.XGraphics gfx = PdfSharp.Drawing.XGraphics.FromPdfPage(Page);

 //Build your pdf here until transparency issue occurs

 //Issue has occured so re-instantiate gfx object
 gfx.Dispose();
 gfx = PdfSharp.Drawing.XGraphics.FromPdfPage(Page);

 //Continue as normal

这对我没有帮助。我的绿色矩形在讨论中的PDF上画得很好,但我的字符串不是。我的代码已经在数千个PDF上运行,所以我不需要这些代码。除非我遗漏了什么?我尝试过使用1.50测试版,没有任何改变。MediaBox和CropBox是正确的。谢谢你的其他建议。如果我发现一个PDF与我可以分享的问题相同,我会的