Как я могу улучшить качество изображений, созданных из PDF? - PullRequest
1 голос
/ 11 февраля 2020

Мы используем TYPO3 9.5.13, GraphicsMagick 1.3.29, Ghostscript 9.27, BK2K\\BootstrapPackage 11.0.1

Использование PDF-файлов в качестве обычных изображений не проблема.
Но теперь я хочу «предварительный просмотр» PDF-файлов в полная ширина столбца (~ 1000 пикселей). И хотя PDF имеет высокое разрешение, сгенерированное изображение имеет ширину всего 595 пикселей, и любой текст почти не читается.

Проблема возникает с Image-CE, как в загружаемых CE, которые я хочу улучшить:
каждый раз, когда я хочу, чтобы изображение использовало полную ширину столбца, оно рендерится с плохим разрешением, и изображение кажется искаженным.

здесь небольшая область от сгенерированного изображения:
enter image description here

и та же область из PDF, как показано в PDF-ридере:
enter image description here

Текучая часть:

<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">

Редактировать:

В случае использования этой жидкости:

<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">

изображение больше (и переполняет контейнер), но качество хуже, обратите внимание на большие пиксели:

enter image description here

1 Ответ

1 голос
/ 12 февраля 2020

На самом деле PDF является НЕ изображением. Это контейнерный формат, который может содержать векторы и изображения с различными цветовыми пространствами и размерами. Растровое изображение имеет фиксированные размеры ширина, высота, плотность, а PDF нет. Первоначально он был создан и оптимизирован для работы на принтерах, а не на экранах.

TYPO3 отражает это с сообщением в бэкэнде: enter image description here

ИМХО, там не существует идеального способа обработки PDF-файлов, которые бы вели себя как изображения, поскольку вы знаете формат вывода, но не формат ввода (правильно). Два способа получения приемлемых результатов:

  1. Расширение элементов содержимого или создание новых и добавление второго слота изображения для изображений предварительного просмотра PDF. Создайте изображения для предварительного просмотра самостоятельно с помощью графической программы.
  2. Напишите свой собственный видовой помощник и создайте собственные эскизы

Решение 1 приведет к дополнительной работе для редакторов. Для меня это не лучшая практика.


Я бы go имел собственный помощник по просмотру.

Добавьте свой собственный тип визуализации для 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:

Этот помощник по просмотру преобразует несколько страниц из PDF, используя CommandUtility :: imageMagickCommand. Вы можете повысить плотность до более высокого значения, чтобы улучшить качество. Как уже упоминалось, этот помощник по видам разрабатывался несколько лет go и мог быть улучшен (например, сохранение в 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

...