Browse Source

added files

pull/6/merge
James Cryer 12 years ago
parent
commit
04b6b74e3e
  1. 91
      demoassets/main.js
  2. 64
      demoassets/resemble.css
  3. 148
      index.html
  4. 9
      libs/twitter-bootstrap/bootstrap.min.css
  5. 67
      resemble.css
  6. 234
      resemble.js

91
demoassets/main.js

@ -0,0 +1,91 @@
$(function(){
var $target = $('#drop-zone');
function dropZone($target, onDrop){
$target.
bind('dragover', function(){
$target.addClass( 'drag-over' );
return false;
}).
bind("dragend", function () {
$target.removeClass( 'drag-over' );
return false;
}).
bind("mouseout", function () {
$target.removeClass( 'drag-over' );
return false;
}).
bind("drop", function(event) {
var file = event.originalEvent.dataTransfer.files[0];
event.stopPropagation();
event.preventDefault();
$target.removeClass( 'drag-over' );
var droppedImage = new Image();
var fileReader = new FileReader();
fileReader.onload = function (event) {
droppedImage.src = event.target.result;
$target.html(droppedImage);
};
fileReader.readAsDataURL(file);
onDrop(file);
});
}
dropZone($target, function(file){
resemble(file).onComplete(function(data){
$('#image-data').show();
$('#red').css('width',data.red+'%');
$('#green').css('width',data.green+'%');
$('#blue').css('width',data.blue+'%');
$('#brightness').css('width',data.brightness+'%');
});
});
function onComplete(data){
var diffImage = new Image();
diffImage.src = data.imageDiffFileData;
$('#image-diff').html(diffImage);
$(diffImage).click(function(){
window.open(diffImage.src, '_blank');
});
if(data.misMatchPercentage == 0){
$('#thesame').show();
$('#diff-results').hide();
} else {
$('#mismatch').text(data.misMatchPercentage);
if(!data.isSameDimensions){
$('#differentdimensions').show();
} else {
$('#differentdimensions').hide();
}
$('#diff-results').show();
$('#thesame').hide();
}
}
var file1;
var file2;
dropZone($('#dropzone1'), function(file){
file1 = file;
if(file2){
resemble(file).compareTo(file2).onComplete(onComplete);
}
});
dropZone($('#dropzone2'), function(file){
file2 = file;
if(file1){
resemble(file).compareTo(file1).onComplete(onComplete);
}
});
});

64
demoassets/resemble.css

@ -0,0 +1,64 @@
h1 {
text-align: center;
}
body {
padding-top: 60px;
}
footer {
margin-top: 45px;
padding: 35px 0 36px;
border-top: 1px solid #e5e5e5;
}
.drop-zone{
border: 10px dashed #ccc;
color: #ccc;
font-size: 32px;
height: 400px;
line-height: 400px;
text-align: center;
width: 400px;
overflow: hidden;
position: relative;
}
.drop-zone.drag-over{
border: 10px dashed #0088CC;
}
.drop-zone img {
width: 400px;
position: absolute;
top: 0;
left: 0;
}
.small-drop-zone{
margin-top: 20px;
margin-left: 90px;
border: 10px dashed #ccc;
color: #ccc;
font-size: 32px;
height: 330px;
line-height: 330px;
text-align: center;
width: 330px;
overflow: hidden;
position: relative;
}
.small-drop-zone.drag-over{
border: 10px dashed #0088CC;
}
.small-drop-zone img {
width: 330px;
position: absolute;
top: 0;
left: 0;
}
#image-diff {
margin-left: 0px;
margin-top: 90px;
border-style: solid;
}

148
index.html

