目前我正在使用iText7版本8.0.4将jpg文件替换为svg文件。 我用 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();
}
我解决了我的问题如下:在 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);
.....
}