如何使用PDFsharp将动态生成的位图插入PDF文档中

本文关键字:插入 位图 PDF 文档 PDFsharp 何使用 动态 | 更新日期: 2023-09-27 17:55:39

我正在尝试使用PDFsharp将动态生成的QR码位图插入PDF文档中。 我不想将位图保存到文件中,而只想将其插入到 PDF 中。 我遇到的问题是 DrawImage 命令正在寻找图像文件所在的字符串。但我不想保存文件,我只想将其插入到 PDF 文档中。有没有办法做到这一点?

var QRCode_BMP = _generalCode.QR_CodeGenerator(AddReviewPath); //This generates the bitmap
MemoryStream streamQR = new MemoryStream();
QRCode_BMP.Save(streamQR, System.Drawing.Imaging.ImageFormat.Jpeg); //save bitmap into memory stream in jpeg format System.Drawing.Image QR_Jpeg = System.Drawing.Image.FromStream(streamQR);// save memory stream to image file
XImage xImage = XImage.FromGdiPlusImage(QR_Jpeg);
gfx = XGraphics.FromPdfPage(page);
DrawImage(gfx, xImage, 0, 0, 100, 100); //This is not working
QRCode_BMP.Dispose();
streamQR.Close();
gfx.Dispose();

如何使用PDFsharp将动态生成的位图插入PDF文档中

这就是我让它工作的方式;

        PdfDocument pdf = PdfGenerator.GeneratePdf("<b>some html here</b>", PageSize.A4);
        QRCodeGenerator qrGenerator = new QRCodeGenerator();
        QRCodeData qrCodeData = qrGenerator.CreateQrCode("some text here", QRCodeGenerator.ECCLevel.Q);
        QRCode qrCode = new QRCode(qrCodeData);
        Bitmap qrCodeImage = qrCode.GetGraphic(10);

        PdfPage page = pdf.Pages[0]; //I will add it to 1st page
        // Get an XGraphics object for drawing
        XGraphics gfx = XGraphics.FromPdfPage(page);
        XImage image = XImage.FromGdiPlusImage(qrCodeImage); //you can use XImage.FromGdiPlusImage to get the bitmap object as image (not a stream)
        gfx.DrawImage(image, 50, 50, 150, 150);
//save your pdf, dispose other objects

您在QRCode_BMP中创建了一个QR码,然后从QR_Jpeg创建了一个XImage并编写它不起作用。

QRCode_BMP仅用于创建从未使用的流。我们看不出QR_Jpeg来自哪里。

提供完整的示例。

顺便说一句:您可以使用XImage.FromStream来使用您创建的流。

PS:恕我直言,JPEG 是二维码的糟糕选择。只需使用BMP,PDFsharp将使用无损压缩。

使用像@I喜欢提到的旧堆栈溢出这样的XImage.FromStream,在您发布的代码中,您应该能够只使用:

var QRCode_BMP = _generalCode.QR_CodeGenerator(AddReviewPath); //This generates the bitmap
MemoryStream streamQR = new MemoryStream();
QRCode_BMP.Save(streamQR, System.Drawing.Imaging.ImageFormat.Jpeg); //save bitmap into memory stream in jpeg format System.Drawing.Image QR_Jpeg = System.Drawing.Image.FromStream(streamQR);// save memory stream to image file
//XImage xImage = XImage.FromGdiPlusImage(QR_Jpeg); // <-- Removed
gfx = XGraphics.FromPdfPage(page);
gfx.DrawImage(XImage.FromStream(streamQR), 0, 0, 100, 100); // <-- Added
//DrawImage(gfx, xImage, 0, 0, 100, 100); //This is not working // <-- Removed
QRCode_BMP.Dispose();
streamQR.Close();
gfx.Dispose();

对于XGraphics.DrawImage流的一般用法(库 PDFSharp),以下是我用于将 SVG 矢量路径数据打印为 PDF 的一些代码:

System.Windows.Shapes.Path path = new System.Windows.Shapes.Path();
// YouTube like button SVG vector path data:
path.Data = Geometry.Parse("M12.42,14A1.54,1.54,0,0,0,14,12.87l1-4.24C15.12,7.76,15,7,14,7H10l1.48-3.54A1.17,1.17,0,0,0,10.24,2a1.49,1.49,0,0,0-1.08.46L5,7H1v7ZM9.89,3.14A.48.48,0,0,1,10.24,3a.29.29,0,0,1,.23.09S9,6.61,9,6.61L8.46,8H14c0,.08-1,4.65-1,4.65a.58.58,0,0,1-.58.35H6V7.39ZM2,8H5v5H2Z");
// Visual check of the path:
// https://yqnn.github.io/svg-path-editor/
// Color area bordered through path of SVG vector:
path.Fill = new SolidColorBrush(Colors.Black);
// Upscale path, if final image is blurry:
double scale = 2;
path.RenderTransform = new ScaleTransform(scale, scale);
Rect bounds = path.Data.GetRenderBounds(null);
// Increase render bounds (here: "+ 4"), if parts of the path in the final image are cut off (test it with "scale = 1" before upscaling):
bounds.Width = (bounds.Width + 4) * scale;
bounds.Height = (bounds.Height + 4) * scale;
path.Measure(bounds.Size);
path.Arrange(bounds);
RenderTargetBitmap bitmap = new RenderTargetBitmap(
    (int)bounds.Width, (int)bounds.Height, 96, 96, PixelFormats.Pbgra32);
bitmap.Render(path);
// Transparent areas are replaced with black pixels when using a "BmpBitmapEncoder", so instead use a "PngBitmapEncoder":
PngBitmapEncoder encoderPng = new PngBitmapEncoder();
encoderPng.Frames.Add(BitmapFrame.Create(bitmap));
using (MemoryStream stream = new MemoryStream())
{
    encoderPng.Save(stream);
    
    // Draw image to PDF using "XGraphics.DrawImage":
    gfx.DrawImage(XImage.FromStream(stream), 10, 100, 14.05, 12.05);
}