@@ -45,8 +45,9 @@ This file is part of the iText (R) project.
45
45
46
46
import com .itextpdf .io .IoExceptionMessage ;
47
47
48
- import java .io .File ;
49
48
import java .io .IOException ;
49
+ import java .util .regex .Matcher ;
50
+ import java .util .regex .Pattern ;
50
51
51
52
/**
52
53
* A utility class that is used as an interface to run 3rd-party tool ImageMagick.
@@ -69,6 +70,9 @@ public class ImageMagickHelper {
69
70
static final String MAGICK_COMPARE_KEYWORD = "ImageMagick Studio LLC" ;
70
71
71
72
private static final String TEMP_FILE_PREFIX = "itext_im_io_temp" ;
73
+ private static final String DIFF_PIXELS_OUTPUT_REGEXP = "^\\ d+\\ .*\\ d*(e\\ +\\ d+)?" ;
74
+
75
+ private static final Pattern pattern = Pattern .compile (DIFF_PIXELS_OUTPUT_REGEXP );
72
76
73
77
private String compareExec ;
74
78
@@ -139,6 +143,58 @@ public boolean runImageMagickImageCompare(String outImageFilePath, String cmpIma
139
143
*/
140
144
public boolean runImageMagickImageCompare (String outImageFilePath , String cmpImageFilePath ,
141
145
String diffImageName , String fuzzValue ) throws IOException , InterruptedException {
146
+ ImageMagickCompareResult compareResult = runImageMagickImageCompareAndGetResult (outImageFilePath ,
147
+ cmpImageFilePath , diffImageName , fuzzValue );
148
+
149
+ return compareResult .isComparingResultSuccessful ();
150
+ }
151
+
152
+ /**
153
+ * Runs imageMagick to visually compare images with the specified fuzziness value and given threshold
154
+ * and generate difference output.
155
+ *
156
+ * @param outImageFilePath Path to the output image file
157
+ * @param cmpImageFilePath Path to the cmp image file
158
+ * @param diffImageName Path to the difference output image file
159
+ * @param fuzzValue String fuzziness value to compare images. Should be formatted as string with integer
160
+ * or decimal number. Can be null, if it is not required to use fuzziness
161
+ * @param threshold Long value of accepted threshold.
162
+ *
163
+ * @return boolean result of comparing: true - images are visually equal
164
+ *
165
+ * @throws IOException if there are file's reading/writing issues
166
+ * @throws InterruptedException if there is thread interruption while executing ImageMagick.
167
+ */
168
+ public boolean runImageMagickImageCompareWithThreshold (String outImageFilePath , String cmpImageFilePath ,
169
+ String diffImageName , String fuzzValue , long threshold ) throws IOException , InterruptedException {
170
+ ImageMagickCompareResult compareResult = runImageMagickImageCompareAndGetResult (outImageFilePath ,
171
+ cmpImageFilePath , diffImageName , fuzzValue );
172
+
173
+ if (compareResult .isComparingResultSuccessful ()) {
174
+ return true ;
175
+ } else {
176
+ return compareResult .getDiffPixels () <= threshold ;
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Runs imageMagick to visually compare images with the specified fuzziness value and generate difference output.
182
+ * This method returns an object of {@link ImageMagickCompareResult}, containing comparing result information,
183
+ * such as boolean result value and the number of different pixels.
184
+ *
185
+ * @param outImageFilePath Path to the output image file
186
+ * @param cmpImageFilePath Path to the cmp image file
187
+ * @param diffImageName Path to the difference output image file
188
+ * @param fuzzValue String fuzziness value to compare images. Should be formatted as string with integer
189
+ * or decimal number. Can be null, if it is not required to use fuzziness
190
+ *
191
+ * @return an object of {@link ImageMagickCompareResult}. containing comparing result information.
192
+ *
193
+ * @throws IOException if there are file's reading/writing issues
194
+ * @throws InterruptedException if there is thread interruption while executing ImageMagick.
195
+ */
196
+ public ImageMagickCompareResult runImageMagickImageCompareAndGetResult (String outImageFilePath ,
197
+ String cmpImageFilePath , String diffImageName , String fuzzValue ) throws IOException , InterruptedException {
142
198
if (!validateFuzziness (fuzzValue )) {
143
199
throw new IllegalArgumentException ("Invalid fuzziness value: " + fuzzValue );
144
200
}
@@ -158,12 +214,15 @@ public boolean runImageMagickImageCompare(String outImageFilePath, String cmpIma
158
214
+ replacementOutFile + "' '"
159
215
+ replacementCmpFile + "' '"
160
216
+ replacementDiff + "'" ;
161
- boolean result = SystemUtil .runProcessAndWait (compareExec , currCompareParams );
217
+ ProcessInfo processInfo = SystemUtil .runProcessAndGetProcessInfo (compareExec , currCompareParams );
218
+ boolean comparingResult = processInfo .getExitCode () == 0 ;
219
+ long diffPixels = parseImageMagickProcessOutput (processInfo .getProcessErrOutput ());
220
+ ImageMagickCompareResult resultInfo = new ImageMagickCompareResult (comparingResult , diffPixels );
162
221
163
222
if (FileUtil .fileExists (replacementDiff )) {
164
223
FileUtil .copy (replacementDiff , diffImageName );
165
224
}
166
- return result ;
225
+ return resultInfo ;
167
226
} finally {
168
227
FileUtil .removeFiles (new String [] {replacementOutFile , replacementCmpFile , replacementDiff });
169
228
}
@@ -182,4 +241,29 @@ static boolean validateFuzziness(String fuzziness) {
182
241
}
183
242
}
184
243
}
244
+
245
+ private static long parseImageMagickProcessOutput (String processOutput ) throws IOException {
246
+ if (null == processOutput ) {
247
+ throw new IllegalArgumentException (IoExceptionMessage .IMAGE_MAGICK_OUTPUT_IS_NULL );
248
+ }
249
+
250
+ if (processOutput .isEmpty ()) {
251
+ return 0L ;
252
+ }
253
+
254
+ String [] processOutputLines = processOutput .split ("\n " );
255
+
256
+ for (String line : processOutputLines ) {
257
+ try {
258
+ Matcher matcher = pattern .matcher (line );
259
+ if (matcher .find ()) {
260
+ return (long ) Double .valueOf (matcher .group ()).longValue ();
261
+ }
262
+ } catch (NumberFormatException e ) {
263
+ // Nothing should be done here because of the exception, that will be thrown later.
264
+ }
265
+ }
266
+
267
+ throw new IOException (IoExceptionMessage .IMAGE_MAGICK_PROCESS_EXECUTION_FAILED + processOutput );
268
+ }
185
269
}
0 commit comments