«Клавиша Print Screen отлично справляется со своей задачей.
Что может быть проще, чем сохранить документ в виде изображенияЭ» - ты спрашиваешь.
Долгое время работал над задачей сохранения отчетов и форм в формате PDF. Но даже с простыми многостраничными таблицами чисел не все генераторы PDF были одинаково успешными.
Не так давно я наткнулся на проект, заказчик которого хотел конвертировать свои маркетинговые шедевры, сохраненные в PDF, в один из графических форматов, например PNG. После долгих уговоров и контраргументов бюджет проекта позволил приобрести недорогой .
NET-компонент. Оставалось выбрать наиболее подходящий под требования заказчика и по возможности с хорошей англоговорящей, англопишущей службой поддержки (не с полуострова Индостан):
Требования к конвертерам PDF
Основное внимание было уделено таким возможностям конвертера, как:- Простота API, в том числе для настройки шрифтов (помимо встроенных шрифтов должна быть возможность добавить недостающий системный шрифт или ссылку на него)
- Возможность экспорта в форматы TIFF, PNG, JPEG, BMP.
- Поддержка прозрачных изображений внутри PDF-документа.
- Поддержка цветовой маски
- Поддержка азиатских шрифтов
- Аннотации необходимо конвертировать вместе с документом (эту опцию можно отключить)
- Различные режимы смешивания
- Различные узоры плитки
- Различные цветовые пространства RGB, CMYK, Gray, DeviceN
- Прозрачные группы для документов, созданных с помощью Adobe Illustrator.
NET-компонентов:
ABCpdf | 6.1.1.5 |
Adobe Acrobat (Interop.Acrobat) | Библиотека типов Adobe Acrobat 10.0 |
Апитрон.
PDF.Растеризатор |
3.0.1.0 |
O2S.Components.PDFRender4NET | 4.5.1.0 |
PDFLibNET | |
PDFSharp | 1.31.1789.0 |
SautinSoft.PdfFocus | 2.2.2.2 |
TallComponents.PDF.Rasterizer | 3.0.91.0 |
Начало тестирования
Для тестовых целей был выбран одностраничный PDF-файл 3BigPreview.pdf (взято с официального сайта Adobe).Он включает в себя большое количество графических элементов, демонстрирующих возможности визуализации компонентов графических объектов PDF и их свойств.
ABCPDF
Сразу запустить пример для этой библиотеки на 64-битной машине не удалось; только сменой платформы с AnyCPU на x86 был получен результат. Проблема возникла с установкой правильного разрешения картинки.Получить изображение правильного размера 612 х 792 пикселей удалось только явно задав разрешение результирующего изображения 72 dpi, что странно, так как другие компоненты выставили его 96dpi (для Win7).
Правильное отображение иероглифов Кинсоку Сёри довольный.
Некоторые буквы выглядят ярче других, что говорит о том, что сглаживание использовалось не совсем добросовестно.
Результат хорош для тех, кого не волнует, что они не используют 100% управляемый код, но мы идем дальше.
Фрагмент кода для ABCpdf:
Результат:public static void ConvertPDFToImage(string pdfInputPath, string imageOutputPath, string imageName, ImageFormat imageFormat) { FileStream fs = new FileStream(pdfInputPath, FileMode.Open); Doc document = new Doc(); document.Read(fs); document.Rendering.DotsPerInch = 72; document.Rendering.DrawAnnotations = true; document.Rendering.AntiAliasImages = true; document.Rect.String = document.CropBox.String; document.Rendering.Save(Path.ChangeExtension(Path.Combine(imageOutputPath ,imageName), imageFormat.ToString())); }
Библиотека типов Adobe Acrobat 10.0
Легко заметить, что родная библиотека Adobe является фаворитом.
Но вызов com-объектов — это не совсем то, что нам хотелось, тем более, что для этого требуется установленная версия продукта Pro.
Фрагмент кода для Adobe: public static void ConvertPDFToImage(string pdfInputPath, string imageOutputPath, string imageName, ImageFormat imageFormat)
{
CAcroPDDoc pdfDoc = (CAcroPDDoc) Interaction.CreateObject("AcroExch.PDDoc", "");
pdfDoc.Open(pdfInputPath);
CAcroPDPage pdfPage = (CAcroPDPage) pdfDoc.AcquirePage(0);
CAcroPoint pdfPoint = (CAcroPoint) pdfPage.GetSize();
CAcroRect pdfRect = (CAcroRect) Interaction.CreateObject("AcroExch.Rect", "");
pdfRect.Left = pdfRect.Top = 0;
pdfRect.right = pdfPoint.x;
pdfRect.bottom = pdfPoint.y;
pdfPage.CopyToClipboard(pdfRect, 0, 0, 100);
IDataObject clipboardData = Clipboard.GetDataObject();
if (clipboardData.GetDataPresent(DataFormats.Bitmap))
{
using(Bitmap pdfBitmap = (Bitmap) clipboardData.GetData(DataFormats.Bitmap))
{
pdfBitmap.Save(Path.ChangeExtension(Path.Combine(imageOutputPath, imageName), imageFormat.ToString()), imageFormat);
}
}
pdfDoc.Close();
Marshal.ReleaseComObject(pdfPage);
Marshal.ReleaseComObject(pdfRect);
Marshal.ReleaseComObject(pdfDoc);
Marshal.ReleaseComObject(pdfPoint);
}
Результат:
Apitron.PDF.Растеризатор для .
NET Компонент показал хорошие результаты в тестовых испытаниях.
Удобный API, есть возможность настроить шрифты и отключить отрисовку аннотаций.
Изображение выглядит четким.
Рисуются все элементы исходного PDF-документа.
Я заметил, что при конвертации документа были задействованы все восемь ядер рабочей машины, скорее всего это будет удобно для тех, кто хочет повысить производительность приложения за счет увеличения оперативной памяти и количества процессоров рабочей системы.
Кусок кода для Апитрона: public static void ConvertPDFToImage(string pdfInputPath, string imageOutputPath, string imageName, ImageFormat imageFormat)
{
FileStream fs = new FileStream(pdfInputPath, FileMode.Open);
Document doc = new Apitron.PDF.Rasterizer.Document(fs);
RenderingSettings option = new RenderingSettings();
option.DrawAnotations = true;
doc.Pages[0].
Render((int) doc.Pages[0].
Width, (int) doc.Pages[0].
Height, option).
Save(Path.ChangeExtension(Path.Combine(imageOutputPath, imageName), imageFormat.ToString()), imageFormat);
}
Результат:
O2S.Components.PDFRender4NET
Румынский компонент выполнил тестовые испытания удовлетворительно.Не все элементы документа сохраняются корректно.
Как видно из полученного файла, поддерживаются все элементы спецификации.
Есть явные проблемы с отрисовкой текста.
Фрагмент кода для O2S: public static void ConvertPDFToImage(string pdfInputPath, string imageOutputPath, string imageName, ImageFormat imageFormat)
{
PDFFile pdfFile = O2S.Components.PDFRender4NET.PDFFile.Open(pdfInputPath);
using (Bitmap pageImage = pdfFile.GetPageImage(0, 300))
{
pageImage.Save(Path.ChangeExtension(Path.Combine(imageOutputPath, imageName), imageFormat.ToString()), imageFormat);
}
}
Результат:
Библиотека оболочки xPDF (PDFLibNET)
Генерация тестового набора не удалась.Изображение выглядит размытым, а текст нечитабельным.
Мы получили ошибки при преобразовании тестового файла.
Фрагмент кода для PDFLibNET: public static void ConvertPDFToImage(string pdfInputPath, string imageOutputPath, string imageName, ImageFormat imageFormat)
{
PDFWrapper pdfWrapper = new PDFWrapper();
pdfWrapper.LoadPDF(pdfInputPath);
pdfWrapper.ExportJpg(Path.ChangeExtension(Path.Combine(imageOutputPath, imageName), imageFormat.ToString()), 10);
pdfWrapper.Dispose();
}
Результат:
PDFSharp (GhostScript и другие оболочки)
PDFSharp, как и другие оболочки известного инструмента GhostScript (например, gouda, GhostscriptSharp), работает специфично и не всегда предсказуемо.Потратив несколько часов времени, мне удалось извлечь только картинки; Мне не удалось сохранить весь документ в виде изображения.
Отмечу это как хорошую идею для новой статьи.
Также здесь можно упомянуть всеми любимый iTextSharp. Удобный инструмент, но не для нашей задачи.
PdfFocus от SautinSoft
Мой обзор включал и бытовую составляющую.Но, к сожалению, испытания он провалил.
В тестовом файле возникла ошибка NRE. Но с другими файлами он работал хорошо.
(Автору: «Максим, я уверен, что у вас отличный софт и эту мелочь быстро исправят.»)
Кусок кода для SautinSoft: public static void ConvertPDFToImage(string pdfInputPath, string imageOutputPath, string imageName, ImageFormat imageFormat)
{
PdfFocus pdfFocus = new PdfFocus();
pdfFocus.OpenPdf(pdfInputPath);
pdfFocus.ImageOptions.Dpi = 96;
pdfFocus.ImageOptions.ImageFormat = imageFormat;
using (Image bitmap = pdfFocus.ToDrawingImage(1))
{
bitmap.Save(Path.ChangeExtension(Path.Combine(imageOutputPath, imageName), imageFormat.ToString()), imageFormat);
}
pdfFocus.ClosePdf();
}
TallComponents.PDF.Rasterizer
Голландский компонент хорошо показал себя в тестовых испытаниях.Сложность конкретного API компенсировалась базовыми знаниями в области графики.
Есть небольшие проблемы с отрисовкой текста.
Кусок кода для TallComponents: public static void ConvertPDFToImage(string pdfInputPath, string imageOutputPath, string imageName, ImageFormat imageFormat)
{
FileStream fs = new FileStream(pdfInputPath, FileMode.Open);
Document document = new Document(fs);
Page page = document.Pages[0];
RenderSettings renderSettings = new RenderSettings();
renderSettings.GdiSettings.WorkAroundImageTransparencyPrintSize = true;
using (Bitmap bitmap = new Bitmap((int) page.Width, (int) page.Height))
{
using (Graphics graphics = Graphics.FromImage(bitmap))
{
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.Clear(Color.White);
page.Draw(graphics, renderSettings);
}
bitmap.Save(Path.ChangeExtension(Path.Combine(imageOutputPath, imageName), imageFormat.ToString()), imageFormat);
}
}
Результат:
Нижняя граница
Сохранение PDF-документов в изображения BMP, JPEG, TIFF – не такая тривиальная задача, как может показаться на первый взгляд. Программных утилит, библиотек и коммерческих сервисов, а также их условно-бесплатных аналогов можно найти множество, но небольшому стартапу не обойтись без надежных сторонних компонентов.Проанализировав результаты, перечитав документацию, примеры кода и цены на сайтах, я выбрал компонент для своего проекта.
По производительности все библиотеки находятся на одном уровне, возможно, из-за особенностей чтения PDF-документа в один поток.
При выборе я не учел возможность использования продуктов на мобильных устройствах, так как не все компоненты из-за ограничений GDI+ смогут корректно работать под платформой Android или совместимы с Mono.Xamarin. Теги: #pdf #PDF в img #C++ #pdf
-
Ноутбук Dell Studio 15
19 Oct, 24 -
Кейс: Создание Лендинга Для Киви
19 Oct, 24 -
Остерегайтесь Фишинга Firstvds
19 Oct, 24 -
Xss-Уязвимость В Mobli
19 Oct, 24 -
Конкурс Дудлов Для Google До 12 Апреля.
19 Oct, 24 -
Второй Пузырь Доткомов Или Новая Эра?
19 Oct, 24