|
14 | 14 | import urllib2 |
15 | 15 | import glob |
16 | 16 |
|
17 | | -def error ( msg ): |
18 | | - print msg |
19 | | - sys.exit( 1 ) |
20 | 17 |
|
21 | | -def colorDiff( c1, c2 ): |
22 | | - redDiff = abs( qRed( c1 ) - qRed( c2 ) ) |
23 | | - greenDiff = abs( qGreen( c1 ) - qGreen( c2 ) ) |
24 | | - blueDiff = abs( qBlue( c1 ) - qBlue( c2 ) ) |
25 | | - alphaDiff = abs( qAlpha( c1 ) - qAlpha( c2 ) ) |
26 | | - return max( redDiff, greenDiff, blueDiff, alphaDiff ) |
| 18 | +def error(msg): |
| 19 | + print msg |
| 20 | + sys.exit(1) |
| 21 | + |
| 22 | + |
| 23 | +def colorDiff(c1, c2): |
| 24 | + redDiff = abs(qRed(c1) - qRed(c2)) |
| 25 | + greenDiff = abs(qGreen(c1) - qGreen(c2)) |
| 26 | + blueDiff = abs(qBlue(c1) - qBlue(c2)) |
| 27 | + alphaDiff = abs(qAlpha(c1) - qAlpha(c2)) |
| 28 | + return max(redDiff, greenDiff, blueDiff, alphaDiff) |
| 29 | + |
27 | 30 |
|
28 | 31 | def imageFromPath(path): |
29 | | - if ( path[:7] == 'http://' or path[:7] == 'file://' ): |
30 | | - #fetch remote image |
31 | | - data = urllib2.urlopen(path).read() |
32 | | - image = QImage() |
33 | | - image.loadFromData(data) |
34 | | - else: |
35 | | - image = QImage( path ) |
36 | | - return image |
| 32 | + if (path[:7] == 'http://' or path[:7] == 'file://'): |
| 33 | + #fetch remote image |
| 34 | + data = urllib2.urlopen(path).read() |
| 35 | + image = QImage() |
| 36 | + image.loadFromData(data) |
| 37 | + else: |
| 38 | + image = QImage(path) |
| 39 | + return image |
| 40 | + |
37 | 41 |
|
38 | 42 | def getControlImagePath(path): |
39 | | - if os.path.isfile(path): |
40 | | - return path |
| 43 | + if os.path.isfile(path): |
| 44 | + return path |
| 45 | + |
| 46 | + #else try and find matching test image |
| 47 | + script_folder = os.path.dirname(os.path.realpath(sys.argv[0])) |
| 48 | + control_images_folder = os.path.join(script_folder, '../tests/testdata/control_images') |
41 | 49 |
|
42 | | - #else try and find matching test image |
43 | | - script_folder = os.path.dirname(os.path.realpath(sys.argv[0])) |
44 | | - control_images_folder = os.path.join( script_folder, '../tests/testdata/control_images') |
| 50 | + matching_control_images = [x[0] for x in os.walk(control_images_folder) if path in x[0]] |
| 51 | + if len(matching_control_images) > 1: |
| 52 | + error('Found multiple matching control images for {}'.format(path)) |
| 53 | + elif len(matching_control_images) == 0: |
| 54 | + error('No matching control images found for {}'.format(path)) |
45 | 55 |
|
46 | | - matching_control_images = [x[0] for x in os.walk(control_images_folder) if path in x[0]] |
47 | | - if len(matching_control_images) > 1: |
48 | | - error('Found multiple matching control images for {}'.format(path)) |
49 | | - elif len(matching_control_images) == 0: |
50 | | - error('No matching control images found for {}'.format(path)) |
| 56 | + found_control_image_path = matching_control_images[0] |
51 | 57 |
|
52 | | - found_control_image_path = matching_control_images[0] |
| 58 | + #check for a single matching expected image |
| 59 | + images = glob.glob(os.path.join(found_control_image_path, '*.png')) |
| 60 | + filtered_images = [i for i in images if not i[-9:] == '_mask.png'] |
| 61 | + if len(filtered_images) > 1: |
| 62 | + error('Found multiple matching control images for {}'.format(path)) |
| 63 | + elif len(filtered_images) == 0: |
| 64 | + error('No matching control images found for {}'.format(path)) |
53 | 65 |
|
54 | | - #check for a single matching expected image |
55 | | - images = glob.glob( os.path.join(found_control_image_path, '*.png') ) |
56 | | - filtered_images = [i for i in images if not i[-9:] == '_mask.png'] |
57 | | - if len(filtered_images) > 1: |
58 | | - error('Found multiple matching control images for {}'.format(path)) |
59 | | - elif len(filtered_images) == 0: |
60 | | - error('No matching control images found for {}'.format(path)) |
| 66 | + found_image = filtered_images[0] |
| 67 | + print 'Found matching control image: {}'.format(found_image) |
| 68 | + return found_image |
61 | 69 |
|
62 | | - found_image = filtered_images[0] |
63 | | - print 'Found matching control image: {}'.format(found_image) |
64 | | - return found_image |
65 | 70 |
|
66 | 71 | def updateMask(control_image_path, rendered_image_path, mask_image_path): |
67 | | - control_image = imageFromPath( control_image_path ) |
68 | | - if not control_image: |
69 | | - error('Could not read control image {}'.format(control_image_path)) |
70 | | - |
71 | | - rendered_image = imageFromPath( rendered_image_path ) |
72 | | - if not rendered_image: |
73 | | - error('Could not read rendered image {}'.format(rendered_image_path)) |
74 | | - if not rendered_image.width() == control_image.width() or not rendered_image.height() == control_image.height(): |
75 | | - print ('Size mismatch - control image is {}x{}, rendered image is {}x{}'.format(control_image.width(), |
76 | | - control_image.height(), |
77 | | - rendered_image.width(), |
78 | | - rendered_image.height())) |
79 | | - |
80 | | - max_width = min( rendered_image.width(), control_image.width() ) |
81 | | - max_height = min( rendered_image.height(), control_image.height() ) |
82 | | - |
83 | | - #read current mask, if it exist |
84 | | - mask_image = imageFromPath( mask_image_path ) |
85 | | - if mask_image.isNull(): |
86 | | - print 'Mask image does not exist, creating {}'.format( mask_image_path ) |
87 | | - mask_image = QImage( control_image.width(), control_image.height(), QImage.Format_ARGB32 ) |
88 | | - mask_image.fill( QColor(0,0,0) ) |
89 | | - |
90 | | - #loop through pixels in rendered image and compare |
91 | | - mismatch_count = 0 |
92 | | - linebytes = max_width * 4 |
93 | | - for y in xrange( max_height ): |
94 | | - control_scanline = control_image.constScanLine( y ).asstring(linebytes) |
95 | | - rendered_scanline = rendered_image.constScanLine( y ).asstring(linebytes) |
96 | | - mask_scanline = mask_image.scanLine( y ).asstring(linebytes) |
97 | | - |
98 | | - for x in xrange( max_width ): |
99 | | - currentTolerance = qRed( struct.unpack('I', mask_scanline[ x*4:x*4+4 ] )[0] ) |
100 | | - |
101 | | - if currentTolerance == 255: |
102 | | - #ignore pixel |
103 | | - continue |
104 | | - |
105 | | - expected_rgb = struct.unpack('I', control_scanline[ x*4:x*4+4 ] )[0] |
106 | | - rendered_rgb = struct.unpack('I', rendered_scanline[ x*4:x*4+4 ] )[0] |
107 | | - difference = colorDiff( expected_rgb, rendered_rgb ) |
108 | | - |
109 | | - if difference > currentTolerance: |
110 | | - #update mask image |
111 | | - mask_image.setPixel( x, y, qRgb( difference, difference, difference ) ) |
112 | | - mismatch_count += 1 |
113 | | - |
114 | | - if mismatch_count: |
115 | | - #update mask |
116 | | - mask_image.save( mask_image_path, "png" ) |
117 | | - print 'Updated {} pixels in {}'.format( mismatch_count, mask_image_path ) |
118 | | - else: |
119 | | - print 'No mismatches in {}'.format( mask_image_path ) |
| 72 | + control_image = imageFromPath(control_image_path) |
| 73 | + if not control_image: |
| 74 | + error('Could not read control image {}'.format(control_image_path)) |
| 75 | + |
| 76 | + rendered_image = imageFromPath(rendered_image_path) |
| 77 | + if not rendered_image: |
| 78 | + error('Could not read rendered image {}'.format(rendered_image_path)) |
| 79 | + if not rendered_image.width() == control_image.width() or not rendered_image.height() == control_image.height(): |
| 80 | + print ('Size mismatch - control image is {}x{}, rendered image is {}x{}'.format(control_image.width(), |
| 81 | + control_image.height(), |
| 82 | + rendered_image.width(), |
| 83 | + rendered_image.height())) |
| 84 | + |
| 85 | + max_width = min(rendered_image.width(), control_image.width()) |
| 86 | + max_height = min(rendered_image.height(), control_image.height()) |
| 87 | + |
| 88 | + #read current mask, if it exist |
| 89 | + mask_image = imageFromPath(mask_image_path) |
| 90 | + if mask_image.isNull(): |
| 91 | + print 'Mask image does not exist, creating {}'.format(mask_image_path) |
| 92 | + mask_image = QImage(control_image.width(), control_image.height(), QImage.Format_ARGB32) |
| 93 | + mask_image.fill(QColor(0, 0, 0)) |
| 94 | + |
| 95 | + #loop through pixels in rendered image and compare |
| 96 | + mismatch_count = 0 |
| 97 | + linebytes = max_width * 4 |
| 98 | + for y in xrange(max_height): |
| 99 | + control_scanline = control_image.constScanLine(y).asstring(linebytes) |
| 100 | + rendered_scanline = rendered_image.constScanLine(y).asstring(linebytes) |
| 101 | + mask_scanline = mask_image.scanLine(y).asstring(linebytes) |
| 102 | + |
| 103 | + for x in xrange(max_width): |
| 104 | + currentTolerance = qRed(struct.unpack('I', mask_scanline[x * 4:x * 4 + 4])[0]) |
| 105 | + |
| 106 | + if currentTolerance == 255: |
| 107 | + #ignore pixel |
| 108 | + continue |
| 109 | + |
| 110 | + expected_rgb = struct.unpack('I', control_scanline[x * 4:x * 4 + 4])[0] |
| 111 | + rendered_rgb = struct.unpack('I', rendered_scanline[x * 4:x * 4 + 4])[0] |
| 112 | + difference = colorDiff(expected_rgb, rendered_rgb) |
| 113 | + |
| 114 | + if difference > currentTolerance: |
| 115 | + #update mask image |
| 116 | + mask_image.setPixel(x, y, qRgb(difference, difference, difference)) |
| 117 | + mismatch_count += 1 |
| 118 | + |
| 119 | + if mismatch_count: |
| 120 | + #update mask |
| 121 | + mask_image.save(mask_image_path, "png") |
| 122 | + print 'Updated {} pixels in {}'.format(mismatch_count, mask_image_path) |
| 123 | + else: |
| 124 | + print 'No mismatches in {}'.format(mask_image_path) |
120 | 125 |
|
121 | 126 | parser = argparse.ArgumentParser() # OptionParser("usage: %prog control_image rendered_image mask_image") |
122 | 127 | parser.add_argument('control_image') |
123 | 128 | parser.add_argument('rendered_image') |
124 | 129 | parser.add_argument('mask_image', nargs='?', default=None) |
125 | 130 | args = parser.parse_args() |
126 | 131 |
|
127 | | -args.control_image = getControlImagePath( args.control_image) |
| 132 | +args.control_image = getControlImagePath(args.control_image) |
128 | 133 |
|
129 | 134 | if not args.mask_image: |
130 | | - args.mask_image = args.control_image[:-4] + '_mask.png' |
| 135 | + args.mask_image = args.control_image[:-4] + '_mask.png' |
131 | 136 |
|
132 | 137 | updateMask(args.control_image, args.rendered_image, args.mask_image) |
0 commit comments