Skip to content

Commit 64da4d1

Browse files
committed
Add callout to install ImageMagick
1 parent 343ba7e commit 64da4d1

File tree

5 files changed

+61
-24
lines changed

5 files changed

+61
-24
lines changed

webdiff/app.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,17 +140,27 @@ def get_image(side, path):
140140
def get_pdiff(idx):
141141
idx = int(idx)
142142
pair = DIFF[idx]
143-
_, pdiff_image = util.generate_pdiff_image(pair['a_path'], pair['b_path'])
144-
dilated_image = util.generate_dilated_pdiff_image(pdiff_image)
143+
try:
144+
_, pdiff_image = util.generate_pdiff_image(pair['a_path'], pair['b_path'])
145+
dilated_image = util.generate_dilated_pdiff_image(pdiff_image)
146+
except util.ImageMagickNotAvailableError:
147+
return 'ImageMagick is not available', 501
148+
except util.ImageMagickError as e:
149+
return 'ImageMagick error %s' % e, 501
145150
return send_file(dilated_image)
146151

147152

148153
@app.route("/pdiffbbox/<int:idx>")
149154
def get_pdiff_bbox(idx):
150155
idx = int(idx)
151156
pair = DIFF[idx]
152-
_, pdiff_image = util.generate_pdiff_image(pair['a_path'], pair['b_path'])
153-
bbox = util.get_pdiff_bbox(pdiff_image)
157+
try:
158+
_, pdiff_image = util.generate_pdiff_image(pair['a_path'], pair['b_path'])
159+
bbox = util.get_pdiff_bbox(pdiff_image)
160+
except util.ImageMagickNotAvailableError:
161+
return 'ImageMagick is not available', 501
162+
except util.ImageMagickError as e:
163+
return 'ImageMagick error %s' % e, 501
154164
return jsonify(bbox)
155165

156166

@@ -165,6 +175,7 @@ def file_diff(idx):
165175
idx = int(idx)
166176
return render_template('file_diff.html',
167177
idx=idx,
178+
has_magick=util.is_imagemagick_available(),
168179
pairs=DIFF)
169180

170181

