pdf - 如何提高从 PDF 生成的图像的质量?
问题描述
我们使用TYPO3 9.5.13
, GraphicsMagick 1.3.29
, Ghostscript 9.27
,BK2K\\BootstrapPackage 11.0.1
使用 PDF 作为普通图像没有问题。
但现在我想要一个完整列宽(~1000px)的 PDF 的“预览”。尽管 PDF 具有高分辨率,但生成的图像宽度仅为 595 像素,任何文本几乎都无法阅读。
像上传 CE 中的图像 CE 会出现问题,我想增强它:
每次我想要使用完整列宽的图像时,它都会以错误的分辨率呈现,并且图像似乎失真。
流体部分:
<img loading="lazy"
src="{f:uri.image(image: file, cropVariant: 'default', maxWidth: 1100)}"
width="{bk2k:lastImageInfo(property: 'width')}"
height="{bk2k:lastImageInfo(property: 'height')}"
intrinsicsize="{bk2k:lastImageInfo(property: 'width')}x{bk2k:lastImageInfo(property: 'height')}"
title="{file.properties.title}"
alt="{file.properties.alternative}">
结果如下:
<img loading="lazy"
src="/fileadmin/_processed_/3/2/csm_Warum_D-Arzt_6afd8ad8d4.png"
intrinsicsize="595x842"
title=""
alt=""
width="595"
height="842">
编辑:
如果使用此 FLUID:
<img loading="lazy"
src="{f:uri.image(image: file, cropVariant: 'default', width: 1100)}"
width="{bk2k:lastImageInfo(property: 'width')}"
height="{bk2k:lastImageInfo(property: 'height')}"
intrinsicsize="{bk2k:lastImageInfo(property: 'width')}x{bk2k:lastImageInfo(property: 'height')}"
title="{file.properties.title}"
alt="{file.properties.alternative}">
我得到:
<img loading="lazy"
src="/fileadmin/_processed_/3/2/csm_Warum_D-Arzt_2ffb63b15f.png"
intrinsicsize="1100x1557"
title=""
alt=""
width="1100"
height="1557">
图像更大(并且溢出容器)但质量更差,请注意更大的像素:
解决方案
实际上,PDF不是图像。它是一种容器格式,可以包含具有不同色彩空间和尺寸的矢量和图像。位图图像具有固定的尺寸宽度、高度、密度,而 PDF 则没有。最初,它是为打印机而不是屏幕而创建和优化的。
恕我直言,没有完美的方法可以处理 PDF 以表现得像图像,因为您知道输出格式,但不知道输入格式(正确)。获得可接受结果的两种方法:
- 扩展内容元素或创建新元素并为 PDF 预览图像添加第二个图像槽。使用图形程序自己创建预览图像。
- 编写自己的视图助手并创建自己的缩略图
解决方案 1 将为编辑带来更多工作。对我来说不是最佳实践。
我会使用自己的viewhelper。
为 PDF 添加您自己的渲染类型:
<f:switch expression="{file.type}">
<f:case value="5">
<f:render partial="Media/Type/Pdf" arguments="{file: file, dimensions: dimensions, data: data, settings: settings}" />
</f:case>
<f:defaultCase>
<f:render partial="Media/Type/Image" arguments="{file: file, dimensions: dimensions, data: data, settings: settings}" />
</f:defaultCase>
</f:switch>
部分媒体/类型/Pdf
{namespace cv=Conversion\HelperUtils\ViewHelpers}
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:ce="http://typo3.org/ns/TYPO3/CMS/FluidStyledContent/ViewHelpers" data-namespace-typo3-fluid="true">
<cv:forEachPdfThumbnail document="{file}" pages="1" as="pdfPreviewPage">
<f:image src="{pdfPreviewPage}" alt="" />
</cv:forEachPdfThumbnail>
</html>
查看助手:
这个viewhelper 使用CommandUtility::imageMagickCommand 从PDF 转换多个页面。您可以将密度提高到更高的值以提高质量。如前所述,这个viewhelper是几年前开发的,可以改进(例如保存到fileadmin/处理而不是typo3temp。随意克隆和改进:https ://github.com/conversion1/t3-pdfthumbnailviewhelper/blob/master /ForEachPdfThumbnailViewHelper.php
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
$templateVariableContainer = $renderingContext->getVariableProvider();
/** @var \TYPO3\CMS\Core\Resource\FileReference $document */
$document = $arguments['document'];
$pages = explode(',', str_replace(' ', '', $arguments['pages']));
$colorspace = TRUE === isset($GLOBALS['TYPO3_CONF_VARS']['GFX']['colorspace']) ? $GLOBALS['TYPO3_CONF_VARS']['GFX']['colorspace'] : 'RGB';
$absFilePath = GeneralUtility::getFileAbsFileName($document->getOriginalFile()->getPublicUrl());
$destinationPath = 'typo3temp/';
$destinationFilePrefix = 'pdf-prev_' . $document->getOriginalFile()->getNameWithoutExtension();
$destinationFileExtension = 'png';
$output = '';
foreach ($pages as $pageNumber) {
if($pageNumber > 0) {
$pageNumber = intval($pageNumber);
} else {
$pageNumber = 1;
}
$destinationFileSuffix = '_page-' . $pageNumber;
$absDestinationFilePath = GeneralUtility::getFileAbsFileName($destinationPath . $destinationFilePrefix . $destinationFileSuffix . '.' . $destinationFileExtension);
$imgArguments = '-colorspace ' . $colorspace;
$imgArguments .= ' -density 300';
$imgArguments .= ' -sharpen 0x.6';
$imgArguments .= ' "' . $absFilePath . '"';
$imgArguments .= '['. intval($pageNumber - 1) .']';
$imgArguments .= ' "' . $absDestinationFilePath . '"';
if(!file_exists($absDestinationFilePath)) {
$command = CommandUtility::imageMagickCommand('convert', $imgArguments);
CommandUtility::exec($command);
}
$thumbnail = substr($absDestinationFilePath, strlen(Environment::getPublicPath()));
$templateVariableContainer->add($arguments['as'], $thumbnail);
$output .= $renderChildrenClosure();
$templateVariableContainer->remove($arguments['as']);
}
return $output;
}
编辑:
第三种方式:您可以使用 JavaScript 库即时生成缩略图。例如https://github.com/mozilla/pdf.js
推荐阅读
- linux - 跨行比较文件值
- android - Android Q - 用户在应用设置中删除 uri 的持久权限。如何再次请求许可?
- angular - 如何仅在一个特定的 NgModule 中添加 http 拦截器(没有延迟加载)?
- windows - 使用 CMake 构建的 Qt 应用程序在 Windows 中编译但不运行
- excel - Excel公式跳转到特定单元格
- excel - 如何在 Excel VBA 中使用 REST API (Zoho Sheets)?
- visual-studio - Visual Studio 的比较工具是否有更好的替代方法来比较目录?
- c++ - 当路径中出现希腊字母时,fs::directory_iterator 返回空列表
- sql - 为什么 SELECT COUNT(id) 这么慢?
- google-sheets - 从按天加权的每周数据中总结一个月的值