C# PDFsharp DrawString文本对于某些PDF不可见
我正在使用的系统是带有特定信息的邮票PDF。它通过在文档的右上角创建一个浅绿色文本框来实现。然后,它在绿色空间的顶部绘制一个特定的字符串。这适用于数千个PDF,但对于其中一个PDF,即使框已绘制,文本也不可见。我仍然可以选择文本并将其复制到其他内容,但它在PDF中不可见 不幸的是,我无法共享PDF,但它是PDF 1.4。这是什么原因造成的 加盖印花守则: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
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与我可以分享的问题相同,我会的