Вопрос или проблема
Как нарисовать изображение, загруженное из IFormFile с помощью PDFSharp?
У меня есть IFormFile, который отправляется в контроллер, и я хочу отобразить изображение в PDF, который я создаю с помощью PDFSharp.
В настоящее время я использую это для попытки отрисовать изображение:
GlobalFontSettings.FontResolver = new FontResolver();
var document = new PdfDocument();
var page = document.AddPage();
var gfx = XGraphics.FromPdfPage(page);
var font = new XFont("Arial", 20, XFontStyle.Bold);
var textColor = XBrushes.Black;
var layout = new XRect(20, 20, page.Width, page.Height);
var format = XStringFormats.Center;
gfx.DrawString("Hello World!", font, textColor, layout, format);
if(campaign.BrandLogo != null)
{
var image = XImage.FromStream(campaign.BrandLogo.OpenReadStream);
gfx.DrawImage(image, 10, 10, 100, 100);
}
MemoryStream stream = new MemoryStream();
document.Save(stream, false);
..где campaign.BrandLogo
является IFormFile
Однако, когда я открываю сгенерированный PDF, я получаю ошибку о том, что документ поврежден, т.е. изображение не отображается.
Мне трудно понять, как прочитать загруженное изображение из потока памяти и правильно отобразить его в PDF. Кто-нибудь может помочь?
Ответ или решение
Для корректного рендеринга изображения из IFormFile в PDF с использованием библиотеки PDFSharp, необходимо убедиться, что поток изображения правильно считывается и используется в качестве источника для объекта XImage. Давайте рассмотрим пример кода, который показывает, как это сделать.
Предположим, что у вас есть контроллер, принимающий IFormFile. Ниже представлено полное решение:
using System.IO;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using PdfSharp.Drawing;
using PdfSharp.Pdf;
public class PdfController : Controller
{
[HttpPost]
public IActionResult GeneratePdf(IFormFile brandLogo)
{
if (brandLogo == null || brandLogo.Length == 0)
{
return BadRequest("Изображение не загружено.");
}
// Создание нового PDF документа
var document = new PdfDocument();
var page = document.AddPage();
var gfx = XGraphics.FromPdfPage(page);
var font = new XFont("Arial", 20, XFontStyle.Bold);
// Рисуем текст на странице
var textColor = XBrushes.Black;
var layout = new XRect(20, 20, page.Width, page.Height);
var format = XStringFormats.Center;
gfx.DrawString("Hello World!", font, textColor, layout, format);
// Рендерим изображение, если оно загружено
if (brandLogo != null && brandLogo.Length > 0)
{
using (var stream = new MemoryStream())
{
brandLogo.CopyTo(stream); // Копируем файл в поток
stream.Position = 0; // Сбрасываем позицию потока на начало
var image = XImage.FromStream(stream); // Создаем XImage из потока
gfx.DrawImage(image, 10, 10, 100, 100); // Рисуем изображение на PDF страницах
}
}
// Сохранение PDF документа в поток
using (var memoryStream = new MemoryStream())
{
document.Save(memoryStream, false);
byte[] pdfBytes = memoryStream.ToArray();
return File(pdfBytes, "application/pdf", "document.pdf");
}
}
}
Объяснение кода:
-
Проверка файла: Перед выполнением основного кода необходимо проверить, что файл изображения загружен и его размер больше нуля.
-
Создание PDF-документа: Создаётся новый экземпляр
PdfDocument
, и на него добавляется новая страница. -
Отрисовка текста: Пример показывает, как отрисовать текст "Hello World!" на PDF-странице с использованием заданного шрифта.
-
Работа с изображением:
- Сначала создается
MemoryStream
, в который загружается содержимоеIFormFile
с помощью методаCopyTo()
. - Позиция потока сбрасывается на начало, чтобы
XImage.FromStream()
мог считать данные с самого начала. - Затем изображение отрисовывается на странице с помощью метода
gfx.DrawImage()
.
- Сначала создается
- Сохранение PDF: PDF сохраняется в
MemoryStream
, после чего его содержимое отправляется обратно клиенту в виде файла PDF.
Заключение
Убедитесь, что вы правильно обрабатываете загрузку изображений и не забывайте управлять потоками (например, правильно сбрасывать их позицию). Данная реализация предоставляет способ получить PDF-документ с рендерингом загруженного изображения без ошибок.