├── .backportrc.json ├── .buildkite ├── deploy_snapshot_pipeline.yml ├── hooks │ └── pre-command ├── mvn-settings.xml ├── pipeline.yml ├── release_pipeline.yml └── scripts │ ├── git_setup.sh │ └── run_deploy_release.sh ├── .gitignore ├── .mvn └── wrapper │ ├── MavenWrapperDownloader.java │ └── maven-wrapper.properties ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE.txt ├── NOTICE.txt.template ├── README.md ├── catalog-info.yaml ├── docs └── images │ ├── thumbnails4j-@1200x1200.png │ ├── thumbnails4j-@1200x628.png │ ├── thumbnails4j-color-logomark.png │ ├── thumbnails4j-color-logomark.svg │ ├── thumbnails4j-color.png │ └── thumbnails4j-color.svg ├── mvnw ├── mvnw.cmd ├── pom.xml ├── src └── main │ └── resources │ └── META-INF │ └── NOTICE.txt ├── thumbnails4j-all ├── NOTICE.txt ├── NOTICE.txt.template ├── pom.xml └── src │ └── main │ └── resources │ └── META-INF │ ├── LICENSE.txt │ └── NOTICE.txt ├── thumbnails4j-core ├── NOTICE.txt ├── NOTICE.txt.template ├── pom.xml └── src │ ├── main │ ├── java │ │ └── co │ │ │ └── elastic │ │ │ └── thumbnails4j │ │ │ └── core │ │ │ ├── Dimensions.java │ │ │ ├── ThumbnailUtils.java │ │ │ ├── Thumbnailer.java │ │ │ └── ThumbnailingException.java │ └── resources │ │ └── META-INF │ │ ├── LICENSE.txt │ │ └── NOTICE.txt │ └── test │ ├── java │ └── co │ │ └── elastic │ │ └── thumbnails4j │ │ └── core │ │ ├── DimensionsTest.groovy │ │ └── ThumbnailUtilsTest.groovy │ └── resources │ └── images │ └── test.png ├── thumbnails4j-doc ├── NOTICE.txt ├── NOTICE.txt.template ├── pom.xml └── src │ ├── main │ ├── java │ │ └── co │ │ │ └── elastic │ │ │ └── thumbnails4j │ │ │ └── doc │ │ │ └── DOCThumbnailer.java │ └── resources │ │ └── META-INF │ │ ├── LICENSE.txt │ │ └── NOTICE.txt │ └── test │ ├── java │ └── co │ │ └── elastic │ │ └── thumbnails4j │ │ └── doc │ │ └── DOCThumbnailerTest.groovy │ └── resources │ ├── test-input.doc │ └── test-output.jpg ├── thumbnails4j-docx ├── NOTICE.txt ├── NOTICE.txt.template ├── pom.xml └── src │ ├── main │ ├── java │ │ └── co │ │ │ └── elastic │ │ │ └── thumbnails4j │ │ │ └── docx │ │ │ └── DOCXThumbnailer.java │ └── resources │ │ └── META-INF │ │ ├── LICENSE.txt │ │ └── NOTICE.txt │ └── test │ ├── java │ └── co │ │ └── elastic │ │ └── thumbnails4j │ │ └── docx │ │ └── DOCXThumbnailerTest.groovy │ └── resources │ ├── test-input.docx │ └── test-output.jpg ├── thumbnails4j-image ├── NOTICE.txt ├── NOTICE.txt.template ├── pom.xml └── src │ ├── main │ ├── java │ │ └── co │ │ │ └── elastic │ │ │ └── thumbnails4j │ │ │ └── image │ │ │ └── ImageThumbnailer.java │ └── resources │ │ └── META-INF │ │ ├── LICENSE.txt │ │ └── NOTICE.txt │ └── test │ ├── java │ └── co │ │ └── elastic │ │ └── thumbnails4j │ │ └── image │ │ └── ImageThumbnailerTest.groovy │ └── resources │ ├── test-input.png │ └── test-output.png ├── thumbnails4j-pdf ├── NOTICE.txt ├── NOTICE.txt.template ├── pom.xml └── src │ ├── main │ ├── java │ │ └── co │ │ │ └── elastic │ │ │ └── thumbnails4j │ │ │ └── pdf │ │ │ ├── NullCache.java │ │ │ └── PDFThumbnailer.java │ └── resources │ │ └── META-INF │ │ ├── LICENSE.txt │ │ └── NOTICE.txt │ └── test │ ├── java │ └── co │ │ └── elastic │ │ └── thumbnails4j │ │ └── pdf │ │ └── PDFThumbnailerTest.groovy │ └── resources │ ├── test-bigger.pdf │ ├── test-input.pdf │ └── test-output.jpg ├── thumbnails4j-pptx ├── NOTICE.txt ├── NOTICE.txt.template ├── pom.xml └── src │ ├── main │ ├── java │ │ └── co │ │ │ └── elastic │ │ │ └── thumbnails4j │ │ │ └── pptx │ │ │ └── PPTXThumbnailer.java │ └── resources │ │ └── META-INF │ │ ├── LICENSE.txt │ │ └── NOTICE.txt │ └── test │ ├── java │ └── co │ │ └── elastic │ │ └── thumbnails4j │ │ └── pptx │ │ └── PPTXThumbnailerTest.groovy │ └── resources │ ├── test-input.pptx │ └── test-output.jpg ├── thumbnails4j-xls ├── NOTICE.txt ├── NOTICE.txt.template ├── pom.xml └── src │ ├── main │ ├── java │ │ └── co │ │ │ └── elastic │ │ │ └── thumbnails4j │ │ │ └── xls │ │ │ └── XLSThumbnailer.java │ └── resources │ │ └── META-INF │ │ ├── LICENSE.txt │ │ └── NOTICE.txt │ └── test │ ├── java │ └── co │ │ └── elastic │ │ └── thumbnails4j │ │ └── xls │ │ └── XLSThumbnailerTest.groovy │ └── resources │ ├── test-input.xls │ └── test-output.jpg └── thumbnails4j-xlsx ├── NOTICE.txt ├── NOTICE.txt.template ├── pom.xml └── src ├── main ├── java │ └── co │ │ └── elastic │ │ └── thumbnails4j │ │ └── xlsx │ │ ├── XLSXThumbnailer.java │ │ └── XlsxToHtmlSerializer.java └── resources │ └── META-INF │ ├── LICENSE.txt │ └── NOTICE.txt └── test ├── java └── co │ └── elastic │ └── thumbnails4j │ └── xlsx │ └── XLSXThumbnailerTest.groovy └── resources ├── test-input.xlsx └── test-output.jpg /.backportrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "targetBranchChoices": [ 3 | { "name": "main", "checked": true }, 4 | "1.1", 5 | "1.0" 6 | ], 7 | "fork": false, 8 | "targetPRLabels": ["backport"], 9 | "branchLabelMapping": { 10 | "^v1.2.0$": "main", 11 | "^v(\\d+).(\\d+)(.\\d+)*$": "$1.$2" 12 | }, 13 | "upstream": "elastic/thumbnails4j" 14 | } 15 | -------------------------------------------------------------------------------- /.buildkite/deploy_snapshot_pipeline.yml: -------------------------------------------------------------------------------- 1 | ## 🏠/.buildkite/deploy_snapshot_pipeline.yml 2 | # snapshot deployment pipeline - runs once per day 3 | 4 | agents: 5 | image: "docker.elastic.co/ci-agent-images/enterprise-search/thumbnails4j-buildkite-agent" 6 | ephemeralStorage: "20G" 7 | memory: "4G" 8 | useVault: true 9 | 10 | notify: 11 | - if: 'build.branch =~ /^((main)|([0-9]+\.[0-9]+))\$/ && (build.state == "failed" || pipeline.started_passing)' 12 | slack: 13 | channels: 14 | - "#search-et-alerts" 15 | message: "${BUILDKITE_MESSAGE}" 16 | 17 | steps: 18 | - label: ":truck: Maven Deploy Snapshot" 19 | command: ".buildkite/scripts/run_deploy_release.sh deploy" 20 | timeout_in_minutes: 45 21 | -------------------------------------------------------------------------------- /.buildkite/hooks/pre-command: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | if [ "$BUILDKITE_PIPELINE_SLUG" == "thumbnails4j-deploy" ] || [ "$BUILDKITE_PIPELINE_SLUG" == "thumbnails4j-release" ]; then 5 | echo "--- Prepare github secrets :vault:" 6 | # Only accessible by Elastic employees 7 | MACHINE_USER_VAULT_PATH="kv/ci-shared/thumbnails4j/thumbnails4jmachine" 8 | GITHUB_SECRET=$(vault kv get --field token "$MACHINE_USER_VAULT_PATH") 9 | GIT_USER=$(vault kv get --field username "$MACHINE_USER_VAULT_PATH") 10 | GIT_EMAIL=$(vault kv get --field email "$MACHINE_USER_VAULT_PATH") 11 | GH_TOKEN=$GITHUB_SECRET 12 | export GITHUB_SECRET GH_TOKEN GIT_USER GIT_EMAIL 13 | 14 | echo "--- Prepare a secure temp :closed_lock_with_key:" 15 | # Prepare a secure temp folder not shared between other jobs to store the key ring 16 | export TMP_WORKSPACE=/tmp/secured 17 | export KEY_FILE=$TMP_WORKSPACE"/private.key" 18 | 19 | # Secure home for our keyring 20 | export GNUPGHOME=$TMP_WORKSPACE"/keyring" 21 | mkdir -p $GNUPGHOME 22 | chmod -R 700 $TMP_WORKSPACE 23 | 24 | echo "--- Prepare keys context :key:" 25 | # Nexus credentials 26 | NEXUS_SECRET=kv/ci-shared/release-eng/team-release-secrets/thumbnails4j/maven_central 27 | SERVER_USERNAME=$(vault kv get --field="username" $NEXUS_SECRET) 28 | export SERVER_USERNAME 29 | SERVER_PASSWORD=$(vault kv get --field="password" $NEXUS_SECRET) 30 | export SERVER_PASSWORD 31 | 32 | # Signing keys 33 | GPG_SECRET=kv/ci-shared/release-eng/team-release-secrets/thumbnails4j/gpg 34 | vault kv get --field="keyring" $GPG_SECRET | base64 -d > $KEY_FILE 35 | 36 | ## NOTE: passphase is the name of the field. 37 | KEYPASS_SECRET=$(vault kv get --field="passphase" $GPG_SECRET) 38 | export KEYPASS_SECRET 39 | 40 | KEY_ID=$(vault kv get --field="key_id" $GPG_SECRET) 41 | KEY_ID_SECRET=${KEY_ID: -8} 42 | export KEY_ID_SECRET 43 | 44 | # Import the key into the keyring 45 | echo "$KEYPASS_SECRET" | gpg --batch --import "$KEY_FILE" 46 | 47 | # echo "--- Configure git context :git:" 48 | # Configure the committer since the maven release requires to push changes to GitHub 49 | # This will help with the SLSA requirements. 50 | git config --global user.email "${GIT_EMAIL}" 51 | git config --global user.name "${GIT_USER}" 52 | fi 53 | -------------------------------------------------------------------------------- /.buildkite/mvn-settings.xml: -------------------------------------------------------------------------------- 1 | 21 | 22 | 25 | 26 | org.apache.maven.plugins 27 | org.codehaus.mojo 28 | 29 | 30 | 31 | sonatype-nexus-snapshots 32 | ${env.SERVER_USERNAME} 33 | ${env.SERVER_PASSWORD} 34 | 35 | 36 | sonatype-nexus-staging 37 | ${env.SERVER_USERNAME} 38 | ${env.SERVER_PASSWORD} 39 | 40 | 41 | github 42 | ${env.GIT_USER} 43 | ${env.GH_TOKEN} 44 | 45 | 46 | 47 | 48 | thumbnails4j 49 | 50 | true 51 | 52 | 53 | ${env.KEYPASS_SECRET} 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /.buildkite/pipeline.yml: -------------------------------------------------------------------------------- 1 | ## 🏠/.buildkite/pipeline.yml 2 | # Primary pipeline for thumbnails4j 3 | # runs with every commit on a PR or branch 4 | 5 | agents: 6 | image: "docker.elastic.co/ci-agent-images/enterprise-search/thumbnails4j-buildkite-agent" 7 | ephemeralStorage: "20G" 8 | memory: "4G" 9 | 10 | notify: 11 | - if: 'build.branch =~ /^((main)|([0-9]+\.[0-9]+))\$/ && (build.state == "failed" || pipeline.started_passing)' 12 | slack: 13 | channels: 14 | - "#search-et-alerts" 15 | message: "${BUILDKITE_MESSAGE}" 16 | 17 | steps: 18 | - label: ":wrench: Maven Build" 19 | command: "./mvnw clean verify" 20 | timeout_in_minutes: 45 21 | -------------------------------------------------------------------------------- /.buildkite/release_pipeline.yml: -------------------------------------------------------------------------------- 1 | ## 🏠/.buildkite/deploy_snapshot_pipeline.yml 2 | # snapshot deployment pipeline - runs once per day 3 | 4 | agents: 5 | image: "docker.elastic.co/ci-agent-images/enterprise-search/thumbnails4j-buildkite-agent" 6 | ephemeralStorage: "20G" 7 | memory: "4G" 8 | useVault: true 9 | 10 | notify: 11 | - if: 'build.branch =~ /^((main)|([0-9]+\.[0-9]+))\$/ && (build.state == "failed" || pipeline.started_passing)' 12 | slack: 13 | channels: 14 | - "#search-et-alerts" 15 | message: "${BUILDKITE_MESSAGE}" 16 | 17 | steps: 18 | - label: ":truck: Maven Release" 19 | command: ".buildkite/scripts/run_deploy_release.sh release" 20 | timeout_in_minutes: 45 21 | -------------------------------------------------------------------------------- /.buildkite/scripts/git_setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | export GIT_BRANCH=${BUILDKITE_BRANCH} 5 | 6 | git switch - 7 | git checkout $GIT_BRANCH 8 | git pull origin $GIT_BRANCH 9 | -------------------------------------------------------------------------------- /.buildkite/scripts/run_deploy_release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eo pipefail 4 | 5 | RUN_TYPE=${1:-} 6 | 7 | if [[ "${RUN_TYPE}" != "deploy" && "${RUN_TYPE}" != "release" ]]; then 8 | echo "Missing arguemnt for RUN_TYPE. Must be 'deploy' or 'release'" 9 | exit 2 10 | fi 11 | 12 | function realpath { 13 | echo "$(cd "$(dirname "$1")"; pwd)"/"$(basename "$1")"; 14 | } 15 | 16 | SCRIPT_PATH="$(dirname "${BASH_SOURCE}")" 17 | BUILDKITE_PATH=$(realpath "$(dirname "$SCRIPT_PATH")") 18 | PROJECT_ROOT=$(realpath "$(dirname "$BUILDKITE_PATH")") 19 | 20 | source "${SCRIPT_PATH}/git_setup.sh" 21 | 22 | # Set Maven options 23 | export MAVEN_CONFIG="-V -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -Dhttps.protocols=TLSv1.2 -Dmaven.wagon.http.retryHandler.count=3 -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false $MAVEN_CONFIG" 24 | 25 | set -x 26 | 27 | mvnw_command="$PROJECT_ROOT/mvnw" 28 | 29 | pushd $PROJECT_ROOT 30 | cd $PROJECT_ROOT 31 | 32 | if [[ "${RUN_TYPE}" == "deploy" ]]; then 33 | $mvnw_command -s .buildkite/mvn-settings.xml \ 34 | -Pgpg clean deploy \ 35 | -DskipTests \ 36 | --batch-mode 2>/dev/null 37 | elif [[ "${RUN_TYPE}" == "release" ]]; then 38 | $mvnw_command release:prepare release:perform \ 39 | --settings .buildkite/mvn-settings.xml \ 40 | -Darguments="-DskipTests" \ 41 | --batch-mode 2>/dev/null 42 | else 43 | echo "Invalid RUN_TYPE: ${RUN_TYPE}. Nothing to do." 44 | fi 45 | 46 | popd 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | # jetbrains 26 | .idea 27 | *.iml 28 | 29 | # maven 30 | target -------------------------------------------------------------------------------- /.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import java.net.*; 17 | import java.io.*; 18 | import java.nio.channels.*; 19 | import java.util.Properties; 20 | 21 | public class MavenWrapperDownloader { 22 | 23 | private static final String WRAPPER_VERSION = "0.5.6"; 24 | /** 25 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 26 | */ 27 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 28 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 29 | 30 | /** 31 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 32 | * use instead of the default one. 33 | */ 34 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 35 | ".mvn/wrapper/maven-wrapper.properties"; 36 | 37 | /** 38 | * Path where the maven-wrapper.jar will be saved to. 39 | */ 40 | private static final String MAVEN_WRAPPER_JAR_PATH = 41 | ".mvn/wrapper/maven-wrapper.jar"; 42 | 43 | /** 44 | * Name of the property which should be used to override the default download url for the wrapper. 45 | */ 46 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 47 | 48 | public static void main(String args[]) { 49 | System.out.println("- Downloader started"); 50 | File baseDirectory = new File(args[0]); 51 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 52 | 53 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 54 | // wrapperUrl parameter. 55 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 56 | String url = DEFAULT_DOWNLOAD_URL; 57 | if(mavenWrapperPropertyFile.exists()) { 58 | FileInputStream mavenWrapperPropertyFileInputStream = null; 59 | try { 60 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 61 | Properties mavenWrapperProperties = new Properties(); 62 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 63 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 64 | } catch (IOException e) { 65 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 66 | } finally { 67 | try { 68 | if(mavenWrapperPropertyFileInputStream != null) { 69 | mavenWrapperPropertyFileInputStream.close(); 70 | } 71 | } catch (IOException e) { 72 | // Ignore ... 73 | } 74 | } 75 | } 76 | System.out.println("- Downloading from: " + url); 77 | 78 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 79 | if(!outputFile.getParentFile().exists()) { 80 | if(!outputFile.getParentFile().mkdirs()) { 81 | System.out.println( 82 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 83 | } 84 | } 85 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 86 | try { 87 | downloadFileFromURL(url, outputFile); 88 | System.out.println("Done"); 89 | System.exit(0); 90 | } catch (Throwable e) { 91 | System.out.println("- Error downloading"); 92 | e.printStackTrace(); 93 | System.exit(1); 94 | } 95 | } 96 | 97 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 98 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 99 | String username = System.getenv("MVNW_USERNAME"); 100 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 101 | Authenticator.setDefault(new Authenticator() { 102 | @Override 103 | protected PasswordAuthentication getPasswordAuthentication() { 104 | return new PasswordAuthentication(username, password); 105 | } 106 | }); 107 | } 108 | URL website = new URL(urlString); 109 | ReadableByteChannel rbc; 110 | rbc = Channels.newChannel(website.openStream()); 111 | FileOutputStream fos = new FileOutputStream(destination); 112 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 113 | fos.close(); 114 | rbc.close(); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ![thumbnails4j](./docs/images/thumbnails4j-color-logomark.png) 2 | # thumbnails4j Contributor's Guide 3 | 4 | Thank you for your interest in contributing to thumbnails4j! 5 | 6 | How to build and contribute to thumbnails4j. 7 | 8 | ### Requirements 9 | 10 | - Java 8 11 | - OS: Unix/Linux 12 | 13 | ### Installing dependencies 14 | 15 | From the root level of this repository: 16 | 17 | ```shell 18 | ./mvnw clean install -DskipTests 19 | ``` 20 | 21 | ### Building 22 | 23 | For all projects, run from project root. For single module, run from 24 | module root. 25 | 26 | ```shell 27 | # Build 28 | ./mvnw clean install -DskipTests 29 | ``` 30 | 31 | ### Testing 32 | 33 | For all projects, run from project root. For single module, run from 34 | module root. 35 | 36 | ```shell 37 | ./mvnw clean test 38 | ``` 39 | 40 | It is expected that any contribution will include unit tests. Tests must be passing in order to merge any pull request. 41 | 42 | ### Branching Strategy 43 | 44 | Our `main` branch holds the latest development code for the next release. If the next release will be a minor release, 45 | the expecation is that no breaking changes will be in `main`. If a change would be breaking, we need to put it behind a 46 | feature flag, or make it an opt-in change. We will only merge breaking PRs when we are ready to start working on the 47 | next major. 48 | 49 | All PRs should be created from a fork, to keep a clean set of branches on `origin`. 50 | 51 | Releases should be performed directly in `main` (or a minor branch for patches), following the Publishing guide below. 52 | 53 | We will create branches for all minor releases. 54 | 55 | ### Publishing 56 | 57 | ##### Publish a new major or minor from `main` 58 | (Example, publishing 1.1.0) 59 | 60 | 1. Manually [deploy a snapshot](https://internal-ci.elastic.co/job/elastic+thumbnails4j+deploy-snapshot/) from `main` to ensure that there are no issues with the deploy mechanisms. 61 | 2. Verify the snapshots are in [https://oss.sonatype.org/content/repositories/snapshots/co/elastic/thumbnails4j/](https://oss.sonatype.org/content/repositories/snapshots/co/elastic/thumbnails4j/) 62 | 3. Create a new minor release branch, like `git checkout -b 1.1` 63 | 4. Push the new minor release branch to the origin, like `git push origin 1.1` 64 | 5. Go back to the `main` branch, like `git checkout main` 65 | 6. Update the `main` branch to point at the next version, like `mvn versions:set -DnewVersion=1.2.0-SNAPSHOT` 66 | 7. Verify your local changes, commit, and push. 67 | 8. Manually [trigger a release](https://internal-ci.elastic.co/job/elastic+thumbnails4j+release/) from the new minor release branch (`1.1` in this example). 68 | 9. Even after the build goes green, artifacts may take 30 minutes or so to appear in [https://repo1.maven.org/maven2/co/elastic/thumbnails4j](https://repo1.maven.org/maven2/co/elastic/thumbnails4j) 69 | 10. In the mean time, verify the automatic (or manually deploy) [snapshot builds](https://internal-ci.elastic.co/job/elastic+thumbnails4j+deploy-snapshot/) for the new minor patch SNAPSHOT (`1.1.1-SNAPSHOT` in this example) and the new main SNAPSHOT (`1.2.0-SNAPSHOT` in this example) 70 | 11. Once the release artifacts are available from Maven Central, [create a new Github Release](https://github.com/elastic/thumbnails4j/releases/new) from the new tag and artifacts. 71 | 72 | ##### Publish a patch 73 | (Example, publish 1.0.1) 74 | 75 | 1. Manually [deploy a snapshot](https://internal-ci.elastic.co/job/elastic+thumbnails4j+deploy-snapshot/) from the release branch (`1.0` in this example) to ensure that there are no issues with the deploy mechanisms. 76 | 2. Verify the snapshots are in [https://oss.sonatype.org/content/repositories/snapshots/co/elastic/thumbnails4j/](https://oss.sonatype.org/content/repositories/snapshots/co/elastic/thumbnails4j/) 77 | 3. Manually [trigger a release](https://internal-ci.elastic.co/job/elastic+thumbnails4j+release/) from the minor release branch (`1.0` in this example). 78 | 4. Even after the build goes green, artifacts may take 30 minutes or so to appear in [https://repo1.maven.org/maven2/co/elastic/thumbnails4j](https://repo1.maven.org/maven2/co/elastic/thumbnails4j) 79 | 5. In the mean time, verify the automatic (or manually deploy) [snapshot build](https://internal-ci.elastic.co/job/elastic+thumbnails4j+deploy-snapshot/) for the new patch SNAPSHOT (`1.0.2-SNAPSHOT` in this example) 80 | 6. Once the release artifacts are available from Maven Central, [create a new Github Release](https://github.com/elastic/thumbnails4j/releases/new) from the new tag and artifacts. 81 | 82 | 83 | ### Known usages 84 | * Elastic Enterprise Search uses thumbnails4j to generate thumbnail images for its Workplace Search product. 85 | 86 | Are you using thumbnails4j? If so, add your usecase here! -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | This product contains code copied from org.apache.poi:poi-examples:4.1.2. 5 | 6 | =========================================== 7 | Third party libraries used by thumbnails4j: 8 | =========================================== 9 | 10 | Apache Commons Codec under Apache License, Version 2.0 11 | Apache Commons Collections under Apache License, Version 2.0 12 | Apache Commons Compress under Apache License, Version 2.0 13 | Apache Commons Logging under The Apache Software License, Version 2.0 14 | Apache Commons Math under Apache License, Version 2.0 15 | Apache FontBox under Apache License, Version 2.0 16 | Apache PDFBox under Apache License, Version 2.0 17 | Apache POI under Apache License, Version 2.0 18 | curvesapi under BSD License 19 | fr.opensagres.poi.xwpf.converter.core under The MIT License (MIT) 20 | fr.opensagres.poi.xwpf.converter.pdf under The MIT License (MIT) 21 | fr.opensagres.poi.xwpf.converter.xhtml under The MIT License (MIT) 22 | fr.opensagres.xdocreport.converter under The MIT License (MIT) 23 | fr.opensagres.xdocreport.converter.docx.xwpf under The MIT License (MIT) 24 | fr.opensagres.xdocreport.core under The MIT License (MIT) 25 | fr.opensagres.xdocreport.itext.extension under The MIT License (MIT) 26 | OOXML schemas under The Apache Software License, Version 2.0 27 | SLF4J API Module under MIT License 28 | SparseBitSet under The Apache Software License, Version 2.0 29 | thumbnails4j-core under The Apache Software License, Version 2.0 30 | thumbnails4j-doc under The Apache Software License, Version 2.0 31 | thumbnails4j-docx under The Apache Software License, Version 2.0 32 | thumbnails4j-image under The Apache Software License, Version 2.0 33 | thumbnails4j-pdf under The Apache Software License, Version 2.0 34 | thumbnails4j-pptx under The Apache Software License, Version 2.0 35 | thumbnails4j-xls under The Apache Software License, Version 2.0 36 | thumbnails4j-xlsx under The Apache Software License, Version 2.0 37 | XmlBeans under The Apache Software License, Version 2.0 38 | 39 | -------------------------------------------------------------------------------- /NOTICE.txt.template: -------------------------------------------------------------------------------- 1 | thumbnails4j 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | This product contains code copied from org.apache.poi:poi-examples:4.1.2. 5 | 6 | =========================================== 7 | Third party libraries used by thumbnails4j: 8 | =========================================== 9 | 10 | #GENERATED_NOTICES# -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![thumbnails4j](./docs/images/thumbnails4j-color-logomark.png) 2 | # thumbnails4j 3 | Open source project for generating file thumbnails with the JVM 4 | 5 | ### Example usage 6 | 7 | ```java 8 | import co.elastic.thumbnails4j.core.Dimensions; 9 | import co.elastic.thumbnails4j.pdf.PDFThumbnailer; 10 | 11 | File input = new File("/path/to/my_file.pdf"); 12 | Thumbnailer thumbnailer = new PDFThumbnailer(); 13 | List outputDimensions = Collections.singletonList(new Dimensions(100, 100)); 14 | BufferedImage output = thumbnailer.getThumbnails(input, outputDimensions).get(0); 15 | ``` 16 | 17 | ### Building 18 | 19 | To build locally, run: 20 | ```bash 21 | ./mvnw clean install 22 | ``` 23 | 24 | ### Where do I report issues with thumbnails4j? 25 | If something is not working as expected, please open an [issue](https://github.com/elastic/thumbnails4j/issues/new). 26 | 27 | ### Where can I go to get help? 28 | The Workplace Search team at Elastic maintains this library and are happy to help. Try posting your question to the 29 | [Elastic Workplace Search discuss forums](https://discuss.elastic.co/c/workplace-search). Be sure to mention that you're 30 | using thumbnails4j and also let us know what file type you're trying to thumbnail, and any errors/issues you are 31 | encountering. You can also find us in the `#enterprise-workplace-search` channel of the 32 | [Elastic Community Slack](elasticstack.slack.com). 33 | 34 | ### Contribute 🚀 35 | We welcome contributors to the project. Before you begin, a couple notes... 36 | * Read the [thumbnails4j Contributor's Guide](https://github.com/elastic/thumbnails4j/blob/main/CONTRIBUTING.md). 37 | * Prior to opening a pull request, please: 38 | * [Create an issue](https://github.com/elastic/thumbnails4j/issues) to discuss the scope of your proposal. 39 | * Sign the [Contributor License Agreement](https://www.elastic.co/contributor-agreement/). We are not asking you to 40 | assign copyright to us, but to give us the right to distribute your code without restriction. We ask this of all 41 | contributors in order to assure our users of the origin and continuing existence of the code. You only need to sign 42 | the CLA once. 43 | * Please write simple code and concise documentation, when appropriate. 44 | -------------------------------------------------------------------------------- /catalog-info.yaml: -------------------------------------------------------------------------------- 1 | ######################################################################### 2 | ###################### catalog-info for ent-search ###################### 3 | # Declare a Backstage Component for ent-search 4 | # When doing changes validate them using https://backstage.elastic.dev/entity-validation 5 | --- 6 | # yaml-language-server: $schema=https://json.schemastore.org/catalog-info.json 7 | apiVersion: "backstage.io/v1alpha1" 8 | kind: "Component" 9 | metadata: 10 | name: "thumbnails4j" 11 | description: "thumbnails4j" 12 | annotations: 13 | backstage.io/source-location: "url:https://github.com/elastic/thumbnails4j/" 14 | github.com/project-slug: "elastic/thumbnails4j" 15 | github.com/team-slug: "elastic/enterprise-search" 16 | buildkite.com/project-slug: "elastic/thumbnails4j" 17 | tags: 18 | - "thumbnails4j" 19 | - "enterprise-search" 20 | - "buildkite" 21 | spec: 22 | type: "library" 23 | system: "enterprise-search" 24 | lifecycle: "production" 25 | owner: "group:enterprise-search" 26 | 27 | --- 28 | # yaml-language-server: $schema=https://gist.githubusercontent.com/elasticmachine/988b80dae436cafea07d9a4a460a011d/raw/rre.schema.json 29 | # Primary pipeline on PR / Commit 30 | 31 | apiVersion: backstage.io/v1alpha1 32 | kind: Resource 33 | metadata: 34 | name: buildkite-pipeline-thumbnails4j 35 | description: Buildkite Pipeline for thumbnails4j 36 | links: 37 | - title: Thumbnails4J 38 | url: https://buildkite.com/elastic/thumbnails4j 39 | 40 | spec: 41 | type: buildkite-pipeline 42 | owner: group:enterprise-search 43 | system: buildkite 44 | implementation: 45 | apiVersion: buildkite.elastic.dev/v1 46 | kind: Pipeline 47 | metadata: 48 | name: thumbnails4j 49 | spec: 50 | repository: elastic/thumbnails4j 51 | pipeline_file: ".buildkite/pipeline.yml" 52 | teams: 53 | enterprise-search: 54 | access_level: "MANAGE_BUILD_AND_READ" 55 | everyone: 56 | access_level: READ_ONLY 57 | 58 | --- 59 | # yaml-language-server: $schema=https://gist.githubusercontent.com/elasticmachine/988b80dae436cafea07d9a4a460a011d/raw/rre.schema.json 60 | apiVersion: backstage.io/v1alpha1 61 | kind: Resource 62 | metadata: 63 | name: buildkite-deploy-snapshot-pipeline-thumbnails4j 64 | description: Deploy Snapshot Buildkite Pipeline for thumbnails4j 65 | links: 66 | - title: Thumbnails4J 67 | url: https://buildkite.com/elastic/thumbnails4j 68 | 69 | spec: 70 | type: buildkite-pipeline 71 | owner: group:enterprise-search 72 | system: buildkite 73 | implementation: 74 | apiVersion: buildkite.elastic.dev/v1 75 | kind: Pipeline 76 | metadata: 77 | name: thumbnails4j-deploy 78 | spec: 79 | repository: elastic/thumbnails4j 80 | pipeline_file: ".buildkite/deploy_snapshot_pipeline.yml" 81 | provider_settings: 82 | trigger_mode: "none" 83 | schedules: 84 | Daily_Run: 85 | branch: 'master' 86 | message: "Runs daily snapshot deployment" 87 | cronline: "15 6 * * *" 88 | teams: 89 | enterprise-search: 90 | access_level: "MANAGE_BUILD_AND_READ" 91 | everyone: 92 | access_level: READ_ONLY 93 | 94 | --- 95 | # yaml-language-server: $schema=https://gist.githubusercontent.com/elasticmachine/988b80dae436cafea07d9a4a460a011d/raw/rre.schema.json 96 | # Release deployment pipeline 97 | 98 | apiVersion: backstage.io/v1alpha1 99 | kind: Resource 100 | metadata: 101 | name: buildkite-release-pipeline-thumbnails4j 102 | description: Deploy Snapshot Buildkite Pipeline for thumbnails4j 103 | links: 104 | - title: Thumbnails4J 105 | url: https://buildkite.com/elastic/thumbnails4j 106 | 107 | spec: 108 | type: buildkite-pipeline 109 | owner: group:enterprise-search 110 | system: buildkite 111 | implementation: 112 | apiVersion: buildkite.elastic.dev/v1 113 | kind: Pipeline 114 | metadata: 115 | name: thumbnails4j-release 116 | spec: 117 | repository: elastic/thumbnails4j 118 | pipeline_file: ".buildkite/release_pipeline.yml" 119 | provider_settings: 120 | trigger_mode: "none" 121 | teams: 122 | enterprise-search: 123 | access_level: "MANAGE_BUILD_AND_READ" 124 | everyone: 125 | access_level: READ_ONLY 126 | -------------------------------------------------------------------------------- /docs/images/thumbnails4j-@1200x1200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/docs/images/thumbnails4j-@1200x1200.png -------------------------------------------------------------------------------- /docs/images/thumbnails4j-@1200x628.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/docs/images/thumbnails4j-@1200x628.png -------------------------------------------------------------------------------- /docs/images/thumbnails4j-color-logomark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/docs/images/thumbnails4j-color-logomark.png -------------------------------------------------------------------------------- /docs/images/thumbnails4j-color-logomark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 12 | 13 | 14 | 15 | 17 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/images/thumbnails4j-color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/docs/images/thumbnails4j-color.png -------------------------------------------------------------------------------- /docs/images/thumbnails4j-color.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 12 | 13 | 15 | 17 | 19 | 22 | 25 | 27 | 30 | 31 | 32 | 35 | 37 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | fi 118 | 119 | if [ -z "$JAVA_HOME" ]; then 120 | javaExecutable="`which javac`" 121 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 122 | # readlink(1) is not available as standard on Solaris 10. 123 | readLink=`which readlink` 124 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 125 | if $darwin ; then 126 | javaHome="`dirname \"$javaExecutable\"`" 127 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 128 | else 129 | javaExecutable="`readlink -f \"$javaExecutable\"`" 130 | fi 131 | javaHome="`dirname \"$javaExecutable\"`" 132 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 133 | JAVA_HOME="$javaHome" 134 | export JAVA_HOME 135 | fi 136 | fi 137 | fi 138 | 139 | if [ -z "$JAVACMD" ] ; then 140 | if [ -n "$JAVA_HOME" ] ; then 141 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 142 | # IBM's JDK on AIX uses strange locations for the executables 143 | JAVACMD="$JAVA_HOME/jre/sh/java" 144 | else 145 | JAVACMD="$JAVA_HOME/bin/java" 146 | fi 147 | else 148 | JAVACMD="`which java`" 149 | fi 150 | fi 151 | 152 | if [ ! -x "$JAVACMD" ] ; then 153 | echo "Error: JAVA_HOME is not defined correctly." >&2 154 | echo " We cannot execute $JAVACMD" >&2 155 | exit 1 156 | fi 157 | 158 | if [ -z "$JAVA_HOME" ] ; then 159 | echo "Warning: JAVA_HOME environment variable is not set." 160 | fi 161 | 162 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 163 | 164 | # traverses directory structure from process work directory to filesystem root 165 | # first directory with .mvn subdirectory is considered project base directory 166 | find_maven_basedir() { 167 | 168 | if [ -z "$1" ] 169 | then 170 | echo "Path not specified to find_maven_basedir" 171 | return 1 172 | fi 173 | 174 | basedir="$1" 175 | wdir="$1" 176 | while [ "$wdir" != '/' ] ; do 177 | if [ -d "$wdir"/.mvn ] ; then 178 | basedir=$wdir 179 | break 180 | fi 181 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 182 | if [ -d "${wdir}" ]; then 183 | wdir=`cd "$wdir/.."; pwd` 184 | fi 185 | # end of workaround 186 | done 187 | echo "${basedir}" 188 | } 189 | 190 | # concatenates all lines of a file 191 | concat_lines() { 192 | if [ -f "$1" ]; then 193 | echo "$(tr -s '\n' ' ' < "$1")" 194 | fi 195 | } 196 | 197 | BASE_DIR=`find_maven_basedir "$(pwd)"` 198 | if [ -z "$BASE_DIR" ]; then 199 | exit 1; 200 | fi 201 | 202 | ########################################################################################## 203 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 204 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 205 | ########################################################################################## 206 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 207 | if [ "$MVNW_VERBOSE" = true ]; then 208 | echo "Found .mvn/wrapper/maven-wrapper.jar" 209 | fi 210 | else 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 213 | fi 214 | if [ -n "$MVNW_REPOURL" ]; then 215 | jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 216 | else 217 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 218 | fi 219 | while IFS="=" read key value; do 220 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 221 | esac 222 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 223 | if [ "$MVNW_VERBOSE" = true ]; then 224 | echo "Downloading from: $jarUrl" 225 | fi 226 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 227 | if $cygwin; then 228 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 229 | fi 230 | 231 | if command -v wget > /dev/null; then 232 | if [ "$MVNW_VERBOSE" = true ]; then 233 | echo "Found wget ... using wget" 234 | fi 235 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 236 | wget "$jarUrl" -O "$wrapperJarPath" 237 | else 238 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" 239 | fi 240 | elif command -v curl > /dev/null; then 241 | if [ "$MVNW_VERBOSE" = true ]; then 242 | echo "Found curl ... using curl" 243 | fi 244 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 245 | curl -o "$wrapperJarPath" "$jarUrl" -f 246 | else 247 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 248 | fi 249 | 250 | else 251 | if [ "$MVNW_VERBOSE" = true ]; then 252 | echo "Falling back to using Java to download" 253 | fi 254 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 255 | # For Cygwin, switch paths to Windows format before running javac 256 | if $cygwin; then 257 | javaClass=`cygpath --path --windows "$javaClass"` 258 | fi 259 | if [ -e "$javaClass" ]; then 260 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 261 | if [ "$MVNW_VERBOSE" = true ]; then 262 | echo " - Compiling MavenWrapperDownloader.java ..." 263 | fi 264 | # Compiling the Java class 265 | ("$JAVA_HOME/bin/javac" "$javaClass") 266 | fi 267 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 268 | # Running the downloader 269 | if [ "$MVNW_VERBOSE" = true ]; then 270 | echo " - Running MavenWrapperDownloader.java ..." 271 | fi 272 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 273 | fi 274 | fi 275 | fi 276 | fi 277 | ########################################################################################## 278 | # End of extension 279 | ########################################################################################## 280 | 281 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 282 | if [ "$MVNW_VERBOSE" = true ]; then 283 | echo $MAVEN_PROJECTBASEDIR 284 | fi 285 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 286 | 287 | # For Cygwin, switch paths to Windows format before running java 288 | if $cygwin; then 289 | [ -n "$M2_HOME" ] && 290 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 291 | [ -n "$JAVA_HOME" ] && 292 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 293 | [ -n "$CLASSPATH" ] && 294 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 295 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 296 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 297 | fi 298 | 299 | # Provide a "standardized" way to retrieve the CLI args that will 300 | # work with both Windows and non-Windows executions. 301 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 302 | export MAVEN_CMD_LINE_ARGS 303 | 304 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 305 | 306 | exec "$JAVACMD" \ 307 | $MAVEN_OPTS \ 308 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 309 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 310 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 311 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 124 | 125 | FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 162 | if ERRORLEVEL 1 goto error 163 | goto end 164 | 165 | :error 166 | set ERROR_CODE=1 167 | 168 | :end 169 | @endlocal & set ERROR_CODE=%ERROR_CODE% 170 | 171 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 172 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 173 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 174 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 175 | :skipRcPost 176 | 177 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 178 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 179 | 180 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 181 | 182 | exit /B %ERROR_CODE% 183 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | This product contains code copied from org.apache.poi:poi-examples:4.1.2. 5 | 6 | =========================================== 7 | Third party libraries used by thumbnails4j: 8 | =========================================== 9 | 10 | Apache Commons Codec under Apache License, Version 2.0 11 | Apache Commons Collections under Apache License, Version 2.0 12 | Apache Commons Compress under Apache License, Version 2.0 13 | Apache Commons Logging under The Apache Software License, Version 2.0 14 | Apache Commons Math under Apache License, Version 2.0 15 | Apache FontBox under Apache License, Version 2.0 16 | Apache PDFBox under Apache License, Version 2.0 17 | Apache POI under Apache License, Version 2.0 18 | curvesapi under BSD License 19 | fr.opensagres.poi.xwpf.converter.core under The MIT License (MIT) 20 | fr.opensagres.poi.xwpf.converter.pdf under The MIT License (MIT) 21 | fr.opensagres.poi.xwpf.converter.xhtml under The MIT License (MIT) 22 | fr.opensagres.xdocreport.converter under The MIT License (MIT) 23 | fr.opensagres.xdocreport.converter.docx.xwpf under The MIT License (MIT) 24 | fr.opensagres.xdocreport.core under The MIT License (MIT) 25 | fr.opensagres.xdocreport.itext.extension under The MIT License (MIT) 26 | OOXML schemas under The Apache Software License, Version 2.0 27 | SLF4J API Module under MIT License 28 | SparseBitSet under The Apache Software License, Version 2.0 29 | thumbnails4j-core under The Apache Software License, Version 2.0 30 | thumbnails4j-doc under The Apache Software License, Version 2.0 31 | thumbnails4j-docx under The Apache Software License, Version 2.0 32 | thumbnails4j-image under The Apache Software License, Version 2.0 33 | thumbnails4j-pdf under The Apache Software License, Version 2.0 34 | thumbnails4j-pptx under The Apache Software License, Version 2.0 35 | thumbnails4j-xls under The Apache Software License, Version 2.0 36 | thumbnails4j-xlsx under The Apache Software License, Version 2.0 37 | XmlBeans under The Apache Software License, Version 2.0 38 | 39 | -------------------------------------------------------------------------------- /thumbnails4j-all/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-all 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | This product contains code copied from org.apache.poi:poi-examples:4.1.2. 5 | 6 | ============================================== 7 | Third party libraries used by thumbnails4j-all: 8 | ============================================== 9 | 10 | Apache Commons Codec under Apache License, Version 2.0 11 | Apache Commons Collections under Apache License, Version 2.0 12 | Apache Commons Compress under Apache License, Version 2.0 13 | Apache Commons Logging under The Apache Software License, Version 2.0 14 | Apache Commons Math under Apache License, Version 2.0 15 | Apache FontBox under Apache License, Version 2.0 16 | Apache PDFBox under Apache License, Version 2.0 17 | Apache POI under Apache License, Version 2.0 18 | curvesapi under BSD License 19 | Extended StAX API under Eclipse Distribution License - v 1.0 20 | fastinfoset under Apache License, Version 2.0 or Eclipse Distribution License - v 1.0 21 | fr.opensagres.poi.xwpf.converter.core under The MIT License (MIT) 22 | fr.opensagres.poi.xwpf.converter.pdf under The MIT License (MIT) 23 | fr.opensagres.poi.xwpf.converter.xhtml under The MIT License (MIT) 24 | fr.opensagres.xdocreport.converter under The MIT License (MIT) 25 | fr.opensagres.xdocreport.converter.docx.xwpf under The MIT License (MIT) 26 | fr.opensagres.xdocreport.core under The MIT License (MIT) 27 | fr.opensagres.xdocreport.itext.extension under The MIT License (MIT) 28 | istack common utility code runtime under Eclipse Distribution License - v 1.0 29 | jakarta.xml.bind-api under Eclipse Distribution License - v 1.0 30 | JavaBeans Activation Framework API jar under EDL 1.0 31 | JAXB Runtime under Eclipse Distribution License - v 1.0 32 | OOXML schemas under The Apache Software License, Version 2.0 33 | SLF4J API Module under MIT License 34 | SparseBitSet under The Apache Software License, Version 2.0 35 | thumbnails4j-core under The Apache Software License, Version 2.0 36 | thumbnails4j-doc under The Apache Software License, Version 2.0 37 | thumbnails4j-docx under The Apache Software License, Version 2.0 38 | thumbnails4j-image under The Apache Software License, Version 2.0 39 | thumbnails4j-pdf under The Apache Software License, Version 2.0 40 | thumbnails4j-pptx under The Apache Software License, Version 2.0 41 | thumbnails4j-xls under The Apache Software License, Version 2.0 42 | thumbnails4j-xlsx under The Apache Software License, Version 2.0 43 | TXW2 Runtime under Eclipse Distribution License - v 1.0 44 | XmlBeans under The Apache Software License, Version 2.0 45 | 46 | -------------------------------------------------------------------------------- /thumbnails4j-all/NOTICE.txt.template: -------------------------------------------------------------------------------- 1 | thumbnails4j-all 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | This product contains code copied from org.apache.poi:poi-examples:4.1.2. 5 | 6 | ============================================== 7 | Third party libraries used by thumbnails4j-all: 8 | ============================================== 9 | 10 | #GENERATED_NOTICES# -------------------------------------------------------------------------------- /thumbnails4j-all/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | thumbnails4j 5 | co.elastic.thumbnails4j 6 | 1.2.0-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | thumbnails4j-all 11 | 12 | 13 | 8 14 | 8 15 | 16 | 17 | 18 | 19 | co.elastic.thumbnails4j 20 | thumbnails4j-core 21 | ${project.version} 22 | 23 | 24 | co.elastic.thumbnails4j 25 | thumbnails4j-doc 26 | ${project.version} 27 | 28 | 29 | co.elastic.thumbnails4j 30 | thumbnails4j-docx 31 | ${project.version} 32 | 33 | 34 | co.elastic.thumbnails4j 35 | thumbnails4j-image 36 | ${project.version} 37 | 38 | 39 | co.elastic.thumbnails4j 40 | thumbnails4j-pdf 41 | ${project.version} 42 | 43 | 44 | co.elastic.thumbnails4j 45 | thumbnails4j-pptx 46 | ${project.version} 47 | 48 | 49 | co.elastic.thumbnails4j 50 | thumbnails4j-xls 51 | ${project.version} 52 | 53 | 54 | co.elastic.thumbnails4j 55 | thumbnails4j-xlsx 56 | ${project.version} 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /thumbnails4j-all/src/main/resources/META-INF/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /thumbnails4j-all/src/main/resources/META-INF/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-all 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | This product contains code copied from org.apache.poi:poi-examples:4.1.2. 5 | 6 | ============================================== 7 | Third party libraries used by thumbnails4j-all: 8 | ============================================== 9 | 10 | Apache Commons Codec under Apache License, Version 2.0 11 | Apache Commons Collections under Apache License, Version 2.0 12 | Apache Commons Compress under Apache License, Version 2.0 13 | Apache Commons Logging under The Apache Software License, Version 2.0 14 | Apache Commons Math under Apache License, Version 2.0 15 | Apache FontBox under Apache License, Version 2.0 16 | Apache PDFBox under Apache License, Version 2.0 17 | Apache POI under Apache License, Version 2.0 18 | curvesapi under BSD License 19 | Extended StAX API under Eclipse Distribution License - v 1.0 20 | fastinfoset under Apache License, Version 2.0 or Eclipse Distribution License - v 1.0 21 | fr.opensagres.poi.xwpf.converter.core under The MIT License (MIT) 22 | fr.opensagres.poi.xwpf.converter.pdf under The MIT License (MIT) 23 | fr.opensagres.poi.xwpf.converter.xhtml under The MIT License (MIT) 24 | fr.opensagres.xdocreport.converter under The MIT License (MIT) 25 | fr.opensagres.xdocreport.converter.docx.xwpf under The MIT License (MIT) 26 | fr.opensagres.xdocreport.core under The MIT License (MIT) 27 | fr.opensagres.xdocreport.itext.extension under The MIT License (MIT) 28 | istack common utility code runtime under Eclipse Distribution License - v 1.0 29 | jakarta.xml.bind-api under Eclipse Distribution License - v 1.0 30 | JavaBeans Activation Framework API jar under EDL 1.0 31 | JAXB Runtime under Eclipse Distribution License - v 1.0 32 | OOXML schemas under The Apache Software License, Version 2.0 33 | SLF4J API Module under MIT License 34 | SparseBitSet under The Apache Software License, Version 2.0 35 | thumbnails4j-core under The Apache Software License, Version 2.0 36 | thumbnails4j-doc under The Apache Software License, Version 2.0 37 | thumbnails4j-docx under The Apache Software License, Version 2.0 38 | thumbnails4j-image under The Apache Software License, Version 2.0 39 | thumbnails4j-pdf under The Apache Software License, Version 2.0 40 | thumbnails4j-pptx under The Apache Software License, Version 2.0 41 | thumbnails4j-xls under The Apache Software License, Version 2.0 42 | thumbnails4j-xlsx under The Apache Software License, Version 2.0 43 | TXW2 Runtime under Eclipse Distribution License - v 1.0 44 | XmlBeans under The Apache Software License, Version 2.0 45 | 46 | -------------------------------------------------------------------------------- /thumbnails4j-core/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-core 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | ================================================ 6 | Third party libraries used by thumbnails4j-core: 7 | ================================================ 8 | 9 | SLF4J API Module under MIT License 10 | 11 | -------------------------------------------------------------------------------- /thumbnails4j-core/NOTICE.txt.template: -------------------------------------------------------------------------------- 1 | thumbnails4j-core 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | ================================================ 6 | Third party libraries used by thumbnails4j-core: 7 | ================================================ 8 | 9 | #GENERATED_NOTICES# -------------------------------------------------------------------------------- /thumbnails4j-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | thumbnails4j 5 | co.elastic.thumbnails4j 6 | 1.2.0-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | thumbnails4j-core 11 | 12 | 13 | 8 14 | 8 15 | 16 | 17 | 18 | 19 | org.slf4j 20 | slf4j-api 21 | 22 | 23 | 24 | 25 | org.spockframework 26 | spock-core 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /thumbnails4j-core/src/main/java/co/elastic/thumbnails4j/core/Dimensions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.core; 23 | 24 | /** 25 | * A simple Java Bean to represent two dimensions. X and Y, or, Width and Height. 26 | */ 27 | public class Dimensions { 28 | public int x; 29 | public int y; 30 | 31 | /** 32 | * Create a new instance of {@link Dimensions} with the specified width and height 33 | * @param width the width, or x, for these dimensions 34 | * @param height the height, or y, for these dimensions 35 | */ 36 | public Dimensions(int width, int height){ 37 | this.x = width; 38 | this.y = height; 39 | } 40 | 41 | /** 42 | * @return the x, or width, of these dimensions. Identical to {@link Dimensions#getWidth()} 43 | */ 44 | public int getX() { 45 | return x; 46 | } 47 | 48 | /** 49 | * @return the width, or x, of these dimensions. Identical to {@link Dimensions#getX()} 50 | */ 51 | public int getWidth() { 52 | return x; 53 | } 54 | 55 | /** 56 | * Change the x, or width, of these dimensions. Identical to {@link Dimensions#setWidth(int)} 57 | * @param x the new x, or width, to be set. 58 | */ 59 | public void setX(int x) { 60 | this.x = x; 61 | } 62 | 63 | /** 64 | * Change the width, or x, of these dimensions. Identical to {@link Dimensions#setX(int)} 65 | * @param width the new width, or x, to be set. 66 | */ 67 | public void setWidth(int width) { 68 | this.x = width; 69 | } 70 | 71 | /** 72 | * @return the y, or height, of these dimensions. Identical to {@link Dimensions#getHeight()} 73 | */ 74 | public int getY() { 75 | return y; 76 | } 77 | 78 | /** 79 | * @return the height, or y, of these dimensions. Identical to {@link Dimensions#getY()} 80 | */ 81 | public int getHeight() { 82 | return y; 83 | } 84 | 85 | /** 86 | * Change the y, or height, of these dimensions. Identical to {@link Dimensions#setHeight(int)} 87 | * @param y the new y, or height, to be set. 88 | */ 89 | public void setY(int y) { 90 | this.y = y; 91 | } 92 | 93 | /** 94 | * Change the height, or y, of these dimensions. Identical to {@link Dimensions#setY(int)} 95 | * @param height the new height, or y, to be set. 96 | */ 97 | public void setHeight(int height) { 98 | this.y = height; 99 | } 100 | 101 | /** 102 | * Whether this {@link Dimensions}, represented as a rectangle with corresponding width and height, could fit inside 103 | * the rectangle corresponding to {@code other} without any of the lines/sides intersecting. 104 | * @param other the other {@link Dimensions} to compare against. 105 | * @return true if this object is smaller-than-or-equal in both width and height to {@code other} 106 | */ 107 | public boolean does_fit_inside(Dimensions other){ 108 | return this.x <= other.getX() && this.y <= other.getY(); 109 | } 110 | 111 | @Override 112 | public boolean equals(Object o) { 113 | if (this == o) return true; 114 | if (!(o instanceof Dimensions)) return false; 115 | 116 | Dimensions that = (Dimensions) o; 117 | 118 | if (getX() != that.getX()) return false; 119 | return getY() == that.getY(); 120 | } 121 | 122 | @Override 123 | public int hashCode() { 124 | int result = getX(); 125 | result = 31 * result + getY(); 126 | return result; 127 | } 128 | 129 | @Override 130 | public String toString() { 131 | return "[" + x + ", " + y + "]"; 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /thumbnails4j-core/src/main/java/co/elastic/thumbnails4j/core/ThumbnailUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.core; 23 | 24 | import javax.swing.*; 25 | import javax.xml.transform.OutputKeys; 26 | import javax.xml.transform.Transformer; 27 | import javax.xml.transform.TransformerConfigurationException; 28 | import javax.xml.transform.TransformerFactory; 29 | import java.awt.*; 30 | import java.awt.geom.Rectangle2D; 31 | import java.awt.image.BufferedImage; 32 | import java.io.UnsupportedEncodingException; 33 | import java.nio.charset.StandardCharsets; 34 | 35 | /** 36 | * A utility class containing common methods used for generating thumbnails, regardless of the source document type. 37 | */ 38 | public class ThumbnailUtils { 39 | 40 | private static Dimensions MAX_IN_MEMORY_BUFFER = new Dimensions(310, 430); 41 | 42 | /** 43 | * @return The largest allowed {@link Dimensions} to attempt to write an image into. By default, 310 pixels by 430 pixels 44 | */ 45 | public static Dimensions getMaxInMemoryBuffer() { 46 | return MAX_IN_MEMORY_BUFFER; 47 | } 48 | 49 | /** 50 | * @param maxInMemoryBuffer the new maximum {@link Dimensions} to allow an image to be written into. 51 | */ 52 | public static void setMaxInMemoryBuffer(Dimensions maxInMemoryBuffer) { 53 | MAX_IN_MEMORY_BUFFER = maxInMemoryBuffer; 54 | } 55 | 56 | /** 57 | * Scale the provided image to the provided dimensions. 58 | * 59 | * This algorithm is based off: https://community.oracle.com/docs/DOC-983611 60 | * Fundamentally, it scales the images down progressively by halves, until 61 | * it reaches the desired width/height. By doing this, more of the original 62 | * image quality is preserved. 63 | * 64 | * @param image the image to scale 65 | * @param dimensions the dimensions to scale the image to 66 | * @return The scaled image. Note the scaled image will be of the same image type as the provided image. 67 | */ 68 | public static BufferedImage scaleImage(BufferedImage image, Dimensions dimensions){ 69 | return scaleImage(image, dimensions, image.getType()); 70 | } 71 | 72 | /** 73 | * Scale the provided image to the provided dimensions. 74 | * 75 | * This algorithm is based off: https://community.oracle.com/docs/DOC-983611 76 | * Fundamentally, it scales the images down progressively by halves, until 77 | * it reaches the desired width/height. By doing this, more of the original 78 | * image quality is preserved. 79 | * 80 | * @param image the image to scale 81 | * @param dimensions the dimensions to scale the image to 82 | * @param imageType the {@link BufferedImage} type (for example, {@link BufferedImage#TYPE_INT_RGB} the resulting 83 | * image should be written as. 84 | * @return The scaled image of the specified type. 85 | */ 86 | public static BufferedImage scaleImage(BufferedImage image, Dimensions dimensions, int imageType){ 87 | int scaledWidth = image.getWidth(); 88 | int scaledHeight = image.getHeight(); 89 | 90 | double widthRatio = ((double)scaledWidth)/dimensions.getWidth(); 91 | double heightRatio = ((double) scaledHeight)/dimensions.getHeight(); 92 | 93 | double aspectRatio = Math.max(widthRatio, heightRatio); 94 | int targetWidth = (int) Math.round(scaledWidth/aspectRatio); 95 | int targetHeight = (int) Math.round(scaledHeight/aspectRatio); 96 | 97 | // until we reach the desired width/height 98 | while (scaledWidth != targetWidth || scaledHeight != targetHeight) { 99 | scaledWidth = scaleDimension(scaledWidth, targetWidth); 100 | scaledHeight = scaleDimension(scaledHeight, targetHeight); 101 | 102 | // redraw the image with the new width/height for this iteration 103 | BufferedImage temp = new BufferedImage(scaledWidth, scaledHeight, imageType); 104 | Graphics2D graphics = temp.createGraphics(); 105 | graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); 106 | graphics.drawImage(image, 0, 0, scaledWidth, scaledHeight, null); 107 | graphics.dispose(); 108 | image = temp; 109 | } 110 | 111 | return image; 112 | } 113 | 114 | /** 115 | * Given {@link ThumbnailUtils#getMaxInMemoryBuffer()}, resize the provided dimensions, while maintaining aspect 116 | * ratio, to ensure memory requirements are not exceeded. 117 | * @param dimensions the initial dimensions 118 | * @return the input dimensions if they would fit it the max-memory buffer. Otherwise, a scaled-down version of the 119 | * input dimensions that will fit in the max-memory buffer. 120 | */ 121 | public static Dimensions memoryOptimiseDimension(Dimensions dimensions){ 122 | if(dimensions.does_fit_inside(MAX_IN_MEMORY_BUFFER)){ 123 | return dimensions; 124 | } else { 125 | double givenXYRatio = ((double) dimensions.getWidth()) / (dimensions.getHeight()); 126 | Dimensions result = new Dimensions(dimensions.getWidth(), dimensions.getHeight()); 127 | double destXYRatio = ((double) MAX_IN_MEMORY_BUFFER.getWidth()) / (MAX_IN_MEMORY_BUFFER.getHeight()); 128 | if (givenXYRatio > destXYRatio) { 129 | // X is the limiting factor 130 | result.setWidth(MAX_IN_MEMORY_BUFFER.getWidth()); 131 | result.setHeight((int)(((double) MAX_IN_MEMORY_BUFFER.getWidth()) / givenXYRatio)); 132 | } else { 133 | // Y is the limiting factor 134 | result.setHeight(MAX_IN_MEMORY_BUFFER.getHeight()); 135 | result.setWidth((int)(MAX_IN_MEMORY_BUFFER.getHeight() * givenXYRatio)); 136 | } 137 | return result; 138 | } 139 | } 140 | 141 | /** 142 | * @return a transformer capable of reading an XHTML DOM 143 | * @throws TransformerConfigurationException 144 | */ 145 | public static Transformer getTransformerForXhtmlDOM() throws TransformerConfigurationException { 146 | Transformer transformer = TransformerFactory.newInstance().newTransformer(); 147 | transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 148 | transformer.setOutputProperty(OutputKeys.METHOD, "xml"); // see https://stackoverflow.com/a/5126973/2479282. JPaneEditor uses an xml parser for html 149 | transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 150 | return transformer; 151 | } 152 | 153 | /** 154 | * Renter an image from an HTML UI component 155 | * @param htmlComponent a {@link JEditorPane} that contains HTML. See also {@link ThumbnailUtils#scaleHtmlToImage(byte[], co.elastic.thumbnails4j.core.Dimensions)} 156 | * @param dimensions the desired dimensions of the output image 157 | * @return the rendered image 158 | */ 159 | public static BufferedImage htmlToImage(JEditorPane htmlComponent, Dimensions dimensions){ 160 | Dimensions optimizedDimensions = memoryOptimiseDimension(dimensions); 161 | double scale_factor = ((double) optimizedDimensions.getWidth()) / dimensions.getWidth(); 162 | BufferedImage image = new BufferedImage(optimizedDimensions.getWidth(), optimizedDimensions.getHeight(), BufferedImage.TYPE_INT_RGB); 163 | 164 | Graphics2D graphics = image.createGraphics(); 165 | graphics.setPaint(Color.white); 166 | graphics.fill(new Rectangle2D.Float(0, 0, optimizedDimensions.getWidth(), optimizedDimensions.getHeight())); 167 | graphics.scale(scale_factor, scale_factor); 168 | htmlComponent.print(graphics); 169 | graphics.dispose(); 170 | return image; 171 | } 172 | 173 | /** 174 | * Render an image from raw HTML 175 | * @param htmlBytes the raw html 176 | * @param dimensions the desired dimensions of the output image 177 | * @return the rendered image 178 | * @throws UnsupportedEncodingException if the raw HTML can not be read as a UTF-8 {@link String} 179 | */ 180 | public static BufferedImage scaleHtmlToImage(byte[] htmlBytes, Dimensions dimensions) throws UnsupportedEncodingException { 181 | JEditorPane htmlComponent = new JEditorPane("text/html", new String(htmlBytes, StandardCharsets.UTF_8)); 182 | Dimension preferredSize = htmlComponent.getPreferredSize(); 183 | int width = preferredSize.width; 184 | double ratio = ((double) width) / dimensions.getWidth(); // determine the ratio between the actual width and the expected width 185 | int height = (int) (ratio * dimensions.getHeight()); // use that ratio to set the height (ignoring actual height) 186 | htmlComponent.setSize(width, height); // this html may be much "longer" proportionally, so we "fit" it to the expected page or thumbnail size 187 | 188 | return htmlToImage(htmlComponent, new Dimensions(width, height)); 189 | } 190 | 191 | /** 192 | * Crop the upper-left {@code dimensions}-worth of an image that would be rendered from raw html. 193 | * This is particularly useful when your HTML describes a very large display, and a zoomed-out view of such a 194 | * display would be meaningless. Sometimes, its better to just show a smaller, zoomed-in, sample of the document. 195 | * @param htmlBytes the raw HTML 196 | * @param dimensions the desired dimensions to keep in the crop/clip. 197 | * @return the clipped image resulting from rendering just a portion of the raw HTML. 198 | */ 199 | public static BufferedImage clipHtmlToImage(byte[] htmlBytes, Dimensions dimensions){ 200 | JEditorPane htmlComponent = new JEditorPane("text/html", new String(htmlBytes, StandardCharsets.UTF_8)); 201 | Dimension preferredSize = htmlComponent.getPreferredSize(); 202 | htmlComponent.setSize(preferredSize.width, preferredSize.height); 203 | return htmlToImage(htmlComponent, dimensions); 204 | } 205 | 206 | private static int scaleDimension(int value, int targetValue){ 207 | if (value > targetValue) { 208 | return Math.max(value / 2, targetValue); 209 | } else if (value < targetValue) { 210 | return Math.min(value * 2, targetValue); 211 | } else { 212 | return value; 213 | } 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /thumbnails4j-core/src/main/java/co/elastic/thumbnails4j/core/Thumbnailer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.core; 23 | 24 | 25 | import java.awt.image.BufferedImage; 26 | import java.io.File; 27 | import java.io.InputStream; 28 | import java.util.List; 29 | 30 | /** 31 | * A simple interface that any thumbnail image generating engine should be able to implement. Given either a {@link File} 32 | * or an {@link InputStream} and an ordered {@link List} of {@link Dimensions}, we expect to be able to generate 33 | * thumbnail images from those binaries of the provided dimensions. 34 | */ 35 | public interface Thumbnailer { 36 | 37 | /** 38 | * Given a {@link File}, generates a {@link List} of thumbnail images of the provided {@link Dimensions} 39 | * @param input the File pointer for which to generate thumbnails. 40 | * @param dimensions the ordered list of dimensions the resulting thumbnails should be. 41 | * @return the output list of thumbnails. The order of this list matches the order of the {@code dimensions} parameter. 42 | * @throws ThumbnailingException if there was any error related to generating a thumbnail for this {@link File} 43 | */ 44 | public List getThumbnails(File input, List dimensions) throws ThumbnailingException; 45 | 46 | /** 47 | * Given an {@link InputStream}, generates a {@link List} of thumbnail images of the provided {@link Dimensions} 48 | * @param input the binary input stream containing the contents of a document for which to generate thumbnails. 49 | * @param dimensions the ordered list of dimensions the resulting thumbnails should be. 50 | * @return the output list of thumbnails. The order of this list matches the order of the {@code dimensions} parameter. 51 | * @throws ThumbnailingException if there was any error related to generating a thumbnail for this {@link InputStream} 52 | */ 53 | public List getThumbnails(InputStream input, List dimensions) throws ThumbnailingException; 54 | } 55 | -------------------------------------------------------------------------------- /thumbnails4j-core/src/main/java/co/elastic/thumbnails4j/core/ThumbnailingException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.core; 23 | 24 | /** 25 | * A generic {@link Exception} used for wrapping various exceptions that may occur while generating thumbnails. 26 | */ 27 | public class ThumbnailingException extends Exception { 28 | 29 | /** 30 | * Create a {@link ThumbnailingException} that wraps another {@link Exception} 31 | * @param e the other exception to wrap 32 | */ 33 | public ThumbnailingException(Exception e) { 34 | super(e); 35 | } 36 | 37 | /** 38 | * Create a {@link ThumbnailingException} that has a specific exception message 39 | * @param msg the message to be contained by this exception 40 | */ 41 | public ThumbnailingException(String msg) { 42 | super(msg); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /thumbnails4j-core/src/main/resources/META-INF/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /thumbnails4j-core/src/main/resources/META-INF/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-core 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | ================================================ 6 | Third party libraries used by thumbnails4j-core: 7 | ================================================ 8 | 9 | SLF4J API Module under MIT License 10 | 11 | -------------------------------------------------------------------------------- /thumbnails4j-core/src/test/java/co/elastic/thumbnails4j/core/DimensionsTest.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.core 23 | 24 | import spock.lang.Specification 25 | 26 | class DimensionsTest extends Specification { 27 | 28 | def "test toString"(){ 29 | setup: 30 | Dimensions dimensions = new Dimensions(2,3) 31 | 32 | expect: 33 | dimensions.toString() == "[2, 3]" 34 | } 35 | 36 | def "test equality and hash code"(){ 37 | expect: 38 | (dimension1 == dimension2) == is_equal 39 | (dimension1.hashCode() == dimension2.hashCode()) == hash_is_equal 40 | 41 | where: 42 | dimension1 | dimension2 | is_equal | hash_is_equal 43 | new Dimensions(1,2) | new Dimensions(2,3) | false | false 44 | new Dimensions(2,3) | new Dimensions(1,2) | false | false 45 | new Dimensions(1,2) | new Dimensions(1,2) | true | true 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /thumbnails4j-core/src/test/java/co/elastic/thumbnails4j/core/ThumbnailUtilsTest.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.core 23 | 24 | import spock.lang.Specification 25 | 26 | import javax.imageio.ImageIO 27 | import java.awt.image.BufferedImage 28 | 29 | class ThumbnailUtilsTest extends Specification { 30 | 31 | def "test that it maintains the aspect ratio"(){ 32 | setup: 33 | def inputFile = new File("src/test/resources/images/test.png") 34 | BufferedImage image = ImageIO.read(inputFile) 35 | 36 | when: 37 | def output = ThumbnailUtils.scaleImage(image, new Dimensions(target_width, target_height)) 38 | 39 | then: 40 | output.width == output_width 41 | output.height == output_height 42 | 43 | where: 44 | target_width | target_height | output_width | output_height 45 | 100 | 100 | 85 | 100 46 | 100 | 1000 | 100 | 118 47 | 1000 | 100 | 85 | 100 48 | 1000 | 1000 | 850 | 1000 49 | 510 | 600 | 510 | 600 50 | 510 | 1000 | 510 | 600 51 | 1000 | 600 | 510 | 600 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /thumbnails4j-core/src/test/resources/images/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/thumbnails4j-core/src/test/resources/images/test.png -------------------------------------------------------------------------------- /thumbnails4j-doc/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-doc 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | =============================================== 6 | Third party libraries used by thumbnails4j-doc: 7 | =============================================== 8 | 9 | Apache Commons Codec under Apache License, Version 2.0 10 | Apache Commons Collections under Apache License, Version 2.0 11 | Apache Commons Math under Apache License, Version 2.0 12 | Apache POI under Apache License, Version 2.0 13 | SLF4J API Module under MIT License 14 | SparseBitSet under The Apache Software License, Version 2.0 15 | thumbnails4j-core under The Apache Software License, Version 2.0 16 | 17 | -------------------------------------------------------------------------------- /thumbnails4j-doc/NOTICE.txt.template: -------------------------------------------------------------------------------- 1 | thumbnails4j-doc 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | =============================================== 6 | Third party libraries used by thumbnails4j-doc: 7 | =============================================== 8 | 9 | #GENERATED_NOTICES# -------------------------------------------------------------------------------- /thumbnails4j-doc/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | thumbnails4j 5 | co.elastic.thumbnails4j 6 | 1.2.0-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | thumbnails4j-doc 11 | 12 | 13 | 8 14 | 8 15 | 16 | 17 | 18 | 19 | co.elastic.thumbnails4j 20 | thumbnails4j-core 21 | ${project.version} 22 | 23 | 24 | org.apache.poi 25 | poi-scratchpad 26 | 27 | 28 | 29 | 30 | org.spockframework 31 | spock-core 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /thumbnails4j-doc/src/main/java/co/elastic/thumbnails4j/doc/DOCThumbnailer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.doc; 23 | 24 | import co.elastic.thumbnails4j.core.Dimensions; 25 | import co.elastic.thumbnails4j.core.ThumbnailUtils; 26 | import co.elastic.thumbnails4j.core.Thumbnailer; 27 | import co.elastic.thumbnails4j.core.ThumbnailingException; 28 | import org.apache.poi.hwpf.HWPFDocument; 29 | import org.apache.poi.hwpf.converter.WordToHtmlConverter; 30 | import org.apache.poi.hwpf.model.SEPX; 31 | import org.apache.poi.hwpf.model.SectionTable; 32 | import org.apache.poi.hwpf.usermodel.SectionProperties; 33 | import org.slf4j.Logger; 34 | import org.slf4j.LoggerFactory; 35 | import org.w3c.dom.Document; 36 | import org.w3c.dom.Element; 37 | import org.w3c.dom.Node; 38 | 39 | import javax.xml.parsers.DocumentBuilderFactory; 40 | import javax.xml.parsers.ParserConfigurationException; 41 | import javax.xml.transform.TransformerException; 42 | import javax.xml.transform.dom.DOMSource; 43 | import javax.xml.transform.stream.StreamResult; 44 | import java.awt.image.BufferedImage; 45 | import java.io.*; 46 | import java.util.ArrayList; 47 | import java.util.List; 48 | 49 | /** 50 | * A {@link Thumbnailer} for Microsoft Word Binary File Formatted 51 | * documents. These files typically end in a {@code .doc} extension. This is not intended to support files with a 52 | * {@code .docx} extension. 53 | * 54 | * The provided document will first be converted to HTML before it is rendered. This means that more complex formatting 55 | * that cannot be expressed in raw HTML will be lost (non-standard fonts, spacing, images, etc). 56 | */ 57 | public class DOCThumbnailer implements Thumbnailer { 58 | 59 | private static Logger logger = LoggerFactory.getLogger(DOCThumbnailer.class); 60 | 61 | @Override 62 | public List getThumbnails(File input, List dimensions) throws ThumbnailingException { 63 | try(FileInputStream fis = new FileInputStream(input)) { 64 | return getThumbnails(fis, dimensions); 65 | } catch (FileNotFoundException e) { 66 | logger.error("Could not find file {}", input.getAbsolutePath()); 67 | logger.error("With stack: ", e); 68 | throw new IllegalArgumentException(e); 69 | } catch (IOException e) { 70 | throw new ThumbnailingException(e); 71 | } 72 | } 73 | 74 | @Override 75 | public List getThumbnails(InputStream input, List dimensions) throws ThumbnailingException { 76 | try (HWPFDocument document = new HWPFDocument(input)){ 77 | byte[] htmlBytes = htmlBytesFromDoc(document); 78 | BufferedImage image = ThumbnailUtils.scaleHtmlToImage(htmlBytes, docPageDimensions(document)); 79 | List results = new ArrayList<>(); 80 | for (Dimensions singleDimension: dimensions) { 81 | results.add(ThumbnailUtils.scaleImage(image, singleDimension)); 82 | } 83 | return results; 84 | } catch (IOException|ParserConfigurationException|TransformerException e) { 85 | logger.error("Could not parse MS Word Document from input stream"); 86 | logger.error("With stack: ", e); 87 | throw new ThumbnailingException(e); 88 | } 89 | } 90 | 91 | private byte[] htmlBytesFromDoc(HWPFDocument document) throws ParserConfigurationException, TransformerException { 92 | WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); 93 | wordToHtmlConverter.processDocument(document); 94 | Document html_document = wordToHtmlConverter.getDocument(); 95 | add_margins_to_html(html_document); 96 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 97 | try { 98 | DOMSource domSource = new DOMSource(html_document); 99 | StreamResult streamResult = new StreamResult(out); 100 | ThumbnailUtils.getTransformerForXhtmlDOM().transform(domSource, streamResult); 101 | } finally { 102 | try { 103 | out.close(); 104 | } catch (IOException e) { 105 | logger.error("Possible resource leak - a problem occurred while closing the stream", e); 106 | } 107 | } 108 | return out.toByteArray(); 109 | } 110 | 111 | private void add_margins_to_html(Document html_document){ 112 | // This function is a hack to add "margins" and wrap lines for arbitrary html 113 | Node body = html_document.getElementsByTagName("body").item(0); 114 | Element page_div = html_document.createElement("div"); 115 | page_div.setAttribute("style", "width:595.4pt;margin-bottom:36.0pt;margin-top:36.0pt;margin-left:36.0pt;margin-right:36.0pt;"); 116 | while (body.getFirstChild() != null) { 117 | page_div.appendChild(body.removeChild(body.getFirstChild())); 118 | } 119 | body.appendChild(page_div); 120 | } 121 | 122 | private Dimensions docPageDimensions(HWPFDocument document){ 123 | SectionTable st = document.getSectionTable(); 124 | List sections = st.getSections(); 125 | SectionProperties sectionProperties = sections.get(0).getSectionProperties(); 126 | return new Dimensions(sectionProperties.getXaPage(), sectionProperties.getYaPage()); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /thumbnails4j-doc/src/main/resources/META-INF/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /thumbnails4j-doc/src/main/resources/META-INF/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-doc 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | =============================================== 6 | Third party libraries used by thumbnails4j-doc: 7 | =============================================== 8 | 9 | Apache Commons Codec under Apache License, Version 2.0 10 | Apache Commons Collections under Apache License, Version 2.0 11 | Apache Commons Math under Apache License, Version 2.0 12 | Apache POI under Apache License, Version 2.0 13 | SLF4J API Module under MIT License 14 | SparseBitSet under The Apache Software License, Version 2.0 15 | thumbnails4j-core under The Apache Software License, Version 2.0 16 | 17 | -------------------------------------------------------------------------------- /thumbnails4j-doc/src/test/java/co/elastic/thumbnails4j/doc/DOCThumbnailerTest.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.doc 23 | 24 | import co.elastic.thumbnails4j.core.Dimensions 25 | import co.elastic.thumbnails4j.core.Thumbnailer 26 | import spock.lang.Specification 27 | 28 | import javax.imageio.ImageIO 29 | 30 | class DOCThumbnailerTest extends Specification { 31 | 32 | def "test .doc thumbnailing"(){ 33 | setup: 34 | File inputFile = new File("src/test/resources/test-input.doc") 35 | File thumbnail = new File("src/test/resources/test-output.jpg") 36 | Thumbnailer thumbnailer = new DOCThumbnailer() 37 | 38 | when: 39 | def output = thumbnailer.getThumbnails(inputFile, [new Dimensions(100, 100)]) 40 | def baos = new ByteArrayOutputStream() 41 | ImageIO.write(output[0], "jpg", baos) 42 | baos.flush() 43 | baos.close() 44 | byte[] actual_bytes = baos.toByteArray() 45 | 46 | then: 47 | output.size() == 1 48 | // thumbnail.getBytes() == actual_bytes 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /thumbnails4j-doc/src/test/resources/test-input.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/thumbnails4j-doc/src/test/resources/test-input.doc -------------------------------------------------------------------------------- /thumbnails4j-doc/src/test/resources/test-output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/thumbnails4j-doc/src/test/resources/test-output.jpg -------------------------------------------------------------------------------- /thumbnails4j-docx/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-docx 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | ================================================ 6 | Third party libraries used by thumbnails4j-docx: 7 | ================================================ 8 | 9 | Apache Commons Codec under Apache License, Version 2.0 10 | Apache Commons Collections under Apache License, Version 2.0 11 | Apache Commons Compress under Apache License, Version 2.0 12 | Apache Commons Math under Apache License, Version 2.0 13 | Apache POI under Apache License, Version 2.0 14 | curvesapi under BSD License 15 | fr.opensagres.poi.xwpf.converter.core under The MIT License (MIT) 16 | fr.opensagres.poi.xwpf.converter.pdf under The MIT License (MIT) 17 | fr.opensagres.poi.xwpf.converter.xhtml under The MIT License (MIT) 18 | fr.opensagres.xdocreport.converter under The MIT License (MIT) 19 | fr.opensagres.xdocreport.converter.docx.xwpf under The MIT License (MIT) 20 | fr.opensagres.xdocreport.core under The MIT License (MIT) 21 | fr.opensagres.xdocreport.itext.extension under The MIT License (MIT) 22 | OOXML schemas under The Apache Software License, Version 2.0 23 | SLF4J API Module under MIT License 24 | SparseBitSet under The Apache Software License, Version 2.0 25 | thumbnails4j-core under The Apache Software License, Version 2.0 26 | XmlBeans under The Apache Software License, Version 2.0 27 | 28 | -------------------------------------------------------------------------------- /thumbnails4j-docx/NOTICE.txt.template: -------------------------------------------------------------------------------- 1 | thumbnails4j-docx 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | ================================================ 6 | Third party libraries used by thumbnails4j-docx: 7 | ================================================ 8 | 9 | #GENERATED_NOTICES# -------------------------------------------------------------------------------- /thumbnails4j-docx/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | thumbnails4j 5 | co.elastic.thumbnails4j 6 | 1.2.0-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | thumbnails4j-docx 11 | 12 | 13 | 8 14 | 8 15 | 16 | 17 | 18 | 19 | co.elastic.thumbnails4j 20 | thumbnails4j-core 21 | ${project.version} 22 | 23 | 24 | org.apache.poi 25 | poi-ooxml 26 | 27 | 28 | fr.opensagres.xdocreport 29 | fr.opensagres.xdocreport.converter.docx.xwpf 30 | 31 | 32 | 33 | 34 | org.spockframework 35 | spock-core 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /thumbnails4j-docx/src/main/java/co/elastic/thumbnails4j/docx/DOCXThumbnailer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.docx; 23 | 24 | import co.elastic.thumbnails4j.core.Dimensions; 25 | import co.elastic.thumbnails4j.core.ThumbnailUtils; 26 | import co.elastic.thumbnails4j.core.Thumbnailer; 27 | import co.elastic.thumbnails4j.core.ThumbnailingException; 28 | import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLConverter; 29 | import org.apache.poi.xwpf.usermodel.XWPFDocument; 30 | import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageSz; 31 | import org.slf4j.Logger; 32 | import org.slf4j.LoggerFactory; 33 | 34 | import javax.imageio.ImageIO; 35 | import java.awt.image.BufferedImage; 36 | import java.io.*; 37 | import java.math.BigInteger; 38 | import java.util.ArrayList; 39 | import java.util.List; 40 | 41 | /** 42 | * A {@link Thumbnailer} for Office Open XML Formatted 43 | * documents. These files typically end in a {@code .docx} extension. This is not intended to support files with a 44 | * {@code .doc} extension. 45 | * 46 | * The Office Open XML specification allows a thumbnail image to be defined and included in the file binary. If it is 47 | * present, this image will be returned (with any appropriate scaling). 48 | * 49 | * Otherwise, the provided document will first be converted to XHTML before it is rendered. This means that more complex 50 | * formatting that cannot be expressed in raw XHTML will be lost (non-standard fonts, spacing, images, etc). 51 | */ 52 | public class DOCXThumbnailer implements Thumbnailer { 53 | Logger logger = LoggerFactory.getLogger(DOCXThumbnailer.class); 54 | 55 | @Override 56 | public List getThumbnails(File input, List dimensions) throws ThumbnailingException { 57 | try (FileInputStream fis = new FileInputStream(input)) { 58 | return getThumbnails(fis, dimensions); 59 | } catch (FileNotFoundException e) { 60 | logger.error("Could not find file {}", input.getAbsolutePath()); 61 | logger.error("With stack: ", e); 62 | throw new IllegalArgumentException(e); 63 | } catch (IOException e) { 64 | throw new ThumbnailingException(e); 65 | } 66 | } 67 | 68 | @Override 69 | public List getThumbnails(InputStream input, List dimensions) throws ThumbnailingException { 70 | List results = new ArrayList<>(); 71 | try (XWPFDocument docx = new XWPFDocument(input)){ 72 | InputStream imageStream = docx.getProperties().getThumbnailImage(); 73 | if (imageStream==null) { 74 | byte[] htmlBytes = htmlBytesFromDocx(docx); 75 | for(Dimensions singleDimension: dimensions){ 76 | Dimensions expectedDimensions = docxPageDimensions(docx, singleDimension); 77 | BufferedImage image = ThumbnailUtils.scaleHtmlToImage(htmlBytes, expectedDimensions); 78 | results.add(ThumbnailUtils.scaleImage(image, singleDimension)); 79 | } 80 | } else { 81 | BufferedImage image = ImageIO.read(imageStream); 82 | for(Dimensions singleDimension: dimensions) { 83 | results.add(ThumbnailUtils.scaleImage(image, singleDimension)); 84 | } 85 | 86 | } 87 | } catch (IOException e) { 88 | logger.error("Failed to read thumbnails from DOCX", e); 89 | throw new ThumbnailingException(e); 90 | } 91 | return results; 92 | } 93 | 94 | private Dimensions docxPageDimensions(XWPFDocument docx, Dimensions dimensions){ 95 | CTPageSz pageSz = null; 96 | try { 97 | pageSz = docx.getDocument().getBody().getSectPr().getPgSz(); 98 | } catch (NullPointerException e){ 99 | logger.debug("No page size detected for DOCX document"); 100 | } 101 | if (pageSz == null){ 102 | return dimensions; 103 | } else { 104 | return new Dimensions(((BigInteger) pageSz.getW()).intValue(), ((BigInteger) pageSz.getH()).intValue()); 105 | } 106 | 107 | } 108 | 109 | private byte[] htmlBytesFromDocx(XWPFDocument docx) throws IOException { 110 | ByteArrayOutputStream htmlStream = new ByteArrayOutputStream(); 111 | XHTMLConverter.getInstance().convert(docx, htmlStream, null); 112 | return htmlStream.toByteArray(); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /thumbnails4j-docx/src/main/resources/META-INF/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-docx 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | ================================================ 6 | Third party libraries used by thumbnails4j-docx: 7 | ================================================ 8 | 9 | Apache Commons Codec under Apache License, Version 2.0 10 | Apache Commons Collections under Apache License, Version 2.0 11 | Apache Commons Compress under Apache License, Version 2.0 12 | Apache Commons Math under Apache License, Version 2.0 13 | Apache POI under Apache License, Version 2.0 14 | curvesapi under BSD License 15 | fr.opensagres.poi.xwpf.converter.core under The MIT License (MIT) 16 | fr.opensagres.poi.xwpf.converter.pdf under The MIT License (MIT) 17 | fr.opensagres.poi.xwpf.converter.xhtml under The MIT License (MIT) 18 | fr.opensagres.xdocreport.converter under The MIT License (MIT) 19 | fr.opensagres.xdocreport.converter.docx.xwpf under The MIT License (MIT) 20 | fr.opensagres.xdocreport.core under The MIT License (MIT) 21 | fr.opensagres.xdocreport.itext.extension under The MIT License (MIT) 22 | OOXML schemas under The Apache Software License, Version 2.0 23 | SLF4J API Module under MIT License 24 | SparseBitSet under The Apache Software License, Version 2.0 25 | thumbnails4j-core under The Apache Software License, Version 2.0 26 | XmlBeans under The Apache Software License, Version 2.0 27 | 28 | -------------------------------------------------------------------------------- /thumbnails4j-docx/src/test/java/co/elastic/thumbnails4j/docx/DOCXThumbnailerTest.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.docx 23 | 24 | import co.elastic.thumbnails4j.core.Dimensions 25 | import co.elastic.thumbnails4j.core.Thumbnailer 26 | import spock.lang.Specification 27 | 28 | import javax.imageio.ImageIO 29 | 30 | class DOCXThumbnailerTest extends Specification { 31 | def "test .docx thumbnailing"(){ 32 | setup: 33 | File inputFile = new File("src/test/resources/test-input.docx") 34 | File thumbnail = new File("src/test/resources/test-output.jpg") 35 | Thumbnailer thumbnailer = new DOCXThumbnailer() 36 | 37 | when: 38 | def output = thumbnailer.getThumbnails(inputFile, [new Dimensions(100, 100)]) 39 | def baos = new ByteArrayOutputStream() 40 | ImageIO.write(output[0], "jpg", baos) 41 | baos.flush() 42 | baos.close() 43 | byte[] actual_bytes = baos.toByteArray() 44 | 45 | then: 46 | output.size() == 1 47 | // thumbnail.getBytes() == actual_bytes 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /thumbnails4j-docx/src/test/resources/test-input.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/thumbnails4j-docx/src/test/resources/test-input.docx -------------------------------------------------------------------------------- /thumbnails4j-docx/src/test/resources/test-output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/thumbnails4j-docx/src/test/resources/test-output.jpg -------------------------------------------------------------------------------- /thumbnails4j-image/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-image 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | ================================================= 6 | Third party libraries used by thumbnails4j-image: 7 | ================================================= 8 | 9 | SLF4J API Module under MIT License 10 | thumbnails4j-core under The Apache Software License, Version 2.0 11 | 12 | -------------------------------------------------------------------------------- /thumbnails4j-image/NOTICE.txt.template: -------------------------------------------------------------------------------- 1 | thumbnails4j-image 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | ================================================= 6 | Third party libraries used by thumbnails4j-image: 7 | ================================================= 8 | 9 | #GENERATED_NOTICES# -------------------------------------------------------------------------------- /thumbnails4j-image/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | thumbnails4j 5 | co.elastic.thumbnails4j 6 | 1.2.0-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | thumbnails4j-image 11 | 12 | 13 | 8 14 | 8 15 | 16 | 17 | 18 | 19 | co.elastic.thumbnails4j 20 | thumbnails4j-core 21 | ${project.version} 22 | 23 | 24 | 25 | 26 | 27 | org.spockframework 28 | spock-core 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /thumbnails4j-image/src/main/java/co/elastic/thumbnails4j/image/ImageThumbnailer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.image; 23 | 24 | import co.elastic.thumbnails4j.core.Dimensions; 25 | import co.elastic.thumbnails4j.core.ThumbnailUtils; 26 | import co.elastic.thumbnails4j.core.Thumbnailer; 27 | import co.elastic.thumbnails4j.core.ThumbnailingException; 28 | import org.slf4j.Logger; 29 | import org.slf4j.LoggerFactory; 30 | 31 | import javax.imageio.ImageIO; 32 | import javax.imageio.ImageReadParam; 33 | import javax.imageio.ImageReader; 34 | import javax.imageio.stream.ImageInputStream; 35 | import java.awt.*; 36 | import java.awt.image.BufferedImage; 37 | import java.io.File; 38 | import java.io.IOException; 39 | import java.io.InputStream; 40 | import java.util.ArrayList; 41 | import java.util.Iterator; 42 | import java.util.List; 43 | 44 | /** 45 | * A {@link Thumbnailer} for image file formats. As the inputs are images to start with, this thumbnailer is mostly 46 | * concerned with scaling the input images. 47 | */ 48 | public class ImageThumbnailer implements Thumbnailer { 49 | public static int MAX_READ_MULTIPLIER = 4; 50 | private static final Logger logger = LoggerFactory.getLogger(ImageThumbnailer.class); 51 | 52 | 53 | private final int imageType; 54 | 55 | /** 56 | * Creates a new {@link ImageThumbnailer} that generates thumbnails of the provided image type. 57 | * @param thumbnailType what type/format of images this thumbnailer should write. {@code "png"} will produce images 58 | * with opacity. {@code "jpg"} will produce solid images. 59 | */ 60 | public ImageThumbnailer(String thumbnailType){ 61 | if (thumbnailType.equalsIgnoreCase("png")){ 62 | this.imageType = BufferedImage.TYPE_INT_ARGB; 63 | } else { 64 | this.imageType = BufferedImage.TYPE_INT_RGB; 65 | } 66 | } 67 | 68 | @Override 69 | public List getThumbnails(File input, List dimensions) throws ThumbnailingException { 70 | return getThumbnailsHelper(input, dimensions); 71 | } 72 | 73 | @Override 74 | public List getThumbnails(InputStream input, List dimensions) throws ThumbnailingException { 75 | return getThumbnailsHelper(input, dimensions); 76 | } 77 | 78 | private List getThumbnailsHelper(Object input, List dimensions) throws ThumbnailingException { 79 | BufferedImage image; 80 | try { 81 | image = imageAtMost(input, maxImageReadSize()); 82 | } catch (IOException e) { 83 | logger.error("Failed to read image from file {}", input); 84 | logger.error("With stacktrace: ", e); 85 | throw new ThumbnailingException(e); 86 | } 87 | List output = new ArrayList<>(); 88 | for (Dimensions singleDimension: dimensions) { 89 | output.add(ThumbnailUtils.scaleImage(image, singleDimension, imageType)); 90 | } 91 | return output; 92 | } 93 | 94 | private BufferedImage imageAtMost(Object input, Dimensions dimensions) throws IOException, ThumbnailingException { 95 | try (ImageInputStream stream = ImageIO.createImageInputStream(input)) { 96 | Iterator readers = ImageIO.getImageReaders(stream); 97 | if (!readers.hasNext()) { 98 | throw new ThumbnailingException("Image stream contained no images"); 99 | } 100 | ImageReader reader = readers.next(); 101 | reader.setInput(stream); 102 | ImageReadParam param = reader.getDefaultReadParam(); 103 | param.setSourceRegion(new Rectangle(0, 0, dimensions.getWidth(), dimensions.getHeight())); 104 | 105 | BufferedImage image = reader.read(0, param); 106 | reader.dispose(); 107 | return image; 108 | } 109 | } 110 | 111 | private static Dimensions maxImageReadSize(){ 112 | return new Dimensions( 113 | ThumbnailUtils.getMaxInMemoryBuffer().getWidth() * MAX_READ_MULTIPLIER, 114 | ThumbnailUtils.getMaxInMemoryBuffer().getHeight() * MAX_READ_MULTIPLIER 115 | ); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /thumbnails4j-image/src/main/resources/META-INF/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-image 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | ================================================= 6 | Third party libraries used by thumbnails4j-image: 7 | ================================================= 8 | 9 | SLF4J API Module under MIT License 10 | thumbnails4j-core under The Apache Software License, Version 2.0 11 | 12 | -------------------------------------------------------------------------------- /thumbnails4j-image/src/test/java/co/elastic/thumbnails4j/image/ImageThumbnailerTest.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.image 23 | 24 | import co.elastic.thumbnails4j.core.Dimensions 25 | import spock.lang.Specification 26 | 27 | import javax.imageio.ImageIO 28 | 29 | class ImageThumbnailerTest extends Specification { 30 | 31 | def "test image thumbnailing"() { 32 | setup: 33 | File inputFile = new File("src/test/resources/test-input.png") 34 | File thumbnail = new File("src/test/resources/test-output.png") 35 | def thumbnailer = new ImageThumbnailer('png') 36 | def dimensions = [new Dimensions(100,100)] 37 | 38 | when: 39 | def output = thumbnailer.getThumbnails(inputFile, dimensions) 40 | ByteArrayOutputStream baos = new ByteArrayOutputStream() 41 | ImageIO.write(output[0], "png", baos) 42 | byte[] actualBytes = baos.toByteArray() 43 | byte[] expectedBytes = thumbnail.getBytes() 44 | 45 | then: 46 | output.size() == 1 47 | output[0].getWidth() == 85 48 | output[0].getHeight() == 100 49 | // actualBytes.size() == expectedBytes.size() 50 | // actualBytes == expectedBytes 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /thumbnails4j-image/src/test/resources/test-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/thumbnails4j-image/src/test/resources/test-input.png -------------------------------------------------------------------------------- /thumbnails4j-image/src/test/resources/test-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/thumbnails4j-image/src/test/resources/test-output.png -------------------------------------------------------------------------------- /thumbnails4j-pdf/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-pdf 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | =============================================== 6 | Third party libraries used by thumbnails4j-pdf: 7 | =============================================== 8 | 9 | Apache Commons Logging under The Apache Software License, Version 2.0 10 | Apache FontBox under Apache License, Version 2.0 11 | Apache PDFBox under Apache License, Version 2.0 12 | SLF4J API Module under MIT License 13 | thumbnails4j-core under The Apache Software License, Version 2.0 14 | 15 | -------------------------------------------------------------------------------- /thumbnails4j-pdf/NOTICE.txt.template: -------------------------------------------------------------------------------- 1 | thumbnails4j-pdf 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | =============================================== 6 | Third party libraries used by thumbnails4j-pdf: 7 | =============================================== 8 | 9 | #GENERATED_NOTICES# -------------------------------------------------------------------------------- /thumbnails4j-pdf/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | thumbnails4j 5 | co.elastic.thumbnails4j 6 | 1.2.0-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | thumbnails4j-pdf 11 | 12 | 13 | 8 14 | 8 15 | 16 | 17 | 18 | 19 | co.elastic.thumbnails4j 20 | thumbnails4j-core 21 | ${project.version} 22 | 23 | 24 | org.apache.pdfbox 25 | pdfbox 26 | 27 | 28 | 29 | 30 | org.spockframework 31 | spock-core 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /thumbnails4j-pdf/src/main/java/co/elastic/thumbnails4j/pdf/NullCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.pdf; 23 | 24 | import org.apache.pdfbox.cos.COSObject; 25 | import org.apache.pdfbox.pdmodel.DefaultResourceCache; 26 | import org.apache.pdfbox.pdmodel.documentinterchange.markedcontent.PDPropertyList; 27 | import org.apache.pdfbox.pdmodel.font.PDFont; 28 | import org.apache.pdfbox.pdmodel.graphics.PDXObject; 29 | import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace; 30 | import org.apache.pdfbox.pdmodel.graphics.pattern.PDAbstractPattern; 31 | import org.apache.pdfbox.pdmodel.graphics.shading.PDShading; 32 | import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState; 33 | 34 | import java.io.IOException; 35 | 36 | /** 37 | * Trades off speed of parsing for memory performance 38 | */ 39 | public class NullCache extends DefaultResourceCache { 40 | 41 | @Override 42 | public void put(COSObject indirect, PDFont font) throws IOException { 43 | //no op 44 | } 45 | 46 | @Override 47 | public void put(COSObject indirect, PDColorSpace colorSpace) throws IOException { 48 | //no op 49 | } 50 | 51 | @Override 52 | public void put(COSObject indirect, PDExtendedGraphicsState extGState) { 53 | //no op 54 | } 55 | 56 | @Override 57 | public void put(COSObject indirect, PDShading shading) throws IOException { 58 | //no op 59 | } 60 | 61 | @Override 62 | public void put(COSObject indirect, PDAbstractPattern pattern) throws IOException { 63 | //no op 64 | } 65 | 66 | @Override 67 | public void put(COSObject indirect, PDPropertyList propertyList) { 68 | //no op 69 | } 70 | 71 | @Override 72 | public void put(COSObject indirect, PDXObject xobject) throws IOException { 73 | //no op 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /thumbnails4j-pdf/src/main/java/co/elastic/thumbnails4j/pdf/PDFThumbnailer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.pdf; 23 | 24 | import co.elastic.thumbnails4j.core.Dimensions; 25 | import co.elastic.thumbnails4j.core.ThumbnailUtils; 26 | import co.elastic.thumbnails4j.core.Thumbnailer; 27 | import co.elastic.thumbnails4j.core.ThumbnailingException; 28 | import org.apache.pdfbox.cos.COSBase; 29 | import org.apache.pdfbox.cos.COSDictionary; 30 | import org.apache.pdfbox.cos.COSName; 31 | import org.apache.pdfbox.cos.COSObject; 32 | import org.apache.pdfbox.pdmodel.PDDocument; 33 | import org.apache.pdfbox.pdmodel.PDPage; 34 | import org.apache.pdfbox.pdmodel.common.PDRectangle; 35 | import org.apache.pdfbox.rendering.PDFRenderer; 36 | import org.slf4j.Logger; 37 | import org.slf4j.LoggerFactory; 38 | 39 | import java.awt.image.BufferedImage; 40 | import java.io.File; 41 | import java.io.IOException; 42 | import java.io.InputStream; 43 | import java.util.ArrayList; 44 | import java.util.List; 45 | import java.util.Map; 46 | 47 | /** 48 | * A {@link Thumbnailer} for Portable Document Formatted (PDF) documents. 49 | * These documents will often have a {@code .pdf} file extension. 50 | * 51 | * {@link PDFThumbnailer} attempts to find the first image in the format that actually fits on a page, and returns that 52 | * scaled image. This can be confusing if you attempt to thumbnail a poorly built PDF whose first page has a background 53 | * image that is larger than the size of the PDF's first page. However, this approach avoids Memory issues that can occur 54 | * when attempting to read undisplayably-large images. 55 | */ 56 | public class PDFThumbnailer implements Thumbnailer { 57 | private static Logger logger = LoggerFactory.getLogger(PDFThumbnailer.class); 58 | 59 | /** 60 | * This allows the image dimensions to be a bit bigger than the page dimensions for producing a thumbnail 61 | */ 62 | private static final double BUFFER_MULTIPLIER = 2.0; 63 | 64 | @Override 65 | public List getThumbnails(File input, List dimensions) throws ThumbnailingException { 66 | try (PDDocument document = PDDocument.load(input)) { 67 | return getThumbnails(document, dimensions); 68 | } catch (IOException e) { 69 | logger.error("Could not load input as PDF: ", e); 70 | throw new ThumbnailingException(e); 71 | } 72 | } 73 | 74 | @Override 75 | public List getThumbnails(InputStream input, List dimensions) throws ThumbnailingException { 76 | try (PDDocument document = PDDocument.load(input)) { 77 | return getThumbnails(document, dimensions); 78 | } catch (IOException e) { 79 | logger.error("Could not load input as PDF: ", e); 80 | throw new ThumbnailingException(e); 81 | } 82 | } 83 | 84 | private List getThumbnails(PDDocument document, List dimensions) throws IOException { 85 | List results = new ArrayList<>(); 86 | document.setResourceCache(new NullCache()); 87 | 88 | Integer thumbnailPageIndex = thumbnailPageIndex(document); 89 | if (thumbnailPageIndex != null){ 90 | BufferedImage image = new PDFRenderer(document).renderImage(thumbnailPageIndex, 0.5f); 91 | for(Dimensions singleDimension: dimensions) { 92 | results.add(ThumbnailUtils.scaleImage(image, singleDimension)); 93 | } 94 | } 95 | return results; 96 | } 97 | 98 | private Integer thumbnailPageIndex(PDDocument document){ 99 | for(int i = 0; i < document.getNumberOfPages(); i++){ 100 | PDPage page = document.getPage(i); 101 | COSDictionary dictionary = (COSDictionary) unwrapPDFObject(page.getCOSObject().getItem(COSName.RESOURCES)); 102 | List images = collectImages(dictionary); 103 | if (imagesFitPage(images, page)){ 104 | return i; 105 | } 106 | } 107 | return null; 108 | } 109 | 110 | private boolean imagesFitPage(List images, PDPage page){ 111 | PDRectangle pageDimensions = page.getBBox(); 112 | boolean allMatch = true; 113 | for(COSDictionary image: images){ 114 | allMatch = allMatch && ( 115 | image.getInt(COSName.WIDTH, 0) <= pageDimensions.getWidth() * BUFFER_MULTIPLIER && 116 | image.getInt(COSName.HEIGHT, 0) <= pageDimensions.getHeight() * BUFFER_MULTIPLIER 117 | ); 118 | } 119 | return allMatch; 120 | } 121 | 122 | private List collectImages(COSDictionary dictionary){ 123 | List values = new ArrayList<>(); 124 | for(Map.Entry entry : dictionary.entrySet()){ 125 | COSBase value = unwrapPDFObject(entry.getValue()); 126 | if (value instanceof COSDictionary) { 127 | if (isImage((COSDictionary) value)){ 128 | values.add((COSDictionary) value); 129 | } else { 130 | values.addAll(collectImages((COSDictionary) value)); 131 | } 132 | } 133 | } 134 | return values; 135 | } 136 | 137 | private COSBase unwrapPDFObject(COSBase object){ 138 | return object instanceof COSObject ? ((COSObject)object).getObject() : object; 139 | } 140 | 141 | private boolean isImage(COSDictionary dictionary){ 142 | return dictionary.getCOSName(COSName.TYPE) == COSName.XOBJECT && 143 | dictionary.getCOSName(COSName.SUBTYPE) == COSName.IMAGE && 144 | dictionary.containsKey(COSName.WIDTH) && 145 | dictionary.containsKey(COSName.HEIGHT); 146 | } 147 | 148 | } 149 | -------------------------------------------------------------------------------- /thumbnails4j-pdf/src/main/resources/META-INF/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-pdf 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | =============================================== 6 | Third party libraries used by thumbnails4j-pdf: 7 | =============================================== 8 | 9 | Apache Commons Logging under The Apache Software License, Version 2.0 10 | Apache FontBox under Apache License, Version 2.0 11 | Apache PDFBox under Apache License, Version 2.0 12 | SLF4J API Module under MIT License 13 | thumbnails4j-core under The Apache Software License, Version 2.0 14 | 15 | -------------------------------------------------------------------------------- /thumbnails4j-pdf/src/test/java/co/elastic/thumbnails4j/pdf/PDFThumbnailerTest.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.pdf 23 | 24 | import co.elastic.thumbnails4j.core.Dimensions 25 | import co.elastic.thumbnails4j.core.Thumbnailer 26 | import spock.lang.Specification 27 | 28 | import javax.imageio.ImageIO 29 | 30 | class PDFThumbnailerTest extends Specification { 31 | def "test .pdf thumbnailing"(){ 32 | setup: 33 | File inputFile = new File("src/test/resources/test-input.pdf") 34 | File thumbnail = new File("src/test/resources/test-output.jpg") 35 | Thumbnailer thumbnailer = new PDFThumbnailer() 36 | 37 | when: 38 | def output = thumbnailer.getThumbnails(inputFile, [new Dimensions(100, 100)]) 39 | def baos = new ByteArrayOutputStream() 40 | ImageIO.write(output[0], "jpg", baos) 41 | baos.flush() 42 | baos.close() 43 | byte[] actual_bytes = baos.toByteArray() 44 | 45 | then: 46 | output.size() == 1 47 | // thumbnail.getBytes() == actual_bytes 48 | } 49 | 50 | def "test .pdf thumbnailing bigger"(){ 51 | setup: 52 | File inputFile = new File("src/test/resources/test-bigger.pdf") 53 | Thumbnailer thumbnailer = new PDFThumbnailer() 54 | 55 | when: 56 | def output = thumbnailer.getThumbnails(inputFile, [new Dimensions(100, 100)]) 57 | def baos = new ByteArrayOutputStream() 58 | ImageIO.write(output[0], "jpg", baos) 59 | baos.flush() 60 | baos.close() 61 | 62 | then: 63 | output.size() == 1 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /thumbnails4j-pdf/src/test/resources/test-bigger.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/thumbnails4j-pdf/src/test/resources/test-bigger.pdf -------------------------------------------------------------------------------- /thumbnails4j-pdf/src/test/resources/test-input.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/thumbnails4j-pdf/src/test/resources/test-input.pdf -------------------------------------------------------------------------------- /thumbnails4j-pdf/src/test/resources/test-output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/thumbnails4j-pdf/src/test/resources/test-output.jpg -------------------------------------------------------------------------------- /thumbnails4j-pptx/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-pptx 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | ================================================ 6 | Third party libraries used by thumbnails4j-pptx: 7 | ================================================ 8 | 9 | Apache Commons Codec under Apache License, Version 2.0 10 | Apache Commons Collections under Apache License, Version 2.0 11 | Apache Commons Compress under Apache License, Version 2.0 12 | Apache Commons Math under Apache License, Version 2.0 13 | Apache POI under Apache License, Version 2.0 14 | curvesapi under BSD License 15 | Extended StAX API under Eclipse Distribution License - v 1.0 16 | fastinfoset under Apache License, Version 2.0 or Eclipse Distribution License - v 1.0 17 | istack common utility code runtime under Eclipse Distribution License - v 1.0 18 | jakarta.xml.bind-api under Eclipse Distribution License - v 1.0 19 | JavaBeans Activation Framework API jar under EDL 1.0 20 | JAXB Runtime under Eclipse Distribution License - v 1.0 21 | SLF4J API Module under MIT License 22 | SparseBitSet under The Apache Software License, Version 2.0 23 | thumbnails4j-core under The Apache Software License, Version 2.0 24 | TXW2 Runtime under Eclipse Distribution License - v 1.0 25 | XmlBeans under The Apache Software License, Version 2.0 26 | 27 | -------------------------------------------------------------------------------- /thumbnails4j-pptx/NOTICE.txt.template: -------------------------------------------------------------------------------- 1 | thumbnails4j-pptx 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | ================================================ 6 | Third party libraries used by thumbnails4j-pptx: 7 | ================================================ 8 | 9 | #GENERATED_NOTICES# -------------------------------------------------------------------------------- /thumbnails4j-pptx/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | thumbnails4j 5 | co.elastic.thumbnails4j 6 | 1.2.0-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | thumbnails4j-pptx 11 | 12 | 13 | 8 14 | 8 15 | 16 | 17 | 18 | 19 | co.elastic.thumbnails4j 20 | thumbnails4j-core 21 | ${project.version} 22 | 23 | 24 | org.apache.poi 25 | poi-ooxml 26 | 27 | 28 | jakarta.xml.bind 29 | jakarta.xml.bind-api 30 | 31 | 32 | org.glassfish.jaxb 33 | jaxb-runtime 34 | 35 | 36 | 37 | 38 | org.spockframework 39 | spock-core 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /thumbnails4j-pptx/src/main/java/co/elastic/thumbnails4j/pptx/PPTXThumbnailer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.pptx; 23 | 24 | import co.elastic.thumbnails4j.core.Dimensions; 25 | import co.elastic.thumbnails4j.core.ThumbnailUtils; 26 | import co.elastic.thumbnails4j.core.Thumbnailer; 27 | import co.elastic.thumbnails4j.core.ThumbnailingException; 28 | import org.apache.poi.xslf.usermodel.XMLSlideShow; 29 | import org.slf4j.Logger; 30 | import org.slf4j.LoggerFactory; 31 | 32 | import java.awt.*; 33 | import java.awt.geom.Rectangle2D; 34 | import java.awt.image.BufferedImage; 35 | import java.io.*; 36 | import java.util.ArrayList; 37 | import java.util.List; 38 | 39 | /** 40 | * A {@link Thumbnailer} for generating thumbnails from 41 | * Open Offic XML Presentation formatted documents. These 42 | * documents commonly end in a {@code .pptx} extension. This is not intended to generate thumbnails for documents with 43 | * a {@code .ppt} extension. 44 | * 45 | * {@link PPTXThumbnailer} generates a rendering of the first slide of the presentation, scaled as specified. 46 | */ 47 | public class PPTXThumbnailer implements Thumbnailer { 48 | Logger logger = LoggerFactory.getLogger(PPTXThumbnailer.class); 49 | 50 | @Override 51 | public List getThumbnails(File input, List dimensions) throws ThumbnailingException { 52 | try (FileInputStream fis = new FileInputStream(input)) { 53 | return getThumbnails(fis, dimensions); 54 | } catch (FileNotFoundException e) { 55 | logger.error("Could not find file {}", input.getAbsolutePath()); 56 | logger.error("With stack: ", e); 57 | throw new IllegalArgumentException(e); 58 | } catch (IOException e) { 59 | throw new ThumbnailingException(e); 60 | } 61 | } 62 | 63 | @Override 64 | public List getThumbnails(InputStream input, List dimensions) throws ThumbnailingException { 65 | try (XMLSlideShow pptx = new XMLSlideShow(input)) { 66 | BufferedImage image = pptxToImage(pptx); 67 | List results = new ArrayList<>(); 68 | for(Dimensions singleDimension: dimensions){ 69 | results.add(ThumbnailUtils.scaleImage(image, singleDimension)); 70 | } 71 | return results; 72 | } catch (IOException e) { 73 | logger.error("Failed to parse PPTX from stream: ", e); 74 | throw new ThumbnailingException(e); 75 | } 76 | } 77 | 78 | private BufferedImage pptxToImage(XMLSlideShow pptx){ 79 | Dimension pageSize = pptx.getPageSize(); 80 | Dimensions optimizedDimensions = ThumbnailUtils.memoryOptimiseDimension(new Dimensions(pageSize.width, pageSize.height)); 81 | double scaleFactor = ((double) optimizedDimensions.getWidth()) / pageSize.width; 82 | BufferedImage image = new BufferedImage(optimizedDimensions.getWidth(), optimizedDimensions.getHeight(), BufferedImage.TYPE_INT_RGB); 83 | Graphics2D graphics = image.createGraphics(); 84 | graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 85 | graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 86 | graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); 87 | graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); 88 | graphics.setPaint(Color.white); 89 | graphics.fill(new Rectangle2D.Float(0, 0, optimizedDimensions.getWidth(), optimizedDimensions.getHeight())); 90 | graphics.scale(scaleFactor, scaleFactor); 91 | pptx.getSlides().get(0).draw(graphics); 92 | graphics.dispose(); 93 | return image; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /thumbnails4j-pptx/src/main/resources/META-INF/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-pptx 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | ================================================ 6 | Third party libraries used by thumbnails4j-pptx: 7 | ================================================ 8 | 9 | Apache Commons Codec under Apache License, Version 2.0 10 | Apache Commons Collections under Apache License, Version 2.0 11 | Apache Commons Compress under Apache License, Version 2.0 12 | Apache Commons Math under Apache License, Version 2.0 13 | Apache POI under Apache License, Version 2.0 14 | curvesapi under BSD License 15 | Extended StAX API under Eclipse Distribution License - v 1.0 16 | fastinfoset under Apache License, Version 2.0 or Eclipse Distribution License - v 1.0 17 | istack common utility code runtime under Eclipse Distribution License - v 1.0 18 | jakarta.xml.bind-api under Eclipse Distribution License - v 1.0 19 | JavaBeans Activation Framework API jar under EDL 1.0 20 | JAXB Runtime under Eclipse Distribution License - v 1.0 21 | SLF4J API Module under MIT License 22 | SparseBitSet under The Apache Software License, Version 2.0 23 | thumbnails4j-core under The Apache Software License, Version 2.0 24 | TXW2 Runtime under Eclipse Distribution License - v 1.0 25 | XmlBeans under The Apache Software License, Version 2.0 26 | 27 | -------------------------------------------------------------------------------- /thumbnails4j-pptx/src/test/java/co/elastic/thumbnails4j/pptx/PPTXThumbnailerTest.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.pptx 23 | 24 | import co.elastic.thumbnails4j.core.Dimensions 25 | import co.elastic.thumbnails4j.core.Thumbnailer 26 | import spock.lang.Specification 27 | 28 | import javax.imageio.ImageIO 29 | 30 | class PPTXThumbnailerTest extends Specification { 31 | 32 | def "test .pptx thumbnailing"(){ 33 | setup: 34 | File inputFile = new File("src/test/resources/test-input.pptx") 35 | File thumbnail = new File("src/test/resources/test-output.jpg") 36 | Thumbnailer thumbnailer = new PPTXThumbnailer() 37 | 38 | when: 39 | def output = thumbnailer.getThumbnails(inputFile, [new Dimensions(100, 100)]) 40 | def baos = new ByteArrayOutputStream() 41 | ImageIO.write(output[0], "jpg", baos) 42 | baos.flush() 43 | baos.close() 44 | byte[] actual_bytes = baos.toByteArray() 45 | 46 | then: 47 | output.size() == 1 48 | // thumbnail.getBytes() == actual_bytes 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /thumbnails4j-pptx/src/test/resources/test-input.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/thumbnails4j-pptx/src/test/resources/test-input.pptx -------------------------------------------------------------------------------- /thumbnails4j-pptx/src/test/resources/test-output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/thumbnails4j-pptx/src/test/resources/test-output.jpg -------------------------------------------------------------------------------- /thumbnails4j-xls/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-xls 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | =============================================== 6 | Third party libraries used by thumbnails4j-xls: 7 | =============================================== 8 | 9 | Apache Commons Codec under Apache License, Version 2.0 10 | Apache Commons Collections under Apache License, Version 2.0 11 | Apache Commons Math under Apache License, Version 2.0 12 | Apache POI under Apache License, Version 2.0 13 | SLF4J API Module under MIT License 14 | SparseBitSet under The Apache Software License, Version 2.0 15 | thumbnails4j-core under The Apache Software License, Version 2.0 16 | 17 | -------------------------------------------------------------------------------- /thumbnails4j-xls/NOTICE.txt.template: -------------------------------------------------------------------------------- 1 | thumbnails4j-xls 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | =============================================== 6 | Third party libraries used by thumbnails4j-xls: 7 | =============================================== 8 | 9 | #GENERATED_NOTICES# -------------------------------------------------------------------------------- /thumbnails4j-xls/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | thumbnails4j 5 | co.elastic.thumbnails4j 6 | 1.2.0-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | thumbnails4j-xls 11 | 12 | 13 | 8 14 | 8 15 | 16 | 17 | 18 | 19 | co.elastic.thumbnails4j 20 | thumbnails4j-core 21 | ${project.version} 22 | 23 | 24 | org.apache.poi 25 | poi-scratchpad 26 | 27 | 28 | 29 | 30 | 31 | org.spockframework 32 | spock-core 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /thumbnails4j-xls/src/main/java/co/elastic/thumbnails4j/xls/XLSThumbnailer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.xls; 23 | 24 | import co.elastic.thumbnails4j.core.Dimensions; 25 | import co.elastic.thumbnails4j.core.ThumbnailUtils; 26 | import co.elastic.thumbnails4j.core.Thumbnailer; 27 | import co.elastic.thumbnails4j.core.ThumbnailingException; 28 | import org.apache.poi.hssf.converter.ExcelToHtmlConverter; 29 | import org.slf4j.Logger; 30 | import org.slf4j.LoggerFactory; 31 | import org.w3c.dom.Document; 32 | 33 | import javax.xml.parsers.ParserConfigurationException; 34 | import javax.xml.transform.TransformerException; 35 | import javax.xml.transform.dom.DOMSource; 36 | import javax.xml.transform.stream.StreamResult; 37 | import java.awt.image.BufferedImage; 38 | import java.io.ByteArrayOutputStream; 39 | import java.io.File; 40 | import java.io.IOException; 41 | import java.io.InputStream; 42 | import java.util.ArrayList; 43 | import java.util.List; 44 | 45 | /** 46 | * A {@link Thumbnailer} for legacy Microsoft Excel formatted 47 | * documents. These documents often have a {@code .xls} extension. This {@link Thumbnailer} is not intended for documents 48 | * with {@code .xlsx} extensions. 49 | * 50 | * {@link XLSThumbnailer} will attempt to clip the upper-right portion of the spreadsheet, and generate an image from that 51 | * limited view. This prevents un-identifiable views of spreadsheets with many rows and/or columns, by avoiding attemping 52 | * to show every cell in the thumbnail. The size of this view is controlled by {@link ThumbnailUtils#getMaxInMemoryBuffer()}. 53 | */ 54 | public class XLSThumbnailer implements Thumbnailer { 55 | Logger logger = LoggerFactory.getLogger(XLSThumbnailer.class); 56 | 57 | @Override 58 | public List getThumbnails(File input, List dimensions) throws ThumbnailingException { 59 | try { 60 | return getThumbnails(ExcelToHtmlConverter.process(input), dimensions); 61 | } catch (IOException|ParserConfigurationException|TransformerException e) { 62 | logger.error("Failed to parse XLS: ", e); 63 | throw new ThumbnailingException(e); 64 | } 65 | } 66 | 67 | @Override 68 | public List getThumbnails(InputStream input, List dimensions) throws ThumbnailingException { 69 | try { 70 | return getThumbnails(ExcelToHtmlConverter.process(input), dimensions); 71 | } catch (IOException|ParserConfigurationException|TransformerException e) { 72 | logger.error("Failed to parse XLS: ", e); 73 | throw new ThumbnailingException(e); 74 | } 75 | } 76 | 77 | private List getThumbnails(Document xhtml_dom, List dimensions) throws TransformerException { 78 | DOMSource domSource = new DOMSource(xhtml_dom); 79 | ByteArrayOutputStream html = new ByteArrayOutputStream(); 80 | StreamResult streamResult = new StreamResult(html); 81 | ThumbnailUtils.getTransformerForXhtmlDOM().transform(domSource, streamResult); 82 | BufferedImage image = ThumbnailUtils.clipHtmlToImage(html.toByteArray(), ThumbnailUtils.getMaxInMemoryBuffer()); 83 | List results = new ArrayList<>(); 84 | for(Dimensions singleDimension: dimensions){ 85 | results.add(ThumbnailUtils.scaleImage(image, singleDimension)); 86 | } 87 | return results; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /thumbnails4j-xls/src/main/resources/META-INF/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-xls 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | 5 | =============================================== 6 | Third party libraries used by thumbnails4j-xls: 7 | =============================================== 8 | 9 | Apache Commons Codec under Apache License, Version 2.0 10 | Apache Commons Collections under Apache License, Version 2.0 11 | Apache Commons Math under Apache License, Version 2.0 12 | Apache POI under Apache License, Version 2.0 13 | SLF4J API Module under MIT License 14 | SparseBitSet under The Apache Software License, Version 2.0 15 | thumbnails4j-core under The Apache Software License, Version 2.0 16 | 17 | -------------------------------------------------------------------------------- /thumbnails4j-xls/src/test/java/co/elastic/thumbnails4j/xls/XLSThumbnailerTest.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.xls 23 | 24 | import co.elastic.thumbnails4j.core.Dimensions 25 | import co.elastic.thumbnails4j.core.Thumbnailer 26 | import spock.lang.Specification 27 | 28 | import javax.imageio.ImageIO 29 | 30 | class XLSThumbnailerTest extends Specification { 31 | def "test .xls thumbnailing"(){ 32 | setup: 33 | File inputFile = new File("src/test/resources/test-input.xls") 34 | File thumbnail = new File("src/test/resources/test-output.jpg") 35 | Thumbnailer thumbnailer = new XLSThumbnailer() 36 | 37 | when: 38 | def output = thumbnailer.getThumbnails(inputFile, [new Dimensions(100, 100)]) 39 | def baos = new ByteArrayOutputStream() 40 | ImageIO.write(output[0], "jpg", baos) 41 | baos.flush() 42 | baos.close() 43 | byte[] actual_bytes = baos.toByteArray() 44 | 45 | then: 46 | output.size() == 1 47 | // thumbnail.getBytes() == actual_bytes 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /thumbnails4j-xls/src/test/resources/test-input.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/thumbnails4j-xls/src/test/resources/test-input.xls -------------------------------------------------------------------------------- /thumbnails4j-xls/src/test/resources/test-output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/thumbnails4j-xls/src/test/resources/test-output.jpg -------------------------------------------------------------------------------- /thumbnails4j-xlsx/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-xlsx 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | This product contains code copied from org.apache.poi:poi-examples:4.1.2. 5 | 6 | ================================================ 7 | Third party libraries used by thumbnails4j-xlsx: 8 | ================================================ 9 | 10 | Apache Commons Codec under Apache License, Version 2.0 11 | Apache Commons Collections under Apache License, Version 2.0 12 | Apache Commons Compress under Apache License, Version 2.0 13 | Apache Commons Math under Apache License, Version 2.0 14 | Apache POI under Apache License, Version 2.0 15 | curvesapi under BSD License 16 | SLF4J API Module under MIT License 17 | SparseBitSet under The Apache Software License, Version 2.0 18 | thumbnails4j-core under The Apache Software License, Version 2.0 19 | XmlBeans under The Apache Software License, Version 2.0 20 | 21 | -------------------------------------------------------------------------------- /thumbnails4j-xlsx/NOTICE.txt.template: -------------------------------------------------------------------------------- 1 | thumbnails4j-xlsx 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | This product contains code copied from org.apache.poi:poi-examples:4.1.2. 5 | 6 | ================================================ 7 | Third party libraries used by thumbnails4j-xlsx: 8 | ================================================ 9 | 10 | #GENERATED_NOTICES# -------------------------------------------------------------------------------- /thumbnails4j-xlsx/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | thumbnails4j 5 | co.elastic.thumbnails4j 6 | 1.2.0-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | thumbnails4j-xlsx 11 | 12 | 13 | 8 14 | 8 15 | 16 | 17 | 18 | 19 | co.elastic.thumbnails4j 20 | thumbnails4j-core 21 | ${project.version} 22 | 23 | 24 | org.apache.poi 25 | poi-ooxml 26 | 27 | 28 | 29 | 30 | 31 | org.spockframework 32 | spock-core 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /thumbnails4j-xlsx/src/main/java/co/elastic/thumbnails4j/xlsx/XLSXThumbnailer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.xlsx; 23 | 24 | import co.elastic.thumbnails4j.core.Dimensions; 25 | import co.elastic.thumbnails4j.core.ThumbnailUtils; 26 | import co.elastic.thumbnails4j.core.Thumbnailer; 27 | import co.elastic.thumbnails4j.core.ThumbnailingException; 28 | 29 | import org.apache.poi.ss.usermodel.Workbook; 30 | import org.apache.poi.ss.usermodel.WorkbookFactory; 31 | import org.slf4j.Logger; 32 | import org.slf4j.LoggerFactory; 33 | 34 | import java.awt.image.BufferedImage; 35 | import java.io.*; 36 | import java.util.*; 37 | 38 | /** 39 | * A {@link Thumbnailer} for Microsoft Excel formatted 40 | * documents. These documents often have a {@code .xlsx} extension. This {@link Thumbnailer} is not intended for documents 41 | * with {@code .xls} extensions. 42 | * 43 | * {@link XLSXThumbnailer} will attempt to clip the upper-right portion of the spreadsheet, and generate an image from that 44 | * limited view. This prevents un-identifiable views of spreadsheets with many rows and/or columns, by avoiding attemping 45 | * to show every cell in the thumbnail. The size of this view is controlled by {@link ThumbnailUtils#getMaxInMemoryBuffer()}. 46 | */ 47 | public class XLSXThumbnailer implements Thumbnailer { 48 | 49 | Logger logger = LoggerFactory.getLogger(XLSXThumbnailer.class); 50 | 51 | @Override 52 | public List getThumbnails(File input, List dimensions) throws ThumbnailingException { 53 | try (Workbook workbook = WorkbookFactory.create(input)) { 54 | return getThumbnails(workbook, dimensions); 55 | } catch (IOException e) { 56 | logger.error("Failed to parse XLSX: ", e); 57 | throw new ThumbnailingException(e); 58 | } 59 | } 60 | 61 | @Override 62 | public List getThumbnails(InputStream input, List dimensions) throws ThumbnailingException { 63 | try (Workbook workbook = WorkbookFactory.create(input)) { 64 | return getThumbnails(workbook, dimensions); 65 | } catch (IOException e) { 66 | logger.error("Failed to parse XLSX: ", e); 67 | throw new ThumbnailingException(e); 68 | } 69 | } 70 | 71 | private List getThumbnails(Workbook workbook, List dimensions) { 72 | XlsxToHtmlSerializer serializer = new XlsxToHtmlSerializer(workbook); 73 | byte[] htmlBytes = serializer.getHtml(); 74 | BufferedImage image = ThumbnailUtils.clipHtmlToImage(htmlBytes, ThumbnailUtils.getMaxInMemoryBuffer()); 75 | List results = new ArrayList<>(); 76 | for(Dimensions singleDimension: dimensions){ 77 | results.add(ThumbnailUtils.scaleImage(image, singleDimension)); 78 | } 79 | return results; 80 | } 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | } 89 | -------------------------------------------------------------------------------- /thumbnails4j-xlsx/src/main/resources/META-INF/NOTICE.txt: -------------------------------------------------------------------------------- 1 | thumbnails4j-xlsx 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). 4 | This product contains code copied from org.apache.poi:poi-examples:4.1.2. 5 | 6 | ================================================ 7 | Third party libraries used by thumbnails4j-xlsx: 8 | ================================================ 9 | 10 | Apache Commons Codec under Apache License, Version 2.0 11 | Apache Commons Collections under Apache License, Version 2.0 12 | Apache Commons Compress under Apache License, Version 2.0 13 | Apache Commons Math under Apache License, Version 2.0 14 | Apache POI under Apache License, Version 2.0 15 | curvesapi under BSD License 16 | SLF4J API Module under MIT License 17 | SparseBitSet under The Apache Software License, Version 2.0 18 | thumbnails4j-core under The Apache Software License, Version 2.0 19 | XmlBeans under The Apache Software License, Version 2.0 20 | 21 | -------------------------------------------------------------------------------- /thumbnails4j-xlsx/src/test/java/co/elastic/thumbnails4j/xlsx/XLSXThumbnailerTest.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to Elasticsearch B.V. under one or more contributor 4 | * * license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright 6 | * * ownership. Elasticsearch B.V. licenses this file to you under 7 | * * the Apache License, Version 2.0 (the "License"); you may 8 | * * not use this file except in compliance with the License. 9 | * * You may obtain a copy of the License at 10 | * * 11 | * * http://www.apache.org/licenses/LICENSE-2.0 12 | * * 13 | * * Unless required by applicable law or agreed to in writing, 14 | * * software distributed under the License is distributed on an 15 | * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * * KIND, either express or implied. See the License for the 17 | * * specific language governing permissions and limitations 18 | * * under the License. 19 | * 20 | */ 21 | 22 | package co.elastic.thumbnails4j.xlsx 23 | 24 | import co.elastic.thumbnails4j.core.Dimensions 25 | import co.elastic.thumbnails4j.core.Thumbnailer 26 | import spock.lang.Specification 27 | 28 | import javax.imageio.ImageIO 29 | 30 | class XLSXThumbnailerTest extends Specification { 31 | 32 | def "test .xlsx thumbnailing"(){ 33 | setup: 34 | File inputFile = new File("src/test/resources/test-input.xlsx") 35 | File thumbnail = new File("src/test/resources/test-output.jpg") 36 | Thumbnailer thumbnailer = new XLSXThumbnailer() 37 | 38 | when: 39 | def output = thumbnailer.getThumbnails(inputFile, [new Dimensions(100, 100)]) 40 | def baos = new ByteArrayOutputStream() 41 | ImageIO.write(output[0], "jpg", baos) 42 | baos.flush() 43 | baos.close() 44 | byte[] actual_bytes = baos.toByteArray() 45 | 46 | then: 47 | output.size() == 1 48 | // thumbnail.getBytes() == actual_bytes 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /thumbnails4j-xlsx/src/test/resources/test-input.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/thumbnails4j-xlsx/src/test/resources/test-input.xlsx -------------------------------------------------------------------------------- /thumbnails4j-xlsx/src/test/resources/test-output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/thumbnails4j/71496c52c88762ba457bc424c09c3ba6f97b083b/thumbnails4j-xlsx/src/test/resources/test-output.jpg --------------------------------------------------------------------------------