JSFiddle - React, Tailwind, and code Playground
Image Comparison Tool: Open two local file system folders with image files, pair them using drag and drop, and show the differences between the pairs.
by skibulk
HTML
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">
<div id="about">
<h1>Graphic Diff (Coming Soon!)</h1>
<p>This tool highlights differences between similar graphics by compositing them with <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation">difference blending mode</a>. It enables you to select two
local folders on your computer and compare documents between them. Graphic Diff is intended to compare different versions of the same document in order to identify changes made from one version to the next. It supports the formats BMP, GIF, JPG, PDF,
PNG, SVG, TIFF, and WebP. <a href="https://github.com/lachmanski/graphic-diff">Graphic Diff is on GitHub</a> and uses <a href="https://github.com/mozilla/pdf.js">PDF.js</a>, <a href="https://github.com/photopea/UTIF.js">UTIF.js</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API">web workers</a>,
and
<a href="https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas">offscreen canvas</a>, which is an experimental technology currently enabled in Chrome. © 2019 <a href="https://github.com/lachmanski">Lachmanski</a></p>
<p><button id="continue">Continue</button></p>
</div>
<div id="app">
<div id="menu">
<label><input id="colABrowse" class="browse" type="file" webkitdirectory directory multiple/><span role="button"><i class="fas fa-folder-open"></i> 1</span></label>
<label><input id="colBBrowse" class="browse" type="file" webkitdirectory directory multiple/><span role="button"><i class="fas fa-folder-open"></i> 2</span></label>
<input type="checkbox" id="subfolders">
<label for="subfolders" id="subfoldersOff" title="Exclude...
CSS
* {
box-sizing: border-box;
margin: 0;
border: 0;
padding: 0;
}
html,
body {
width: 100%;
min-width: 320px;
height: 100%;
min-height: 320px;
font-family: arial;
font-size: 16px;
line-height: 1.5rem;
}
#about {
padding: 40px;
margin: 0 auto;
max-width: 600px;
}
h1,
h2,
h3,
p {
padding-bottom: 20px;
}
button,
[role=button] {
margin: 0;
padding: 8px 16px;
color: white;
background: #3498DB;
cursor: pointer;
font-size: 1rem;
}
#app {
display: none;
width: 100%;
height: 100%;
user-select: none;
}
#menu, #scroll {
position: absolute;
top: 0;
left: 0;
right: 0;
}
#menu {
text-align: center;
}
label {
cursor: pointer;
}
input[type=file],
input[type=checkbox] {
display: none;
}
#subfolders:not(:checked)~#subfoldersOn {
display: none;
}
#subfolders:checked~#subfoldersOff {
display: none;
}
#scroll {
margin-top: 28px;
bottom: 0;
font-size: 0;
overflow-x: scroll;
}
.set {
height: 50%;
white-space: nowrap;
}
.box {
display: inline-block;
width: 200px;
height: 100%;
background: #f5f5f5;
}
JavaScript
$("#continue").click(function(event) {
$("#about").hide();
$("#app").show();
});
/*
To-Do
// https://github.com/mozilla/pdf.js
// https://github.com/seikichi/tiff.js
Browse, Drag + Drop, Multi-Add
Remove All / Remove Folder / Remove Multi-Page Doc
Skip Images <200px w/h
PDF Pages
User Interface:
Select
Top
Up
Down
Bottom
Path
Remove / Hide
Remove / Hide Series
Cache Processed Images
Web Workers
https://www.html5rocks.com/en/tutorials/file/filesystem-sync/
https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
chrome://flags/#enable-experimental-canvas-features
https://github.com/photopea/UTIF.js
Alternative to OffscreenCanvas?:
https://github.com/nodeca/pica/blob/master/dist/pica.js
Formats: JPEG, GIF, PNG, SVG, BMP, TIFF, PDF
*/
(function($) {
"use strict";
var canvas = document.getElementById("artboard");
var context = canvasA.getContext('2d');
$('#colABrowse').on('change', function(event) {
addImages(event.target.files, colA);
});
$('#colBBrowse').on('change', function(event) {
addImages(event.target.files, colB);
});
function addImages(files, container) {
$(container).empty();
$("#colC").empty();
var queue = 0;
$(files).each(function(i, file) {
if (file.type.indexOf("image") == 0) {
var li = $("<li class='ui-state-default'></li>");
// Shift-Click Sends to Bottom
li.mousedown(function(event) {
if (event.shiftKey) {
$(this).parent().append(this);
updateResults();
event.stopPropagation();
}
});
li.appendTo(container);
var $canvas = $("<canvas width='300' height='300'>");
$canvas.appendTo(li);
var ctx = $canvas[0].getContext('2d');
queue++;
var img = new Image;
img.onload = function() {
// https://github.com/viliusle/Hermite-resize
ctx.drawImage(img, 0, 0, 300, 300);
URL.revokeObjectURL(img.src)
...