View Javadoc

1   /*
2    * Copyright 2016-2016 Hippo B.V. (http://www.onehippo.com)
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  package org.onehippo.forge.gallerymagick.core.command;
17  
18  import java.io.ByteArrayOutputStream;
19  import java.io.File;
20  import java.io.IOException;
21  import java.util.Arrays;
22  import java.util.Collections;
23  import java.util.List;
24  
25  import org.apache.commons.lang.StringUtils;
26  import org.onehippo.forge.gallerymagick.core.ImageDimension;
27  
28  /**
29   * Utility to run Image Magick Commands.
30   */
31  public class ImageMagickCommandUtils {
32  
33      private ImageMagickCommandUtils() {
34      }
35  
36      /**
37       * Execute <code>identify -verbose</code> sub-command and return a string of all extracted metadata from the output.
38       * @param sourceFile source image file
39       * @return Execute <code>identify -verbose</code> sub-command and return a string of all extracted metadata from the output
40       * @throws MagickExecuteException if execution exception occurs
41       * @throws IOException if IO exception occurs
42       */
43      public static String identifyAllMetadata(File sourceFile) throws MagickExecuteException, IOException {
44          ImageMagickCommand cmd = new ImageMagickCommand(null, "identify");
45  
46          final File tempFolder = getTempFolder();
47  
48          if (tempFolder != null) {
49              cmd.setWorkingDirectory(tempFolder);
50          }
51  
52          cmd.addArgument("-verbose");
53          cmd.addArgument(sourceFile.getCanonicalPath());
54  
55          ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
56          cmd.execute(baos);
57          return StringUtils.trim(baos.toString("UTF-8"));
58      }
59  
60      /**
61       * Execute <code>identify</code> sub-command and return an {@link ImageDimension} instance from the output.
62       * @param sourceFile source image file
63       * @return Execute <code>identify</code> sub-command and return an {@link ImageDimension} instance from the output
64       * @throws MagickExecuteException if execution exception occurs
65       * @throws IOException if IO exception occurs
66       */
67      public static ImageDimension identifyDimension(File sourceFile) throws MagickExecuteException, IOException {
68          ImageMagickCommand cmd = new ImageMagickCommand(null, "identify");
69  
70          final File tempFolder = getTempFolder();
71  
72          if (tempFolder != null) {
73              cmd.setWorkingDirectory(tempFolder);
74          }
75  
76          cmd.addArgument("-format");
77          cmd.addArgument("%wx%h");
78          cmd.addArgument(sourceFile.getCanonicalPath());
79  
80          ByteArrayOutputStream baos = new ByteArrayOutputStream(40);
81          cmd.execute(baos);
82          String output = StringUtils.trim(baos.toString("UTF-8"));
83  
84          return ImageDimension.from(output);
85      }
86  
87      /**
88       * Resize the given image {@code sourceFile} with resizing it to {@code width} and {@code height}
89       * and store the resized image to {@code targetFile}.
90       * @param sourceFile source image file
91       * @param targetFile target image file
92       * @param dimension image dimension
93       * @throws MagickExecuteException if execution exception occurs
94       * @throws IOException if IO exception occurs
95       */
96      public static void resizeImage(File sourceFile, File targetFile, ImageDimension dimension)
97              throws MagickExecuteException, IOException {
98          resizeImage(sourceFile, targetFile, dimension, (String []) null);
99      }
100 
101     /**
102      * Resize the given image {@code sourceFile} with resizing it to {@code width} and {@code height}
103      * and store the resized image to {@code targetFile}, with appending {@code extraOptions} in the command line if provided.
104      * @param sourceFile source image file
105      * @param targetFile target image file
106      * @param dimension image dimension
107      * @param extraOptions extra command line options
108      * @throws MagickExecuteException if execution exception occurs
109      * @throws IOException if IO exception occurs
110      */
111     public static void resizeImage(File sourceFile, File targetFile, ImageDimension dimension, String ... extraOptions)
112             throws MagickExecuteException, IOException {
113         if (dimension == null) {
114             throw new IllegalArgumentException("Invalid dimension: " + dimension);
115         }
116 
117         ImageMagickCommand cmd = new ImageMagickCommand(null, "convert");
118 
119         final File tempFolder = getTempFolder();
120 
121         if (tempFolder != null) {
122             cmd.setWorkingDirectory(tempFolder);
123         }
124 
125         cmd.addArgument(sourceFile.getCanonicalPath());
126         final String dimensionArg = dimension.toCommandArgument();
127         cmd.addArgument("-resize");
128         cmd.addArgument(dimensionArg);
129 
130         final List<String> extraOptionList = (extraOptions != null) ? Arrays.asList(extraOptions) : Collections.emptyList();
131 
132         for (String extraOption : extraOptionList) {
133             cmd.addArgument(extraOption);
134         }
135 
136         if (dimension.getWidth() > 0 || dimension.getHeight() > 0) {
137             if (!extraOptionList.contains("-size")) {
138                 cmd.addArgument("-size");
139                 cmd.addArgument(dimensionArg);
140             }
141         }
142 
143         if (!extraOptionList.contains("+profile") && !extraOptionList.contains("-profile")) {
144             cmd.addArgument("+profile");
145             cmd.addArgument("*");
146         }
147 
148         cmd.addArgument(targetFile.getCanonicalPath());
149 
150         cmd.execute();
151     }
152 
153     /**
154      * Returns the temporary folder file.
155      * @return the temporary foler file
156      */
157     private static File getTempFolder() {
158         File tempFolder = null;
159         final String tmpDirPath = System.getProperty("java.io.tmpdir");
160 
161         if (StringUtils.isNotBlank(tmpDirPath)) {
162             tempFolder = new File(tmpDirPath);
163         }
164 
165         return tempFolder;
166     }
167 }