Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 版本5.5.4+中的ItextSharp字体颜色问题;_C#_Itext - Fatal编程技术网

C# 版本5.5.4+中的ItextSharp字体颜色问题;

C# 版本5.5.4+中的ItextSharp字体颜色问题;,c#,itext,C#,Itext,我有一些使用红色字体颜色创建红色“戳记”的代码: string StampDate = DateTime.Now.ToString("MM/dd/yyyy"); string FontPath = Server.MapPath("/assets/Fonts"); string OrigFile = Server.MapPath("/test.pdf"); const int OpacityPercent = 80; const float PDFPaidF

我有一些使用红色字体颜色创建红色“戳记”的代码:

    string StampDate = DateTime.Now.ToString("MM/dd/yyyy");
    string FontPath = Server.MapPath("/assets/Fonts");
    string OrigFile = Server.MapPath("/test.pdf");
    const int OpacityPercent = 80;
    const float PDFPaidFontSize = 28;
    const float PDFCopyX = 170;
    const float PDFPaidX = 385;
    const float PDFY = 20;
    const float PDFDateXOffset = 7;
    const float PDFDateYOffset = 12;
    const float PDFDateFontSize = 10;
    const string PaidStampTxt = "PAID";
    const string CopyStampTxt = "COPY";
    const string ArialFilename = "arialbd.ttf";
    PdfStamper stamper = null;
    PdfReader reader = null;
    PdfReader.unethicalreading = true;
    MemoryStream streamPDF;
    try
    {
        reader = new PdfReader(OrigFile);
        streamPDF = new MemoryStream();
        stamper = new PdfStamper(reader, streamPDF);
        for (int i = 1; i <= reader.NumberOfPages; i++)
        {
            PdfGState gstate = new PdfGState();
            gstate.FillOpacity = gstate.StrokeOpacity = OpacityPercent / 100F;
            PdfContentByte overContent = stamper.GetOverContent(i);
            overContent.SaveState();
            overContent.SetGState(gstate);
            overContent.SetColorFill(BaseColor.RED);
            overContent.BeginText();
            BaseFont font = BaseFont.CreateFont(BaseFont.TIMES_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
            overContent.SetFontAndSize(font, PDFPaidFontSize);
            overContent.ShowTextAligned(PdfContentByte.ALIGN_LEFT, CopyStampTxt, PDFCopyX, PDFY, 0);
            overContent.ShowTextAligned(PdfContentByte.ALIGN_LEFT, PaidStampTxt, PDFPaidX, PDFY, 0);
            overContent.SetColorFill(BaseColor.BLACK);
            font = BaseFont.CreateFont(Path.Combine(FontPath, ArialFilename), BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
            overContent.SetFontAndSize(font, PDFDateFontSize);
            overContent.ShowTextAligned(PdfContentByte.ALIGN_LEFT, StampDate, PDFPaidX + PDFDateXOffset, PDFY - PDFDateYOffset, 0);
            overContent.EndText();
            overContent.RestoreState();
        }
    }
    finally
    {
        if (stamper != null)
        {
            stamper.Close();
        }
        if (reader != null)
        {
            reader.Close();
        }
    }
    byte[] pdf = streamPDF.ToArray();
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
    Response.Buffer = false;
    Response.Clear();
    Response.ClearContent();
    Response.ClearHeaders();
    Response.Charset = string.Empty;
    Response.ContentType = "application/pdf";
    Response.AddHeader("content-length", pdf.Length.ToString());
    Response.AddHeader("Content-Disposition", "inline;filename=test.pdf;");
    Response.BinaryWrite(pdf);
    Response.Close();
string StampDate=DateTime.Now.ToString(“MM/dd/yyyy”);
字符串FontPath=Server.MapPath(“/assets/Fonts”);
字符串OrigFile=Server.MapPath(“/test.pdf”);
常数不透明度=80;
常量浮点PDFPaidFontSize=28;
常量浮点PDFCopyX=170;
常量浮点PDFPaidX=385;
常数浮点PDFY=20;
常量浮点PDFDateXOffset=7;
常量浮点PDFDateYOffset=12;
常量浮点PDFDateFontSize=10;
const string PaidStampTxt=“已付款”;
常量字符串copyStampText=“复制”;
常量字符串ArialFilename=“arialbd.ttf”;
PdfStamper压模=null;
PdfReader reader=null;
PdfReader.unethicalreading=true;
MemoryStream streamPDF;
尝试
{
读卡器=新的PDF读卡器(原始文件);
streamPDF=新的MemoryStream();
压模=新的PdfStamper(读卡器,streamPDF);
对于(int i=1;i)首次尝试重现问题
我刚刚为这些值执行了您的代码:

        int OpacityPercent = 70;
        int PDFPaidFontSize = 20;
        string CopyStampTxt = "COPY";
        string PaidStampTxt = "PAID";
        int PDFCopyX = 100;
        int PDFPaidX = 250;
        int PDFY = 500;
        string FontPath = @"C:\Windows\Fonts";
        string ArialFilename = "ariali.ttf";
        int PDFDateFontSize = 30;
        string StampDate = "TODAY";
        int PDFDateXOffset = 0;
        int PDFDateYOffset = 35;
使用简单的源PDF,结果PDF如下所示:

与你的观察相反

生成的pdf文本是灰色而不是红色

生成的文本颜色为淡红色(白色上的部分透明红色)

我使用iTextSharp 5.5.5进行了测试

因此,要获得灰色而不是红色,变量值或源PDF必须有一些特殊之处,这不是一个一般问题

使用OP提供的文件复制问题 在首次尝试重现问题后,OP提供了一个示例文件,实际上,对于该文件,相同代码的结果是:

因此,确实存在一个问题

分析 两种情况下添加的内容流操作的比较显示:

  • 对于第一次尝试使用我的示例PDF:

    /Xi0 gs
    1 0 0 rg
    BT
    /Xi1 20 Tf
    1 0 0 1 100 500 Tm
    (COPY) Tj
    
  • 对于使用OP示例文件的第二次尝试:

    /Xi0 gs
    1 0 0 rg
    BT
    0 g
    /Xi1 20 Tf
    1 0 0 1 100 500 Tm
    (COPY) Tj
    
因此,尽管使用了相同的代码,在后一种情况下还有一个附加的
0g
操作,并且该操作选择黑色作为填充颜色

因此,我查看了iText代码和代码历史以获得解释(我选择了iText/Java代码,因为它是原始开发的地方,可以更彻底地检查更改)

实际上,
PdfContentByte.beginext
以以下内容结尾:

if (isTagged()) {
    try {
        restoreColor();
    } catch (IOException ioe) {

    }
}
背景 因此,在标记PDF的情况下,此方法“重置颜色”。为什么

查看代码历史记录会给出一些提示

  • 修订版5499标记的PDF支持:将图形和文本保留在一个画布中。尚未准备就绪

  • 修订版5515现在iText可以将文本和图形写入1个画布。为此,应将PdfDocument.puttextandgraphics设置为true

    这里,上面的块首先出现,略有不同

    if (autoControlTextBlocks) {
        try {
            restoreColor();
        } catch (IOException ioe) {
    
        }
    }
    
    i、 e.仅当
    autoControlTextBlocks
    true
    时,颜色才会恢复

  • 修订版5533 writer.istaged属性现在决定是将所有内容写入一个画布还是写入单独的画布

    这里,标志
    autoControlTextBlocks
    被相关写入程序的
    istaged
    调用所取代

我的解释是:

  • 为了正确地支持带标签的PDF,将图形和文本保存在一个画布中是必要的,或者至少是有利的(以前它们是在不同的画布中创建的,最终被连接在一起,因此相关的图形和文本在内容中彼此距离较远)

  • 为了使图形和文本在高级代码中保持在一起,并将开销降至最低,在
    PdfContentByte
    中添加了一个新的autoControlTextBlocks模式,可根据需要自动启动和停止文本对象,并保存和恢复文本的单独颜色集

  • 此模式似乎已被选为iText中支持标记内容的方式,但似乎对其他上下文没有用处。因此,此模式现在自动用于标记文件

在我看来,这种选择不是最优的。
PdfContentByte
是公开可用的iText API的一部分,它被公开宣传(称为“过度内容”),用于对生成的或预先存在的PDF进行低级调整。引入这种副作用违反了API合同,至少是阻碍人们升级的麻烦

变通 只需切换颜色设置和文本对象启动操作的顺序,使用

...
overContent.BeginText();
overContent.SetColorFill(BaseColor.RED);
...
导致

决议 如果我正确解释了最终签入,这个问题应该在iText版本5.5.6中解决

提交301a45b57dcef37ae0ec3625fbdd6caaf4004a3a


删除了PdfContentByte类(DEV-1371)中已标记pdf文档保存和恢复颜色的不推荐逻辑。

请显示更完整的代码示例,还包括文本绘图说明。编辑以显示完整的代码示例。“红色”代码为:overContent.SetColorFill(BaseColor.Red);乍一看还可以。但是,代码中有许多未知实体,尤其是源PDF和外部设置的许多值。因此,您能否完成示例以使其独立?或者至少提供一个示例输出PDF以进行分析?我认为这与源PDF属性有更大关系。我编辑以显示v可变值,以及在比较有效的pdf文件和无效的pdf文件时我可以确定的内容。您能否创建一个源文件来说明您可以共享的问题?非常感谢您的帮助!非常棒的深入分析!:O