Created
March 31, 2011 14:47
-
-
Save ynkdir/896487 to your computer and use it in GitHub Desktop.
github like image diff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
<title>github like image diff</title> | |
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/themes/ui-lightness/jquery-ui.css" /> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script> | |
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js"></script> | |
<style> | |
body { | |
background: #808080; | |
} | |
</style> | |
<script> | |
function LoadImage(url) { | |
var d = $.Deferred(); | |
var img = new Image(); | |
img.onload = function() { d.resolve(img); }; | |
img.src = url; | |
return d.promise(); | |
} | |
function ImageDataGetPixel(imgdata, x, y) { | |
var i = (y * imgdata.width + x) * 4; | |
var r = imgdata.data[i]; | |
var g = imgdata.data[i + 1]; | |
var b = imgdata.data[i + 2]; | |
var a = imgdata.data[i + 3]; | |
return [r, g, b, a]; | |
} | |
function ImageDataSetPixel(imgdata, x, y, pixel) { | |
var i = (y * imgdata.width + x) * 4; | |
imgdata.data[i] = pixel[0]; | |
imgdata.data[i + 1] = pixel[1]; | |
imgdata.data[i + 2] = pixel[2]; | |
imgdata.data[i + 3] = pixel[3]; | |
} | |
function DiffPixel(p1, p2) { | |
var r = p1[0] - p2[0]; | |
var g = p1[1] - p2[1]; | |
var b = p1[2] - p2[2]; | |
var a = p1[3] - p2[3]; | |
if (r < 0) { r = -r; } | |
if (g < 0) { g = -g; } | |
if (b < 0) { b = -b; } | |
if (a < 0) { a = -b; } | |
return [r, g, b, 255]; | |
} | |
// TODO: use background | |
// background-image: -moz-element(#canvaselement) | |
function CreateTransBackgroundImage(img, width, height) { | |
var canvas = document.createElement('canvas'); | |
canvas.width = width; | |
canvas.height = height; | |
var ctx = canvas.getContext('2d'); | |
var size = 5; | |
var yi = 0; | |
var xi = 0; | |
var x, y; | |
for (y = 0; y < width; y += 5) { | |
xi = yi % 2 ? 0 : 1; | |
for (x = 0; x < width; x += 5) { | |
if (xi % 2) { | |
ctx.fillStyle = 'rgb(196, 196, 196)'; | |
} else { | |
ctx.fillStyle = 'rgb(255, 255, 255)'; | |
} | |
ctx.fillRect(x, y, size, size); | |
xi++; | |
} | |
yi++; | |
} | |
ctx.drawImage(img, | |
Math.round((width - img.width) / 2), | |
Math.round((height - img.height) / 2)); | |
return canvas; | |
} | |
function cmp_2up(img1, img2) { | |
//var e1 = $('<img\/>').attr('src', img1.src) | |
var e1 = $(CreateTransBackgroundImage(img1, img1.width, img1.height)) | |
.css({ | |
width: img1.width, | |
height: img1.height, | |
border: '1px solid red' | |
}); | |
//var e2 = $('<img\/>').attr('src', img2.src) | |
var e2 = $(CreateTransBackgroundImage(img2, img2.width, img2.height)) | |
.css({ | |
width: img2.width, | |
height: img2.height, | |
border: '1px solid green' | |
}); | |
$('#cmp_2up') | |
.html('') | |
.append(e1, e2); | |
} | |
function cmp_swipe(img1, img2) { | |
var width = Math.max(img1.width, img2.width); | |
var height = Math.max(img1.height, img2.height); | |
//var e1 = $('<img\/>').attr('src', img1.src) | |
var e1 = $(CreateTransBackgroundImage(img1, img1.width, img1.height)) | |
.css({ | |
position: 'absolute', | |
left: Math.round((width - img1.width) / 2), | |
top: Math.round((height - img1.height) / 2), | |
border: '1px solid red' | |
}); | |
// e1.clone() not work for canvas | |
var e1clone = $(CreateTransBackgroundImage(img1, img1.width, img1.height)) | |
.css({ | |
position: 'absolute', | |
left: Math.round((width - img1.width) / 2), | |
top: Math.round((height - img1.height) / 2), | |
border: '1px solid red' | |
}); | |
//var e2 = $('<img\/>').attr('src', img2.src) | |
var e2 = $(CreateTransBackgroundImage(img2, img2.width, img2.height)) | |
.css({ | |
position: 'absolute', | |
left: Math.round((width - img2.width) / 2), | |
top: Math.round((height - img2.height) / 2), | |
border: '1px solid green' | |
}); | |
var e3 = $('<div><\/div>') | |
.css({ | |
position: 'absolute', | |
left: 0, | |
top: 0, | |
width: 0, | |
height: height, | |
borderRight: '1px solid gray', | |
overflow: 'hidden' | |
}) | |
//.append(e1.clone()); | |
.append(e1clone); | |
var container = $('<div><\/div>') | |
.css({ | |
position: 'relative', | |
width: width, | |
height: height | |
}) | |
.append(e1, e2, e3); | |
var slider = $('<div><\/div>') | |
.css({ | |
width: width | |
}) | |
.slider({ | |
value: 0, | |
slide: function(event, ui) { | |
$(e3).css({ | |
width: Math.round(width * (ui.value / 100)) | |
}); | |
} | |
}); | |
$('#cmp_swipe') | |
.html('') | |
.append(container, slider); | |
} | |
function cmp_onion(img1, img2) { | |
var width = Math.max(img1.width, img2.width); | |
var height = Math.max(img1.height, img2.height); | |
//var e1 = $('<img\/>').attr('src', img1.src) | |
var e1 = $(CreateTransBackgroundImage(img1, img1.width, img1.height)) | |
.css({ | |
position: 'absolute', | |
left: Math.round((width - img1.width) / 2), | |
top: Math.round((height - img1.height) / 2), | |
border: '1px solid red' | |
}); | |
//var e2 = $('<img\/>').attr('src', img2.src) | |
var e2 = $(CreateTransBackgroundImage(img2, img2.width, img2.height)) | |
.css({ | |
position: 'absolute', | |
left: Math.round((width - img2.width) / 2), | |
top: Math.round((height - img2.height) / 2), | |
border: '1px solid green' | |
}); | |
var container = $('<div><\/div>') | |
.css({ | |
position: 'relative', | |
width: width, | |
height: height | |
}) | |
.append(e1, e2); | |
var slider = $('<div><\/div>') | |
.css({ | |
width: width | |
}) | |
.slider({ | |
value: 100, | |
slide: function(event, ui) { | |
$(e2).css('opacity', ui.value / 100); | |
} | |
}); | |
$('#cmp_onion') | |
.html('') | |
.append(container, slider); | |
} | |
function cmp_diff(img1, img2) { | |
var width = Math.max(img1.width, img2.width); | |
var height = Math.max(img1.height, img2.height); | |
var canvas = document.createElement('canvas'); | |
canvas.width = width; | |
canvas.height = height; | |
var ctx = canvas.getContext('2d'); | |
ctx.fillStyle = 'rgb(0, 0, 0)'; | |
ctx.fillRect(0, 0, width, height); | |
ctx.drawImage(img1, | |
Math.round((width - img1.width) / 2), | |
Math.round((height - img1.height) / 2)); | |
var imgdata1 = ctx.getImageData(0, 0, width, height); | |
ctx.fillStyle = 'rgb(0, 0, 0)'; | |
ctx.fillRect(0, 0, width, height); | |
ctx.drawImage(img2, | |
Math.round((width - img2.width) / 2), | |
Math.round((height - img2.height) / 2)); | |
var imgdata2 = ctx.getImageData(0, 0, width, height); | |
var imgdiff = ctx.createImageData(width, height); | |
var x, y; | |
for (y = 0; y < img1.height; ++y) { | |
for (x = 0; x < img1.width; ++x) { | |
var p1 = ImageDataGetPixel(imgdata1, x, y); | |
var p2 = ImageDataGetPixel(imgdata2, x, y); | |
ImageDataSetPixel(imgdiff, x, y, DiffPixel(p1, p2)); | |
} | |
} | |
ctx.putImageData(imgdiff, 0, 0); | |
$('#cmp_diff') | |
.html('') | |
.append(canvas); | |
} | |
function MakeDiff() { | |
var img1_url = document.getElementById('img1_url').value; | |
var img2_url = document.getElementById('img2_url').value; | |
$.when(LoadImage(img1_url), LoadImage(img2_url)) | |
.done(function(img1, img2) { | |
cmp_2up(img1, img2); | |
cmp_swipe(img1, img2); | |
cmp_onion(img1, img2); | |
try { | |
cmp_diff(img1, img2); | |
} catch (e) { | |
$('#cmp_diff').html(e.toString()); | |
} | |
}); | |
} | |
</script> | |
</head> | |
<body> | |
<div> | |
img1: <input id="img1_url" name="img1_url" type="text" value="" /><br /> | |
img2: <input id="img2_url" name="img2_url" type="text" value="" /><br /> | |
<button type="button" onclick="MakeDiff();">load</button> | |
<button type="button" onclick="$('#img1_url').val('https://github.com/cameronmcefee/Image-Diff-View-Modes/raw/8bf009f5e2aaf3c363d64d4e013527589c810b7e/1_normal.jpg'); $('#img2_url').val('https://github.com/cameronmcefee/Image-Diff-View-Modes/raw/8e95f70c9c47168305970e91021072673d7cdad8/1_normal.jpg'); MakeDiff();">1</button> | |
<button type="button" onclick="$('#img1_url').val('https://github.com/cameronmcefee/Image-Diff-View-Modes/raw/8bf009f5e2aaf3c363d64d4e013527589c810b7e/2_transparentPixels.png'); $('#img2_url').val('https://github.com/cameronmcefee/Image-Diff-View-Modes/raw/8e95f70c9c47168305970e91021072673d7cdad8/2_transparentPixels.png'); MakeDiff();">2</button> | |
<button type="button" onclick="$('#img1_url').val('https://github.com/cameronmcefee/Image-Diff-View-Modes/raw/8bf009f5e2aaf3c363d64d4e013527589c810b7e/3_tooLarge.jpg'); $('#img2_url').val('https://github.com/cameronmcefee/Image-Diff-View-Modes/raw/8e95f70c9c47168305970e91021072673d7cdad8/3_tooLarge.jpg'); MakeDiff();">3</button> | |
<button type="button" onclick="$('#img1_url').val('https://github.com/cameronmcefee/Image-Diff-View-Modes/raw/8bf009f5e2aaf3c363d64d4e013527589c810b7e/4_differentSize.jpg'); $('#img2_url').val('https://github.com/cameronmcefee/Image-Diff-View-Modes/raw/8e95f70c9c47168305970e91021072673d7cdad8/4_differentSize.jpg'); MakeDiff();">4</button> | |
</div> | |
<h3>2up</h3> | |
<div id="cmp_2up"></div> | |
<h3>swipe</h3> | |
<div id="cmp_swipe"></div> | |
<h3>onion</h3> | |
<div id="cmp_onion"></div> | |
<h3>diff (don't work for other domain's image due to security reason)</h3> | |
<div id="cmp_diff"></div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment