Skip to content

Commit

Permalink
replace Scalr with Thumbnailator. Upgraded metadata-extractor. Moved …
Browse files Browse the repository at this point in the history
…ImageOptimizer to PRO
  • Loading branch information
torakiki committed Mar 3, 2021
1 parent d938279 commit c6bee05
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 172 deletions.
4 changes: 3 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,8 @@
<sejda.io.version>2.1.3</sejda.io.version>
<bouncycastle.version>1.66</bouncycastle.version>
<twelvemonkeys.version>3.4.2</twelvemonkeys.version>
<metadata-extractor.version>2.15.0</metadata-extractor.version>
<thumbnailator.version>0.4.13</thumbnailator.version>
<!-- so that build is not platform dependent via encoding -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<timestamp>${maven.build.timestamp}</timestamp>
Expand All @@ -393,7 +395,7 @@
<dependency>
<groupId>com.drewnoakes</groupId>
<artifactId>metadata-extractor</artifactId>
<version>2.10.1</version>
<version>${metadata-extractor.version}</version>
</dependency>
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
Expand Down
5 changes: 0 additions & 5 deletions sejda-image-writers/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,5 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.imgscalr</groupId>
<artifactId>imgscalr-lib</artifactId>
<version>4.2</version>
</dependency>
</dependencies>
</project>

This file was deleted.

5 changes: 5 additions & 0 deletions sejda-sambox/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>${thumbnailator.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;

import org.imgscalr.Scalr;
import org.sejda.core.support.io.IOUtils;
import org.sejda.io.SeekableSource;
import org.sejda.io.SeekableSources;
Expand All @@ -60,6 +59,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.coobird.thumbnailator.Thumbnails;

public class PageImageWriter {
private static final Logger LOG = LoggerFactory.getLogger(PageImageWriter.class);

Expand Down Expand Up @@ -200,9 +201,8 @@ private static Optional<SeekableSource> convertExifRotatedIf(SeekableSource sour
int degrees = ExifHelper.getRotationBasedOnExifOrientation(source.asNewInputStream());

BufferedImage image = ImageIO.read(source.asNewInputStream());
Scalr.Rotation rotation = toScalrRotation(degrees);
if (rotation != null) {
BufferedImage result = Scalr.rotate(image, rotation);
if (degrees > 0) {
BufferedImage result = Thumbnails.of(image).scale(1).rotate(degrees).asBufferedImage();

File tmpFile = IOUtils.createTemporaryBuffer();
ImageIO.write(result, getImageIOSaveFormat(source), tmpFile);
Expand All @@ -221,22 +221,6 @@ private static String getImageIOSaveFormat(SeekableSource source) {
return "png";
}

private static Scalr.Rotation toScalrRotation(int degrees) {
if (degrees == 90) {
return Scalr.Rotation.CW_90;
}

if (degrees == 180) {
return Scalr.Rotation.CW_180;
}

if (degrees == 270) {
return Scalr.Rotation.CW_270;
}

return null;
}

/**
* Checks if the input file is a JPEG using CMYK If that's the case, converts to RGB and returns the file path
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@
*/
package org.sejda.impl.sambox.util;

import org.imgscalr.Scalr;
import static org.sejda.core.service.BaseTaskTest.customInput;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.junit.Assert;
import org.sejda.core.support.io.IOUtils;
import org.sejda.impl.sambox.component.DefaultPdfSourceOpener;
Expand All @@ -29,24 +36,21 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import static org.sejda.core.service.BaseTaskTest.customInput;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.resizers.configurations.ScalingMode;

public class PixelCompareUtils {

private static final Logger LOG = LoggerFactory.getLogger(PixelCompareUtils.class);

public static void assertSimilar(PDDocumentHandler doc1, String doc2ResourcePath) {
assertSimilar(doc1.getUnderlyingPDDocument(), doc2ResourcePath);
assertSimilar(doc1.getUnderlyingPDDocument(), doc2ResourcePath);
}

public static void assertSimilar(PDDocument doc1, String doc2ResourcePath) {
try {
PDDocument doc2 = customInput(doc2ResourcePath).open(new DefaultPdfSourceOpener()).getUnderlyingPDDocument();
PDDocument doc2 = customInput(doc2ResourcePath).open(new DefaultPdfSourceOpener())
.getUnderlyingPDDocument();
assertSimilar(doc1, doc2, Integer.MAX_VALUE);
} catch (TaskIOException e) {
throw new RuntimeException(e);
Expand All @@ -56,11 +60,12 @@ public static void assertSimilar(PDDocument doc1, String doc2ResourcePath) {
public static void assertSimilar(PDDocument doc1, PDDocument doc2) {
assertSimilar(doc1, doc2, Integer.MAX_VALUE);
}

public static void assertSimilar(PDDocument doc1, PDDocument doc2, int maxNumberOfPages) {
try {
if(doc1.getNumberOfPages() != doc2.getNumberOfPages()) {
Assert.fail("Documents have different number of pages:" + doc1.getNumberOfPages() + ", " + doc2.getNumberOfPages());
if (doc1.getNumberOfPages() != doc2.getNumberOfPages()) {
Assert.fail("Documents have different number of pages:" + doc1.getNumberOfPages() + ", "
+ doc2.getNumberOfPages());
}

int numOfPages = Math.min(doc1.getNumberOfPages(), maxNumberOfPages);
Expand All @@ -72,10 +77,10 @@ public static void assertSimilar(PDDocument doc1, PDDocument doc2, int maxNumber
BufferedImage p2 = takeScreenshotOf(doc2, i);
double similary = pixelSimilarityOf(p1, p2);

if (similary < 99.5d){
if (similary < 99.5d) {
File folder = IOUtils.createTemporaryFolder();
File f1 = new File(folder, "p"+ (i + 1) + "_1.png");
File f2 = new File(folder, "p"+ (i + 1) + "_2.png");
File f1 = new File(folder, "p" + (i + 1) + "_1.png");
File f2 = new File(folder, "p" + (i + 1) + "_2.png");
ImageIO.write(p1, "png", f1);
ImageIO.write(p2, "png", f2);
LOG.error("Troubleshoot:\n" + f1 + "\n" + f2);
Expand All @@ -88,22 +93,23 @@ public static void assertSimilar(PDDocument doc1, PDDocument doc2, int maxNumber
}
}

public static BufferedImage takeScreenshotOf(PDDocument doc, int pageIndex) throws IOException, TaskIOException {
public static BufferedImage takeScreenshotOf(PDDocument doc, int pageIndex) throws IOException {
PDFRenderer pdfRenderer = new PDFRenderer(doc);
return pdfRenderer.renderImageWithDPI(pageIndex, 150);
}

private static BufferedImage resizeTo(BufferedImage image, int width) {
return Scalr.resize(image, Scalr.Method.ULTRA_QUALITY, width);
private static BufferedImage resizeTo(BufferedImage image, int width) throws IOException {
return Thumbnails.of(image).scalingMode(ScalingMode.PROGRESSIVE_BILINEAR).width(width)
.asBufferedImage();
}

private static double pixelSimilarityOf(BufferedImage src1, BufferedImage src2) {
private static double pixelSimilarityOf(BufferedImage src1, BufferedImage src2) throws IOException {
BufferedImage img1 = resizeTo(src1, 1024);
BufferedImage img2 = resizeTo(src2, 1024);

double difference = 0d;
for(int x = 0; x < img1.getWidth(); x++) {
for(int y = 0; y < img1.getHeight(); y++) {
for (int x = 0; x < img1.getWidth(); x++) {
for (int y = 0; y < img1.getHeight(); y++) {
int rgbA = img1.getRGB(x, y);
int rgbB = img2.getRGB(x, y);
int redA = (rgbA >> 16) & 0xff;
Expand All @@ -118,18 +124,18 @@ private static double pixelSimilarityOf(BufferedImage src1, BufferedImage src2)
}
}

// Total number of red pixels = width * height
// Total number of blue pixels = width * height
// Total number of green pixels = width * height
// So total number of pixels = width * height * 3
// Total number of red pixels = width * height
// Total number of blue pixels = width * height
// Total number of green pixels = width * height
// So total number of pixels = width * height * 3
double totalPixels = img1.getWidth() * img1.getHeight() * 3d;

// Normalizing the value of different pixels
// for accuracy(average pixels per color
// component)
// Normalizing the value of different pixels
// for accuracy(average pixels per color
// component)
double avgDifferentPixels = difference / totalPixels;

// There are 255 values of pixels in total
// There are 255 values of pixels in total
double percentage = (avgDifferentPixels / 255) * 100d;

return 100 - percentage;
Expand Down

0 comments on commit c6bee05

Please sign in to comment.