Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 | 2 |
| 3 """ | 3 """ |
| 4 Copyright 2013 Google Inc. | 4 Copyright 2013 Google Inc. |
| 5 | 5 |
| 6 Use of this source code is governed by a BSD-style license that can be | 6 Use of this source code is governed by a BSD-style license that can be |
| 7 found in the LICENSE file. | 7 found in the LICENSE file. |
| 8 | 8 |
| 9 Calulate differences between image pairs, and store them in a database. | 9 Calulate differences between image pairs, and store them in a database. |
| 10 """ | 10 """ |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 # Return early if we do not need to generate diffs. | 115 # Return early if we do not need to generate diffs. |
| 116 if (expected_image_url == actual_image_url or | 116 if (expected_image_url == actual_image_url or |
| 117 not expected_image_url or not actual_image_url): | 117 not expected_image_url or not actual_image_url): |
| 118 return | 118 return |
| 119 | 119 |
| 120 # Get all diff images and values using the skpdiff binary. | 120 # Get all diff images and values using the skpdiff binary. |
| 121 skpdiff_output_dir = tempfile.mkdtemp() | 121 skpdiff_output_dir = tempfile.mkdtemp() |
| 122 try: | 122 try: |
| 123 skpdiff_summary_file = os.path.join(skpdiff_output_dir, | 123 skpdiff_summary_file = os.path.join(skpdiff_output_dir, |
| 124 'skpdiff-output.json') | 124 'skpdiff-output.json') |
| 125 skpdiff_rgbdiff_dir = os.path.join(skpdiff_output_dir, 'rgbDiff') | 125 skpdiff_rgbdiff_dir = os.path.join(storage_root, RGBDIFFS_SUBDIR) |
| 126 skpdiff_whitediff_dir = os.path.join(skpdiff_output_dir, 'whiteDiff') | 126 skpdiff_whitediff_dir = os.path.join(storage_root, WHITEDIFFS_SUBDIR) |
| 127 _mkdir_unless_exists(skpdiff_rgbdiff_dir) | |
| 128 _mkdir_unless_exists(skpdiff_rgbdiff_dir) | |
| 127 | 129 |
| 128 # TODO(epoger): Consider calling skpdiff ONCE for all image pairs, | 130 # TODO(epoger): Consider calling skpdiff ONCE for all image pairs, |
| 129 # instead of calling it separately for each image pair. | 131 # instead of calling it separately for each image pair. |
| 130 # Pro: we'll incur less overhead from making repeated system calls, | 132 # Pro: we'll incur less overhead from making repeated system calls, |
| 131 # spinning up the skpdiff binary, etc. | 133 # spinning up the skpdiff binary, etc. |
| 132 # Con: we would have to wait until all image pairs were loaded before | 134 # Con: we would have to wait until all image pairs were loaded before |
| 133 # generating any of the diffs? | 135 # generating any of the diffs? |
| 134 find_run_binary.run_command( | 136 find_run_binary.run_command( |
| 135 [SKPDIFF_BINARY, '-p', expected_image_file, actual_image_file, | 137 [SKPDIFF_BINARY, '-p', expected_image_file, actual_image_file, |
| 136 '--jsonp', 'false', | 138 '--jsonp', 'false', |
| 139 '--longnames', 'true', | |
| 137 '--output', skpdiff_summary_file, | 140 '--output', skpdiff_summary_file, |
| 138 '--differs', 'perceptual', 'different_pixels', | 141 '--differs', 'perceptual', 'different_pixels', |
| 139 '--rgbDiffDir', skpdiff_rgbdiff_dir, | 142 '--rgbDiffDir', skpdiff_rgbdiff_dir, |
|
epoger
2014/08/11 19:33:27
Instead of adding the --longnames parameter and al
stephana
2014/08/11 20:03:57
That was going to be my first approach (namely to
| |
| 140 '--whiteDiffDir', skpdiff_whitediff_dir, | 143 '--whiteDiffDir', skpdiff_whitediff_dir, |
| 141 ]) | 144 ]) |
| 142 | 145 |
| 143 # Get information out of the skpdiff_summary_file. | 146 # Get information out of the skpdiff_summary_file. |
| 144 with contextlib.closing(open(skpdiff_summary_file)) as fp: | 147 with contextlib.closing(open(skpdiff_summary_file)) as fp: |
| 145 data = json.load(fp) | 148 data = json.load(fp) |
| 146 | 149 |
| 147 # For now, we can assume there is only one record in the output summary, | 150 # For now, we can assume there is only one record in the output summary, |
| 148 # since we passed skpdiff only one pair of images. | 151 # since we passed skpdiff only one pair of images. |
| 149 record = data['records'][0] | 152 record = data['records'][0] |
| 150 self._width = record['width'] | 153 self._width = record['width'] |
| 151 self._height = record['height'] | 154 self._height = record['height'] |
| 152 # TODO: make max_diff_per_channel a tuple instead of a list, because the | 155 # TODO: make max_diff_per_channel a tuple instead of a list, because the |
| 153 # structure is meaningful (first element is red, second is green, etc.) | 156 # structure is meaningful (first element is red, second is green, etc.) |
| 154 # See http://stackoverflow.com/a/626871 | 157 # See http://stackoverflow.com/a/626871 |
| 155 self._max_diff_per_channel = [ | 158 self._max_diff_per_channel = [ |
| 156 record['maxRedDiff'], record['maxGreenDiff'], record['maxBlueDiff']] | 159 record['maxRedDiff'], record['maxGreenDiff'], record['maxBlueDiff']] |
| 157 rgb_diff_path = record['rgbDiffPath'] | |
| 158 white_diff_path = record['whiteDiffPath'] | |
| 159 per_differ_stats = record['diffs'] | 160 per_differ_stats = record['diffs'] |
| 160 for stats in per_differ_stats: | 161 for stats in per_differ_stats: |
| 161 differ_name = stats['differName'] | 162 differ_name = stats['differName'] |
| 162 if differ_name == 'different_pixels': | 163 if differ_name == 'different_pixels': |
| 163 self._num_pixels_differing = stats['pointsOfInterest'] | 164 self._num_pixels_differing = stats['pointsOfInterest'] |
| 164 elif differ_name == 'perceptual': | 165 elif differ_name == 'perceptual': |
| 165 perceptual_similarity = stats['result'] | 166 perceptual_similarity = stats['result'] |
| 166 | 167 |
| 167 # skpdiff returns the perceptual similarity; convert it to get the | 168 # skpdiff returns the perceptual similarity; convert it to get the |
| 168 # perceptual difference percentage. | 169 # perceptual difference percentage. |
| 169 # skpdiff outputs -1 if the images are different sizes. Treat any | 170 # skpdiff outputs -1 if the images are different sizes. Treat any |
| 170 # output that does not lie in [0, 1] as having 0% perceptual | 171 # output that does not lie in [0, 1] as having 0% perceptual |
| 171 # similarity. | 172 # similarity. |
| 172 if not 0 <= perceptual_similarity <= 1: | 173 if not 0 <= perceptual_similarity <= 1: |
| 173 perceptual_similarity = 0 | 174 perceptual_similarity = 0 |
| 174 self._perceptual_difference = 100 - (perceptual_similarity * 100) | 175 self._perceptual_difference = 100 - (perceptual_similarity * 100) |
| 175 | |
| 176 # Store the rgbdiff and whitediff images generated above. | |
| 177 diff_image_locator = _get_difference_locator( | |
|
epoger
2014/08/11 19:33:27
I *think* this is the only call to _get_difference
stephana
2014/08/11 20:03:57
Agreed.
On 2014/08/11 19:33:27, epoger wrote:
| |
| 178 expected_image_locator=expected_image_locator, | |
| 179 actual_image_locator=actual_image_locator) | |
| 180 basename = str(diff_image_locator) + image_suffix | |
| 181 _mkdir_unless_exists(os.path.join(storage_root, RGBDIFFS_SUBDIR)) | |
| 182 _mkdir_unless_exists(os.path.join(storage_root, WHITEDIFFS_SUBDIR)) | |
| 183 # TODO: Modify skpdiff's behavior so we can tell it exactly where to | |
| 184 # write the image files into, rather than having to move them around | |
| 185 # after skpdiff writes them out. | |
| 186 shutil.copyfile(rgb_diff_path, | |
| 187 os.path.join(storage_root, RGBDIFFS_SUBDIR, basename)) | |
| 188 shutil.copyfile(white_diff_path, | |
| 189 os.path.join(storage_root, WHITEDIFFS_SUBDIR, basename)) | |
| 190 | |
| 191 finally: | 176 finally: |
| 192 shutil.rmtree(skpdiff_output_dir) | 177 shutil.rmtree(skpdiff_output_dir) |
| 193 | 178 |
| 194 # TODO(epoger): Use properties instead of getters throughout. | 179 # TODO(epoger): Use properties instead of getters throughout. |
| 195 # See http://stackoverflow.com/a/6618176 | 180 # See http://stackoverflow.com/a/6618176 |
| 196 def get_num_pixels_differing(self): | 181 def get_num_pixels_differing(self): |
| 197 """Returns the absolute number of pixels that differ.""" | 182 """Returns the absolute number of pixels that differ.""" |
| 198 return self._num_pixels_differing | 183 return self._num_pixels_differing |
| 199 | 184 |
| 200 def get_percent_pixels_differing(self): | 185 def get_percent_pixels_differing(self): |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 457 | 442 |
| 458 Args: | 443 Args: |
| 459 expected_image_locator: locator string pointing at expected image | 444 expected_image_locator: locator string pointing at expected image |
| 460 actual_image_locator: locator string pointing at actual image | 445 actual_image_locator: locator string pointing at actual image |
| 461 | 446 |
| 462 Returns: already-sanitized locator where the diffs between expected and | 447 Returns: already-sanitized locator where the diffs between expected and |
| 463 actual images can be found | 448 actual images can be found |
| 464 """ | 449 """ |
| 465 return "%s-vs-%s" % (_sanitize_locator(expected_image_locator), | 450 return "%s-vs-%s" % (_sanitize_locator(expected_image_locator), |
| 466 _sanitize_locator(actual_image_locator)) | 451 _sanitize_locator(actual_image_locator)) |
| OLD | NEW |