1 16 17 package org.apache.batik.test.util; 18 19 import java.awt.Color ; 20 import java.awt.Graphics2D ; 21 import java.awt.image.BufferedImage ; 22 import java.awt.image.ColorModel ; 23 import java.awt.image.RenderedImage ; 24 import java.awt.image.WritableRaster ; 25 import java.io.BufferedInputStream ; 26 import java.io.File ; 27 import java.io.FileOutputStream ; 28 import java.io.IOException ; 29 import java.io.InputStream ; 30 import java.net.MalformedURLException ; 31 import java.net.URL ; 32 33 import org.apache.batik.ext.awt.image.GraphicsUtil; 34 import org.apache.batik.ext.awt.image.codec.PNGEncodeParam; 35 import org.apache.batik.ext.awt.image.codec.PNGImageEncoder; 36 import org.apache.batik.ext.awt.image.renderable.Filter; 37 import org.apache.batik.ext.awt.image.spi.ImageTagRegistry; 38 import org.apache.batik.test.AbstractTest; 39 import org.apache.batik.test.TestReport; 40 import org.apache.batik.util.ParsedURL; 41 42 50 public class ImageCompareTest extends AbstractTest { 51 public static final String ERROR_COULD_NOT_OPEN_IMAGE 52 = "ImageCompareTest.error.could.not.open.image"; 53 54 public static final String ERROR_COULD_NOT_LOAD_IMAGE 55 = "ImageCompareTest.error.could.not.load.image"; 56 57 public static final String ERROR_DIFFERENCES 58 = "ImageCompareTest.error.differences"; 59 60 public static final String ERROR_WHILE_COMPARING_FILES 61 = "ImageCompareTest.error.while.comparing.files"; 62 63 public static final String ENTRY_KEY_FIRST_IMAGE 64 = "ImageCompareTest.entry.key.first.image"; 65 66 public static final String ENTRY_KEY_SECOND_IMAGE 67 = "ImageCompareTest.entry.key.second.image"; 68 69 public static final String ENTRY_KEY_COMPARISON 70 = "ImageCompareTest.entry.key.comparison"; 71 72 public static final String ENTRY_KEY_DIFFERENCE 73 = "ImageCompareTest.entry.key.difference"; 74 75 public static final String ENTRY_KEY_IMAGE_URL 76 = "ImageCompareTest.entry.key.image.url"; 77 78 public static final String IMAGE_TYPE_DIFFERENCE 79 = "_diff"; 80 81 public static final String IMAGE_TYPE_COMPARISON 82 = "_cmp"; 83 84 88 public static final String TEMP_FILE_PREFIX 89 = "ImageCompareTest"; 90 91 95 public static final String TEMP_FILE_SUFFIX 96 = ""; 97 98 101 protected String urlAStr; 102 protected URL urlA; 103 104 107 protected String urlBStr; 108 protected URL urlB; 109 110 118 protected URL resolveURL(String url){ 119 File f = (new File (url)).getAbsoluteFile(); 121 if(f.exists()){ 122 try{ 123 return f.toURL(); 124 }catch(MalformedURLException e){ 125 throw new IllegalArgumentException (); 126 } 127 } 128 129 try{ 131 return new URL (url); 132 }catch(MalformedURLException e){ 133 throw new IllegalArgumentException (url); 134 } 135 } 136 137 146 public ImageCompareTest(String urlA, 147 String urlB){ 148 urlAStr = urlA; 149 urlBStr = urlB; 150 } 151 152 protected void initURLs(){ 153 if(urlA == null){ 154 throw new IllegalArgumentException (); 155 } 156 157 if(urlB == null){ 158 throw new IllegalArgumentException (); 159 } 160 161 this.urlA = resolveURL(urlAStr); 162 this.urlB = resolveURL(urlBStr); 163 } 164 165 public TestReport rumImpl() throws Exception { 166 initURLs(); 167 168 InputStream streamA = null; 169 170 try{ 171 streamA = new BufferedInputStream (urlA.openStream()); 172 }catch(IOException e){ 173 return reportException(ERROR_COULD_NOT_OPEN_IMAGE, e); 174 } 175 176 InputStream streamB = null; 177 178 try{ 179 streamB = new BufferedInputStream (urlB.openStream()); 180 }catch(IOException e){ 181 return reportException(ERROR_COULD_NOT_OPEN_IMAGE, e); 182 } 183 184 boolean accurate = false; 185 186 try{ 187 accurate = compare(streamA, streamB); 188 }catch(IOException e){ 189 TestReport report = reportException(ERROR_WHILE_COMPARING_FILES, e); 190 report.addDescriptionEntry(ENTRY_KEY_FIRST_IMAGE, 191 urlA.toString()); 192 report.addDescriptionEntry(ENTRY_KEY_SECOND_IMAGE, 193 urlB.toString()); 194 return report; 195 } 196 197 if(accurate){ 198 return reportSuccess(); 199 } 200 201 BufferedImage imageA = getImage(urlA); 204 if(imageA == null){ 205 TestReport report = reportError(ERROR_COULD_NOT_LOAD_IMAGE); 206 report.addDescriptionEntry(ENTRY_KEY_IMAGE_URL, 207 urlA.toString()); 208 return report; 209 } 210 211 BufferedImage imageB = getImage(urlB); 212 if(imageB == null){ 213 TestReport report = reportError(ERROR_COULD_NOT_LOAD_IMAGE); 214 report.addDescriptionEntry(ENTRY_KEY_IMAGE_URL, 215 urlB.toString()); 216 return report; 217 } 218 219 BufferedImage diff = buildDiffImage(imageA, imageB); 220 BufferedImage cmp = buildCompareImage(imageA, imageB); 221 222 File tmpDiff = imageToFile(diff, IMAGE_TYPE_DIFFERENCE); 223 File tmpCmp = imageToFile(cmp, IMAGE_TYPE_COMPARISON); 224 225 TestReport report = reportError(ERROR_DIFFERENCES); 226 report.addDescriptionEntry(ENTRY_KEY_COMPARISON, tmpCmp); 227 report.addDescriptionEntry(ENTRY_KEY_DIFFERENCE, tmpDiff); 228 229 return report; 230 } 231 232 protected BufferedImage buildCompareImage(BufferedImage ref, 233 BufferedImage gen){ 234 BufferedImage cmp = new BufferedImage (ref.getWidth()*2, 235 ref.getHeight(), 236 BufferedImage.TYPE_INT_ARGB); 237 238 Graphics2D g = cmp.createGraphics(); 239 g.setPaint(Color.white); 240 g.fillRect(0, 0, cmp.getWidth(), cmp.getHeight()); 241 g.drawImage(ref, 0, 0, null); 242 g.translate(ref.getWidth(), 0); 243 g.drawImage(gen, 0, 0, null); 244 g.dispose(); 245 246 return cmp; 247 } 248 249 253 protected File imageToFile(BufferedImage img, 254 String imageType) 255 throws IOException { 256 257 File imageFile = makeRandomFileName(imageType); 258 imageFile.deleteOnExit(); 259 260 PNGImageEncoder encoder 261 = new PNGImageEncoder(new FileOutputStream (imageFile), 262 PNGEncodeParam.getDefaultEncodeParam(img)); 263 264 encoder.encode(img); 265 266 return imageFile; 267 268 } 269 270 274 protected File makeRandomFileName(String imageType) 275 throws IOException { 276 277 return File.createTempFile(TEMP_FILE_PREFIX, 278 TEMP_FILE_SUFFIX + imageType, 279 null); 280 } 281 282 285 public static BufferedImage buildDiffImage(BufferedImage ref, 286 BufferedImage gen) { 287 BufferedImage diff = new BufferedImage (ref.getWidth(), 288 ref.getHeight(), 289 BufferedImage.TYPE_INT_ARGB); 290 WritableRaster refWR = ref.getRaster(); 291 WritableRaster genWR = gen.getRaster(); 292 WritableRaster dstWR = diff.getRaster(); 293 294 boolean refPre = ref.isAlphaPremultiplied(); 295 if (!refPre) { 296 ColorModel cm = ref.getColorModel(); 297 cm = GraphicsUtil.coerceData(refWR, cm, true); 298 ref = new BufferedImage (cm, refWR, true, null); 299 } 300 boolean genPre = gen.isAlphaPremultiplied(); 301 if (!genPre) { 302 ColorModel cm = gen.getColorModel(); 303 cm = GraphicsUtil.coerceData(genWR, cm, true); 304 gen = new BufferedImage (cm, genWR, true, null); 305 } 306 307 308 int w=ref.getWidth(); 309 int h=ref.getHeight(); 310 311 int y, i,val; 312 int [] refPix = null; 313 int [] genPix = null; 314 for (y=0; y<h; y++) { 315 refPix = refWR.getPixels (0, y, w, 1, refPix); 316 genPix = genWR.getPixels (0, y, w, 1, genPix); 317 for (i=0; i<refPix.length; i++) { 318 val = ((refPix[i]-genPix[i])*10)+128; 320 if ((val & 0xFFFFFF00) != 0) 321 if ((val & 0x80000000) != 0) val = 0; 322 else val = 255; 323 genPix[i] = val; 324 } 325 dstWR.setPixels(0, y, w, 1, genPix); 326 } 327 328 if (!genPre) { 329 ColorModel cm = gen.getColorModel(); 330 cm = GraphicsUtil.coerceData(genWR, cm, false); 331 } 332 333 if (!refPre) { 334 ColorModel cm = ref.getColorModel(); 335 cm = GraphicsUtil.coerceData(refWR, cm, false); 336 } 337 338 return diff; 339 } 340 341 342 345 public static boolean compare(InputStream refStream, 346 InputStream newStream) 347 throws IOException { 348 int b, nb; 349 do { 350 b = refStream.read(); 351 nb = newStream.read(); 352 } while (b != -1 && nb != -1 && b == nb); 353 refStream.close(); 354 newStream.close(); 355 return (b == nb); 356 } 357 358 361 protected BufferedImage getImage(URL url) { 362 ImageTagRegistry reg = ImageTagRegistry.getRegistry(); 363 Filter filt = reg.readURL(new ParsedURL(url)); 364 if(filt == null){ 365 return null; 366 } 367 368 RenderedImage red = filt.createDefaultRendering(); 369 if(red == null){ 370 return null; 371 } 372 373 BufferedImage img = new BufferedImage (red.getWidth(), 374 red.getHeight(), 375 BufferedImage.TYPE_INT_ARGB); 376 red.copyData(img.getRaster()); 377 378 return img; 379 } 380 381 382 } 383 384 | Popular Tags |