Как вставить динамически генерируемое растровое изображение в PDF-документ с помощью PDFsharp?

Я пытаюсь использовать 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();

3 ответа

Вы создаете QR-код в QRCode_BMP а затем вы создаете XImage из QR_Jpeg и написать это не работает.

QRCode_BMP используется только для создания потока, который никогда не используется. Мы не видим где QR_Jpeg идет от.

Предоставьте полный образец.

Кстати: вы можете использовать XImage.FromStream использовать поток, который вы создали.

PS: IMHO JPEG - плохой выбор для QR-кодов. Просто используйте BMP и PDFsharp будет использовать сжатие без потерь.

Вот как я заставил это работать;

        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

С использованиемXImage.FromStreamнапример user162529 , в опубликованном коде вы должны просто использовать:

      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);
}
Другие вопросы по тегам