@ -0,0 +1,148 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Resemble.js : Image analysis</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="libs/twitter-bootstrap/bootstrap.min.css">
<link rel="stylesheet" href="demoassets/resemble.css">
</head>
<body>
<div class="container">
<header>
<div class="page-header">
<h1>Resemble.js : Image analysis and comparison</h1>
</div>
</header>
<section role="main">
<div class="row">
<div class="span12">
<div class="hero-unit">
<div class="row">
<div class="span6">
<p>
<div id="drop-zone" class="drop-zone">
Drop image here.
</div>
</p>
</div>
<div class="span4">
<h2>What is this?</h2>
<p>
Resemble.js analyses and compares images with HTML5 canvas and JavaScript.
</p>
<p>
<strong>Try it for yourself.</strong>
</p>
<div id="image-data" style="display:none">
RGB
<div class="progress progress-danger">
<div id="red" class="bar" style="width: 0%;"></div>
</div>
<div class="progress progress-success">
<div id="green" class="bar" style="width: 0%;"></div>
</div>
<div class="progress">
<div id="blue" class="bar" style="width: 0%;"></div>
</div>
Brightness
<div class="progress progress-warning">
<div id="brightness" class="bar" style="width: 0%;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="span12">
<div class="row">
<div class="span6">
<div id="dropzone1" class="small-drop-zone">
Drop first image
</div>
<div id="dropzone2" class="small-drop-zone">
Drop second image
</div>
</div>
<div class="span6">
<h2>Compare two images?</h2>
<p>
Drop two images on the boxes to the right. The box below will show a generated 'diff' image, pink areas show mismatch. This example best works with two very similar but slightly different images. Try for yourself!
</p>
<div id="image-diff" class="small-drop-zone">
Diff will appear here.
</div>
<br/>
<p id="diff-results" style="display:none;">
<strong>The second image is <span id="mismatch"></span>% different compared to the first.
<span id="differentdimensions" style="display:none;">And they have different dimensions.</span></strong>
</p>
<p id="thesame" style="display:none;">
<strong>These images are the same!</strong>
</p>
</div>
</div>
</div>
</div>
<br/><br/>
<div class="row">
<div class="span6">
<h2>How does it work?</h2>
<p>
Dark magic.
</p>
<p>
<br/>
<a class="btn btn-large btn-primary" href="#"><strong>View project on Github</strong></a>
</p>
</div>
<div class="span6">
<h2>How can I use it?</h2>
<p>Invoke Resemble on an image or canvas image to extract data</p>
<pre>
var data = resemble('img').onComplete(function(data){
return data;
});
/*
{
red: 255,
green: 255,
blue: 255,
brightness: 255
}
*/</pre>
<p>Use resemble to compare two image</p>
<pre>
resemble(file).compareTo(file2).onComplete(function(){
return data;
});
/*
{
misMatchPercentage : 100, // %
isSameDimensions: true, // or false
imageDiffFileData: {} // dataUrl of image as png
}
*/</pre>
</div>
</div>
</section>
<footer class="footer">
<p>
Footer message
</p>
</footer>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="resemble.js"></script>
<script src="demoassets/main.js"></script>
</body>
</html>

9
libs/twitter-bootstrap/bootstrap.min.css vendored

File diff suppressed because one or more lines are too long

67
resemble.css

@ -0,0 +1,67 @@
h1 {
text-align: center;
}
body {
padding-top: 60px;
}
footer {
margin-top: 45px;
padding: 35px 0 36px;
border-top: 1px solid #e5e5e5;
}
.drop-zone{
border: 10px dashed #ccc;
color: #ccc;
font-size: 32px;
height: 400px;
line-height: 400px;
text-align: center;
width: 400px;
overflow: hidden;
position: relative;
}
.drop-zone.drag-over{
border: 10px dashed #0088CC;
}
.drop-zone img {
width: 400px;
position: absolute;
top: 0;
left: 0;
}
.small-drop-zone{
margin-top: 20px;
margin-left: 90px;
border: 10px dashed #ccc;
color: #ccc;
font-size: 32px;
height: 330px;
line-height: 330px;
text-align: center;
width: 330px;
overflow: hidden;
position: relative;
}
.small-drop-zone.drag-over{
border: 10px dashed #0088CC;
}
.small-drop-zone img {
width: 330px;
position: absolute;
top: 0;
left: 0;
}
#image-diff {
margin-left: 0px;
margin-top: 90px;
border-style: solid;
}
#image-diff img {
cursor: pointer !important;
}

234
resemble.js

