使用 Windows 10+“打印到 PDF”选项时 PDF 水印会翻转

问题描述 投票:0回答:1

我正在使用 Windows 10 或更高版本中的

Print to PDF
功能生成带水印的 PDF,但我遇到了打印或查看时水印翻转或出现镜像的问题。我正在使用 iText7 库向 PDF 添加水印,以下代码用于水印生成:

try
{
    using var inputStream = new MemoryStream(pdfBytes);
    using var outputStream = new MemoryStream();

    var writerProperties = password != null ? CreateEncryptedWriterProperties(password) : new WriterProperties();

    using var reader = new PdfReader(inputStream);
    using var writer = new PdfWriter(outputStream, writerProperties);
    using var document = new PdfDocument(reader, writer);

    var pageCount = document.GetNumberOfPages();
    for (int i = 1; i <= pageCount; i++)
    {
        var page = document.GetPage(i);
        var canvas = new PdfCanvas(page.NewContentStreamAfter(), page.GetResources(), document);
        DrawWatermark(canvas, watermarkText, document, page);
    }

    document.Close();
    return outputStream.ToArray();
}
catch (Exception ex)
{
    _logger?.LogError(ex, "Error watermarking PDF bytes");
    return null;
}

private void DrawWatermark(PdfCanvas canvas, string watermarkText, PdfDocument document, PdfPage page)
    {
        var pageSize = page.GetPageSize();
        var (pageWidth, pageHeight) = (pageSize.GetWidth(), pageSize.GetHeight());

        var dateText = _options.IncludeDate ? DateTime.Now.ToString(_options.DateFormat) : string.Empty;
        var font = string.IsNullOrEmpty(_options.FontPath) ? PdfFontFactory.CreateFont() : PdfFontFactory.CreateFont(_options.FontPath);

        var position = CalculateWatermarkPosition(watermarkText, dateText, pageWidth, pageHeight, _options.FontSize, font);

        ApplyWatermark(canvas, watermarkText, dateText, position, font, pageWidth, pageHeight);
    }

    private (float TextX, float TextY, float DateX, float DateY, float TextWidth, float DateWidth) CalculateWatermarkPosition(
        string watermarkText,
        string dateText,
        float pageWidth,
        float pageHeight,
        float fontSize,
        PdfFont font)
    {
        var textWidth = (font.GetWidth(watermarkText) * fontSize) / 1000;
        var dateWidth = (font.GetWidth(dateText) * (fontSize / 2)) / 1000;

        var centerX = pageWidth / 2f;
        var centerY = pageHeight / 2f;

        float verticalSpacing = fontSize / 4;

        return (
            TextX: centerX - textWidth / 2f,
            TextY: centerY,
            DateX: centerX - dateWidth / 2f,
            DateY: centerY - fontSize - verticalSpacing,
            TextWidth: textWidth,
            DateWidth: dateWidth
        );
    }
private void ApplyWatermark(
    PdfCanvas canvas,
    string watermarkText,
    string dateText,
    (float TextX, float TextY, float DateX, float DateY, float TextWidth, float DateWidth) position,
    PdfFont font,
    float pageWidth,
    float pageHeight)
{
    var centerX = pageWidth / 2f;
    var centerY = pageHeight / 2f;
    var angleInRadians = (float)(_options.RotationAngle * Math.PI / 180);

    canvas.SaveState();

    var gs = new PdfExtGState().SetFillOpacity(_options.Opacity);
    canvas.SetExtGState(gs);

    canvas.BeginText()
        .SetFontAndSize(font, _options.FontSize)
        .SetFillColor(_options.Color)
        .SetTextRenderingMode(PdfCanvasConstants.TextRenderingMode.FILL_STROKE);

    var cosAngle = (float)Math.Cos(angleInRadians);
    var sinAngle = (float)Math.Sin(angleInRadians);

    var tx = position.TextX - centerX;
    var ty = position.TextY - centerY;

    var finalX = centerX + (tx * cosAngle - ty * sinAngle);
    var finalY = centerY + (tx * sinAngle + ty * cosAngle);

    canvas.SetTextMatrix(
        cosAngle, sinAngle,
        -sinAngle, cosAngle,
        finalX, finalY
    )
    .ShowText(watermarkText);

    canvas.EndText()
        .RestoreState();
}

此问题似乎仅发生在使用 Windows 10 或更高版本的“打印到 PDF”功能生成的 PDF 中。通过其他方式生成的 PDF 不会出现此问题。
flipped watermark
normal pdf

c# itext itext7
1个回答
0
投票

你使用

var canvas = new PdfCanvas(page.NewContentStreamAfter(), page.GetResources(), document);

构建

PdfCanvas

考虑使用

var canvas = new PdfCanvas(page, true);

相反。

bool
参数值
true
使iText将现有内容包装在保存图形状态/恢复图形状态信封中。

© www.soinside.com 2019 - 2024. All rights reserved.