mirror of
https://github.com/Alfresco/alfresco-transform-core.git
synced 2026-09-16 18:12:54 +00:00
MNT-24205 Tiff to pdf page size regression (#965)
* MNT-24205 Fix Tiff to PDF regression * MNT-24205 add test files * MNT-24205 remove redundant code
This commit is contained in:
@@ -52,6 +52,13 @@
|
||||
<version>${dependency.pdfbox.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-imaging -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-imaging</artifactId>
|
||||
<version>${dependency.imaging.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- OOXMLThumbnailContentTransformer -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
|
||||
+66
-5
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Transform Core
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2024 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* -
|
||||
@@ -30,6 +30,8 @@ import static org.alfresco.transform.common.RequestParamMap.END_PAGE;
|
||||
import static org.alfresco.transform.common.RequestParamMap.PDF_FORMAT;
|
||||
import static org.alfresco.transform.common.RequestParamMap.PDF_ORIENTATION;
|
||||
import static org.alfresco.transform.common.RequestParamMap.START_PAGE;
|
||||
import static org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants.TIFF_TAG_XRESOLUTION;
|
||||
import static org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants.TIFF_TAG_YRESOLUTION;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReader;
|
||||
@@ -45,6 +47,12 @@ import java.util.stream.Stream;
|
||||
|
||||
import org.alfresco.transform.base.TransformManager;
|
||||
import org.alfresco.transform.base.util.CustomTransformerFileAdaptor;
|
||||
import org.apache.commons.imaging.Imaging;
|
||||
import org.apache.commons.imaging.ImagingException;
|
||||
import org.apache.commons.imaging.common.ImageMetadata;
|
||||
import org.apache.commons.imaging.formats.tiff.TiffField;
|
||||
import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;
|
||||
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfo;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
@@ -75,8 +83,9 @@ public class ImageToPdfTransformer implements CustomTransformerFileAdaptor
|
||||
private static final String START_PAGE_GREATER_THAN_END_PAGE_ERROR_MESSAGE = "Start page number cannot be greater than end page.";
|
||||
private static final String INVALID_OPTION_ERROR_MESSAGE = "Parameter '%s' is invalid: \"%s\" - it must be an integer.";
|
||||
private static final String INVALID_IMAGE_ERROR_MESSAGE = "Image file (%s) format (%s) not supported by ImageIO.";
|
||||
private static final String DEFAULT_PDF_FORMAT_STRING = "DEFAULT";
|
||||
private static final String DEFAULT_PDF_FORMAT_STRING = "DEFAULT"; // pdf format to use when no pdf format specified
|
||||
private static final String DEFAULT_PDF_ORIENTATION_STRING = "DEFAULT";
|
||||
private static final float PDFBOX_POINTS_PER_INCH = 72.0F;
|
||||
|
||||
@Override
|
||||
public String getTransformerName()
|
||||
@@ -99,6 +108,7 @@ public class ImageToPdfTransformer implements CustomTransformerFileAdaptor
|
||||
final String pdfOrientation = parseOptionIfPresent(transformOptions, PDF_ORIENTATION, String.class).orElse(DEFAULT_PDF_ORIENTATION_STRING);
|
||||
verifyOptions(startPage, endPage);
|
||||
|
||||
final Map<String, Integer> resolution = determineImageResolution(imageFile);
|
||||
final ImageReader imageReader = findImageReader(imageInputStream, imageFile.getName(), sourceMimetype);
|
||||
for (int i = 0; i < imageReader.getNumImages(true); i++)
|
||||
{
|
||||
@@ -111,7 +121,7 @@ public class ImageToPdfTransformer implements CustomTransformerFileAdaptor
|
||||
break;
|
||||
}
|
||||
|
||||
scaleAndDrawImage(pdfDocument, imageReader.read(i), pdfFormat, pdfOrientation);
|
||||
scaleAndDrawImage(pdfDocument, imageReader.read(i), pdfFormat, pdfOrientation, resolution);
|
||||
}
|
||||
|
||||
pdfDocument.save(pdfFile);
|
||||
@@ -131,11 +141,22 @@ public class ImageToPdfTransformer implements CustomTransformerFileAdaptor
|
||||
return imageReader;
|
||||
}
|
||||
|
||||
private void scaleAndDrawImage(final PDDocument pdfDocument, final BufferedImage bufferedImage, final String pdfFormat, final String pdfOrientation)
|
||||
private void scaleAndDrawImage(final PDDocument pdfDocument, final BufferedImage bufferedImage, final String pdfFormat, final String pdfOrientation, final Map<String, Integer> resolution)
|
||||
throws IOException
|
||||
{
|
||||
final PDImageXObject image = LosslessFactory.createFromImage(pdfDocument, bufferedImage);
|
||||
final PDPage pdfPage = new PDPage(resolvePdfFormat(pdfFormat, pdfOrientation, image.getWidth(), image.getHeight()));
|
||||
|
||||
int imageWidth = image.getWidth();
|
||||
int imageHeight = image.getHeight();
|
||||
// if the image has a resolution which differs from pdfbox then adjust size in pixels according to pdfbox ppi
|
||||
if (resolution.get("X") > 0 && resolution.get("X") != PDFBOX_POINTS_PER_INCH &&
|
||||
resolution.get("Y") > 0 && resolution.get("Y") != PDFBOX_POINTS_PER_INCH)
|
||||
{
|
||||
imageWidth = (int)(((float)imageWidth / resolution.get("X")) * PDFBOX_POINTS_PER_INCH);
|
||||
imageHeight = (int)(((float)imageHeight / resolution.get("Y")) * PDFBOX_POINTS_PER_INCH);
|
||||
}
|
||||
|
||||
final PDPage pdfPage = new PDPage(resolvePdfFormat(pdfFormat, pdfOrientation, imageWidth, imageHeight));
|
||||
pdfDocument.addPage(pdfPage);
|
||||
try (PDPageContentStream pdfPageContent = new PDPageContentStream(pdfDocument, pdfPage))
|
||||
{
|
||||
@@ -257,4 +278,44 @@ public class ImageToPdfTransformer implements CustomTransformerFileAdaptor
|
||||
throw new IllegalArgumentException(START_PAGE_GREATER_THAN_END_PAGE_ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, Integer> determineImageResolution(File imageFile)
|
||||
{
|
||||
int xResolution = 0;
|
||||
int yResolution = 0;
|
||||
|
||||
try
|
||||
{
|
||||
final ImageMetadata metadata = Imaging.getMetadata(imageFile);
|
||||
if (metadata instanceof TiffImageMetadata)
|
||||
{
|
||||
final TiffImageMetadata tiffImageMetadata = (TiffImageMetadata) metadata;
|
||||
xResolution = findMetadataField(tiffImageMetadata, TIFF_TAG_XRESOLUTION);
|
||||
yResolution = findMetadataField(tiffImageMetadata, TIFF_TAG_YRESOLUTION);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// treat as though no resolution exists
|
||||
}
|
||||
return Map.of("X", xResolution, "Y", yResolution);
|
||||
}
|
||||
|
||||
static private int findMetadataField(TiffImageMetadata tiffImageMetadata, TagInfo tagInfo)
|
||||
{
|
||||
int value = 0;
|
||||
try
|
||||
{
|
||||
TiffField field = tiffImageMetadata.findField(tagInfo);
|
||||
if (field != null)
|
||||
{
|
||||
value = field.getIntValue();
|
||||
}
|
||||
}
|
||||
catch (ImagingException e)
|
||||
{
|
||||
// treat as though field not found
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
+36
-1
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Transform Core
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2024 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* -
|
||||
@@ -290,6 +290,41 @@ class ImageToPdfTransformerTest
|
||||
}
|
||||
}
|
||||
|
||||
static Stream<Arguments> imageFilesOfVariousSizeAndResolution()
|
||||
{
|
||||
return Stream.of(
|
||||
Arguments.of(ImageFile.of("MNT-24205.tiff", MIMETYPE_IMAGE_TIFF), 612.0f, 792.0f),
|
||||
Arguments.of(ImageFile.of("459x594-50.tif", MIMETYPE_IMAGE_TIFF), 660.0f, 855.0f),
|
||||
Arguments.of(ImageFile.of("459x594-72.tif", MIMETYPE_IMAGE_TIFF), 459.0f, 594.0f),
|
||||
Arguments.of(ImageFile.of("459x594-300.tif", MIMETYPE_IMAGE_TIFF), 110.0f, 142.0f),
|
||||
Arguments.of(ImageFile.of("612x792-50.tif", MIMETYPE_IMAGE_TIFF), 881.0f, 1140.0f),
|
||||
Arguments.of(ImageFile.of("612x792-72.tif", MIMETYPE_IMAGE_TIFF), 612.0f, 792.0f),
|
||||
Arguments.of(ImageFile.of("612x792-300.tif", MIMETYPE_IMAGE_TIFF), 146.0f, 190.0f),
|
||||
Arguments.of(ImageFile.of("765x990-50.tif", MIMETYPE_IMAGE_TIFF), 1101.0f, 1425.0f),
|
||||
Arguments.of(ImageFile.of("765x990-72.tif", MIMETYPE_IMAGE_TIFF), 765.0f, 990.0f),
|
||||
Arguments.of(ImageFile.of("765x990-300.tif", MIMETYPE_IMAGE_TIFF), 183.0f, 237.0f)
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("imageFilesOfVariousSizeAndResolution")
|
||||
void testTransformTiffToPDF_withVariousImageSizes(ImageFile imageFile, float expectedWidth, float expectedHeight) throws Exception
|
||||
{
|
||||
TransformOptions transformOptions = TransformOptions.of("DEFAULT");
|
||||
|
||||
File source = loadFile(imageFile.fileName);
|
||||
|
||||
// when
|
||||
transformer.transform(imageFile.mimetype, MIMETYPE_PDF, transformOptions.toMap(), source, targetFile, transformManager);
|
||||
|
||||
try (PDDocument actualPdfDocument = PDDocument.load(targetFile))
|
||||
{
|
||||
assertNotNull(actualPdfDocument);
|
||||
assertEquals(expectedWidth, actualPdfDocument.getPage(0).getMediaBox().getWidth(),"Pdf width");
|
||||
assertEquals(expectedHeight,actualPdfDocument.getPage(0).getMediaBox().getHeight(),"Pdf height");
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------- Helper methods and classes -----------------------------------------------
|
||||
|
||||
private static BiFunction<Float, Float, PDRectangle> unchangedRectangle()
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -27,6 +27,7 @@
|
||||
<dependency.jackson.version>2.16.1</dependency.jackson.version>
|
||||
<dependency.tika.version>2.9.2</dependency.tika.version>
|
||||
<dependency.poi.version>5.2.5</dependency.poi.version>
|
||||
<dependency.imaging.version>1.0.0-alpha5</dependency.imaging.version>
|
||||
<dependency.snakeyaml.version>2.2</dependency.snakeyaml.version>
|
||||
<!--The override can be removed when transitive (from tika) bouncycastle dependency is free of vulnerabilities-->
|
||||
<dependency.bouncycastle.version.override>1.78.1</dependency.bouncycastle.version.override>
|
||||
@@ -160,6 +161,12 @@
|
||||
<artifactId>pdfbox-tools</artifactId>
|
||||
<version>${dependency.pdfbox.version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-imaging -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-imaging</artifactId>
|
||||
<version>${dependency.imaging.version}</version>
|
||||
</dependency>
|
||||
<!-- Jackson -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson</groupId>
|
||||
|
||||
Reference in New Issue
Block a user