为什么将 SVG 添加到 pdf 时字体会发生变化?

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

目前我正在使用iText7版本8.0.4将jpg文件替换为svg文件。 enter image description here 我用 svg 图像替换了 jpg 图像,但问题是我的第二个屏幕截图中的字体是错误的,我在 svg 文件中使用的字体是“Lucida Console”,但是当我替换 svg 文件时,它会更改为该字体。 “时间新罗马”。当 svg 文件保存在我的计算机上时,它仍然可以正确显示,只是当我将其添加到 pdf 时,它的字体错误

这是我的.net 代码:

public bool ReplaceImageWithSvg(string inputPdf, string outputPdf)
{
    try
    {
        using (PdfReader pdfReader = new PdfReader(inputPdf))
        using (PdfWriter pdfWriter = new PdfWriter(outputPdf))
        using (PdfDocument pdfDocument = new PdfDocument(pdfReader, pdfWriter))
        {
            int numPages = pdfDocument.GetNumberOfPages();
            string tempPath = System.IO.Path.GetTempPath();

            for (int pageNum = 1; pageNum <= numPages; pageNum++)
            {
                PdfPage page = pdfDocument.GetPage(pageNum);

                IList<PdfAnnotation> annotations = new List<PdfAnnotation>(page.GetAnnotations());

                foreach (PdfAnnotation annotation in annotations)
                {
                    if (annotation.GetSubtype().Equals(PdfName.Link))
                    {
                        PdfLinkAnnotation linkAnnotation = (PdfLinkAnnotation)annotation;

                        // Check if the link annotation is associated with an image
                        PdfArray rect = linkAnnotation.GetRectangle();
                        if (rect != null && rect.Size() == 4)
                        {
                            var tempSvgFile = System.IO.Path.Combine(tempPath, Guid.NewGuid().ToString() + ".svg");
                            var imageUrl = ExtractURL(linkAnnotation.GetAction().ToString());

                            var svgContent = FetchSvgImageAsync(imageUrl);

                            var imageStream = ModifySvgFontAttributes(svgContent, _newFontFamily, _increaseFontSizeBy, _increaseFontWeight, _newStrokeWidth);

                            SaveSvgToFile(imageStream, tempSvgFile);

                            ReplaceImageWithSvg(page, rect, tempSvgFile);

                            page.RemoveAnnotation(linkAnnotation);

                            if (File.Exists(tempSvgFile))
                            {
                                File.Delete(tempSvgFile);
                            }
                        }
                    }
                }
            }
        }

        return true;
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error replacing image with SVG: {ex.Message}");
        return false;
    }
}

private void ReplaceImageWithSvg(PdfPage page, PdfArray rect, string svgImagePath)
{
    try
    {
        // Extract position and dimensions of the existing image
        float x = rect.GetAsNumber(0).FloatValue();
        float y = rect.GetAsNumber(1).FloatValue();
        // Added on to get rid of the border
        float width = rect.GetAsNumber(2).FloatValue() - x + _border;
        float height = rect.GetAsNumber(3).FloatValue() - y + _border;


        // Convert the SVG image to PdfFormXObject
        PdfDocument pdfDoc = page.GetDocument();
        using (Stream svgStream = File.OpenRead(svgImagePath))
        {
            PdfFormXObject svgObject = SvgConverter.ConvertToXObject(svgStream, pdfDoc);

            // Get the content stream of the page
            PdfCanvas canvas = new PdfCanvas(page);
            // Set fill color to white(or match the page background)
            canvas.SetFillColorGray(1.0f); // White color
            // Cover the area with a rectangle
            canvas.Rectangle(x, y, width, height);
            canvas.Fill();

            // Calculate the scale to fit the SVG in the specified rectangle
            // Assumes the SVG's aspect ratio matches the target rectangle.
            float scaleX = width / svgObject.GetWidth();
            float scaleY = height / svgObject.GetHeight();

            // Create transformation matrix for scaling and then translating the image
            float[] matrix = new float[] { scaleX, 0, 0, scaleY, x, y };

            // Add the SVG Form XObject to the canvas with transformation
            canvas.AddXObjectWithTransformationMatrix(svgObject, matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error replacing image with SVG: {ex.Message}");
    }
}

private string ModifySvgFontAttributes(string svgContent, string newFontFamily, string fontSizeIncrease, int fontWeightIncrease, string strokeWidth)
{
    XDocument svgDoc = XDocument.Parse(svgContent);

    // Update font-family
    var elementsWithFontFamily = svgDoc.Descendants().Where(e => e.Attribute("font-family") != null);
    foreach (var elem in elementsWithFontFamily)
    {
        elem.SetAttributeValue("font-family", newFontFamily);
    }

    return svgDoc.ToString();
}
svg itext itext7
1个回答
0
投票

我解决了我的问题如下:在 ReplaceImageWithSvg 函数中,我添加了 front 属性。代码如下:

using (Stream svgStream = File.OpenRead(svgImagePath))
{
    string fontPath = "LUCON.TTF";
    var provider = new FontProvider();
    FontProgram fontProgram = FontProgramFactory.CreateFont(fontPath);
    var props = new SvgConverterProperties();

    provider.AddFont(fontProgram);
    props.SetFontProvider(provider);

    PdfFormXObject svgObject = SvgConverter.ConvertToXObject(svgStream, pdfDoc, props);

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