webdiff/static/css/style.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,9 @@ table .side-a, table .side-b {
154154
.diff-box-disabled {
155155
color: gray;
156156
}
157+
.pdiff-options {
158+
margin-left: 10px;
159+
}
160+
.magick {
161+
font-style: italic;
162+
}

webdiff/static/js/image.jsx

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -89,33 +89,44 @@ var ImageDiff = React.createClass({
8989
});
9090
var diffBoxEnabled = isSameSizeImagePair(pair);
9191
var boxClasses = diffBoxEnabled ? '' : 'diff-box-disabled';
92+
var boxStyles = { display: HAS_IMAGE_MAGICK ? '' : 'none' };
93+
var imageMagickCallout = !HAS_IMAGE_MAGICK ? (
94+
<span className="magick">Install{' '}
95+
<a href="http://www.imagemagick.org/script/binary-releases.php">ImageMagick</a>{' '}
96+
to see perceptual diffs</span>
97+
) : null;
9298

9399
return <div>
94100
<div className="image-diff-controls">
95101
<ImageDiffModeSelector {...this.props} />
96102
<input type="checkbox" id="shrink-to-fit" checked={this.state.shrinkToFit} onChange={this.toggleShrinkToFit} />
97103
<label htmlFor="shrink-to-fit"> Shrink to fit</label>
98104
&nbsp;
99-
<span className={boxClasses}>
100-
Perceptual Diff:
101-
<input type="radio" name="pdiff-mode"
102-
id="pdiff-off"
103-
checked={this.props.pdiffMode == PDIFF_MODE.OFF}
104-
disabled={!diffBoxEnabled}
105-
onChange={() => this.setPdiffMode(PDIFF_MODE.OFF)} />
106-
<label htmlFor="pdiff-off"> None</label>
107-
<input type="radio" name="pdiff-mode"
108-
id="pdiff-bbox"
109-
checked={this.props.pdiffMode == PDIFF_MODE.BBOX}
110-
disabled={!diffBoxEnabled}
111-
onChange={() => this.setPdiffMode(PDIFF_MODE.BBOX)} />
112-
<label htmlFor="pdiff-bbox"> Box</label>
113-
<input type="radio" name="pdiff-mode"
114-
id="pdiff-pixels"
115-
checked={this.props.pdiffMode == PDIFF_MODE.PIXELS}
116-
disabled={!diffBoxEnabled}
117-
onChange={() => this.setPdiffMode(PDIFF_MODE.PIXELS)} />
118-
<label htmlFor="pdiff-pixels"> Differing Pixels</label>
105+
<span className="pdiff-options">
106+
<span className={boxClasses} style={boxStyles}>
107+
Perceptual Diff:&nbsp;
108+
<input type="radio" name="pdiff-mode"
109+
id="pdiff-off"
110+
checked={this.props.pdiffMode == PDIFF_MODE.OFF}
111+
disabled={!diffBoxEnabled}
112+
onChange={() => this.setPdiffMode(PDIFF_MODE.OFF)} />
113+
<label htmlFor="pdiff-off"> None</label>
114+
&nbsp;
115+
<input type="radio" name="pdiff-mode"
116+
id="pdiff-bbox"
117+
checked={this.props.pdiffMode == PDIFF_MODE.BBOX}
118+
disabled={!diffBoxEnabled}
119+
onChange={() => this.setPdiffMode(PDIFF_MODE.BBOX)} />
120+
<label htmlFor="pdiff-bbox"> Box</label>
121+
&nbsp;
122+
<input type="radio" name="pdiff-mode"
123+
id="pdiff-pixels"
124+
checked={this.props.pdiffMode == PDIFF_MODE.PIXELS}
125+
disabled={!diffBoxEnabled}
126+
onChange={() => this.setPdiffMode(PDIFF_MODE.PIXELS)} />
127+
<label htmlFor="pdiff-pixels"> Differing Pixels</label>
128+
</span>
129+
{imageMagickCallout}
119130
</span>
120131
</div>
121132
<div className={'image-diff ' + mode}>

webdiff/templates/file_diff.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<script>
1515
var pairs = {{pairs|tojson}};
1616
var initialIdx = {{idx|tojson}};
17+
var HAS_IMAGE_MAGICK = {{has_magick|tojson}};
1718
</script>
1819

1920
<script type="text/jsx;harmony=true" src="/static/js/util.js"></script>

webdiff/util.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ def _annotate_file_pair(d, a_dir, b_dir):
121121
d['are_same_pixels'], _ = generate_pdiff_image(a_path, b_path)
122122
except ImageMagickError:
123123
d['are_same_pixels'] = False
124+
except ImageMagickNotAvailableError:
125+
pass
124126

125127
if a_path and b_path:
126128
d['no_changes'] = _are_files_identical(a_path, b_path)
@@ -260,6 +262,7 @@ def diff_for_args(args):
260262
return [a_dir, b_dir] + [find_diff(a_dir, b_dir)]
261263

262264

265+
@memoize
263266
def is_imagemagick_available():
264267
try:
265268
# this swallows stdout/stderr
@@ -307,6 +310,8 @@ def generate_pdiff_image(before_path, after_path):
307310
@memoize
308311
def generate_dilated_pdiff_image(diff_path):
309312
'''Given a pdiff image, dilate it to highlight small differences.'''
313+
if not is_imagemagick_available():
314+
raise ImageMagickNotAvailableError()
310315

311316
# Dilate the diff image (to highlight small differences) and make it red.
312317
_, diff_dilate_path = tempfile.mkstemp(suffix='.png')
@@ -326,6 +331,9 @@ def generate_dilated_pdiff_image(diff_path):
326331
@memoize
327332
def get_pdiff_bbox(diff_path):
328333
'''Returns {top,left,width,height} for the content of a pdiff.'''
334+
if not is_imagemagick_available():
335+
raise ImageMagickNotAvailableError()
336+
329337
out = subprocess.check_output(['identify', '-format', '%@', diff_path])
330338
# This looks like "26x94+0+830"
331339
m = re.match(r'^(\d+)x(\d+)\+(\d+)\+(\d+)', out)

0 commit comments

Comments
 (0)