@ -0,0 +1,234 @@
(function(_this){
_this['resemble'] = function( fileData ){
var data = {};
var images = [];
var updateCallbackArray = [];
var tolerance = [ // between 0 and 255
255, // red
255, // green 16
255, // blue 24
255, // alpha
255 // brightness
];
function triggerDataUpdate(){
var len = updateCallbackArray.length;
var i;
for(i=0;i<len;i++){
if (typeof updateCallbackArray[i] === 'function'){
updateCallbackArray[i](data);
}
}
}
function loop(x, y, callback){
var i,j;
for (i=0;i<x;i++){
for (j=0;j<y;j++){
callback(i, j);
}
}
}
function parseImage(sourceImageData, width, height){
var pixleCount = 0;
var redTotal = 0;
var greenTotal = 0;
var blueTotal = 0;
var brightnessTotal = 0;
loop(height, width, function(verticalPos, horizontalPos){
var offset = (verticalPos*width + horizontalPos) * 4;
var red = sourceImageData[offset];
var green = sourceImageData[offset + 1];
var blue = sourceImageData[offset + 2];
var alpha = sourceImageData[offset + 3];
var brightness = (0.3*red + 0.59*green + 0.11*blue);
pixleCount++;
redTotal += red / 255 * 100;
greenTotal += green / 255 * 100;
blueTotal += blue / 255 * 100;
brightnessTotal += brightness / 255 * 100;
});
data.red = Math.floor(redTotal / pixleCount);
data.green = Math.floor(greenTotal / pixleCount);
data.blue = Math.floor(blueTotal / pixleCount);
data.brightness = Math.floor(brightnessTotal / pixleCount);
triggerDataUpdate();
}
function loadImageData( fileData, callback ){
var hiddenImage = new Image();
var fileReader = new FileReader();
fileReader.onload = function (event) {
hiddenImage.src = event.target.result;
};
hiddenImage.onload = function() {
var hiddenCanvas = document.createElement('canvas');
var imageData;
var width = hiddenImage.width;
var height = hiddenImage.height;
hiddenCanvas.width = width;
hiddenCanvas.height = height;
hiddenCanvas.getContext('2d').drawImage(hiddenImage, 0, 0, width, height);
imageData = hiddenCanvas.getContext('2d').getImageData(0, 0, width, height);
images.push(imageData);
callback(imageData, width, height);
};
fileReader.readAsDataURL(fileData);
}
function isPixelDifferent(d1, d2, off, plus){
var a = d1[off + plus];
var b = d2[off + plus];
var absDiff = Math.abs(a - b);
if(typeof a === 'undefined'){
return false;
}
if(typeof b === 'undefined'){
return false;
}
if(a === b){
return true;
} else if ( absDiff < tolerance[plus] ) {
return true;
} else {
return false;
}
}
function compareBrightness(data1, data2, offset){
var red1 = data1[offset + 0];
var green1 = data1[offset + 1];
var blue1 = data1[offset + 2];
var red2 = data2[offset + 0];
var green2 = data2[offset + 1];
var blue2 = data2[offset + 2];
var brightness1;
var brightness2;
if(red1 && green1 && blue1 && red2 && green2 && blue2){
brightness1 = (0.3*red1 + 0.59*green1 + 0.11*blue1);
brightness2 = (0.3*red2 + 0.59*green2 + 0.11*blue2);
return Math.abs(brightness1 - brightness2) < tolerance[4];
} else {
return false;
}
}
function analyseImages(img1, img2, width, height){
var hiddenCanvas = document.createElement('canvas');
var data1 = img1.data;
var data2 = img2.data;
hiddenCanvas.width = width;
hiddenCanvas.height = height;
var context = hiddenCanvas.getContext('2d');
var imgd = context.createImageData(width,height);
var pix = imgd.data;
var mismatchCount = 0;
loop(height, width, function(verticalPos, horizontalPos){
var offset = (verticalPos*width + horizontalPos) * 4;
var red = isPixelDifferent(data1, data2, offset, 0);
var green = isPixelDifferent(data1, data2, offset, 1);
var blue = isPixelDifferent(data1, data2, offset, 2);
var alpha = isPixelDifferent(data1, data2, offset, 3);
var brightness = compareBrightness(data1, data2, offset);
if(brightness && red && green && blue){
pix[offset] = data1[offset + 0];
pix[offset + 1] = data1[offset + 1];
pix[offset + 2] = data1[offset + 2];
pix[offset + 3] = data1[offset + 3];
} else {
pix[offset] = 255;
pix[offset + 1] = 0;
pix[offset + 2] = 255;
pix[offset + 3] = 255;
mismatchCount++;
}
});
context.putImageData(imgd, 0,0);
data.misMatchPercentage = (mismatchCount / (height*width) * 100).toFixed(2);
data.imageDiffFileData = hiddenCanvas.toDataURL("image/png");
}
function compare(one, two){
function onceWeHaveBoth(){
var width;
var height;
if(images.length === 2){
width = images[0].width > images[1].width ? images[0].width : images[1].width;
height = images[0].height > images[1].height ? images[0].height : images[1].height;
if( (images[0].width === images[1].width) && (images[0].height === images[1].height) ){
data.isSameDimensions = true;
} else {
data.isSameDimensions = false;
}
analyseImages(images[0], images[1], width, height);
triggerDataUpdate();
}
}
loadImageData(one, onceWeHaveBoth);
loadImageData(two, onceWeHaveBoth);
}
return {
onComplete: function( callback ){
updateCallbackArray.push(callback);
loadImageData(fileData, function(imageData, width, height){
parseImage(imageData.data, width, height);
});
},
compareTo: function(secondFileData){
return {
onComplete: function( callback ){
updateCallbackArray.push(callback);
compare(fileData, secondFileData);
}
};
}
};
};
}(this));
Loading…
Cancel
Save