Contour detection

by PhilQ

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.9/dat.gui.min.js"></script>
<div id="drawing"></div>

<label class="uploadfield">
	<input id="input1" type="file" accept="image/png, image/jpg, image/jpeg">
</label>

SCSS

*, ::before, ::after { margin: 0; padding: 0; box-sizing: border-box; }

body {
	background: #1f2227;
}

#drawing {
	display: block;
}

svg, canvas {
	display: block;
	margin: 50px auto 0;
	background: #1a1d21;
	// background: #fff;
	// background: transparent;
}

.uploadfield {
	position: relative;
	display: flex;
	margin: 50px auto;
	width: 300px;
	height: 80px;
	background: rgba(230, 230, 255, 0.1);
	border-radius: 4px;
	cursor: pointer;
	text-align: center;
	
	&::before {
		content: 'Pick image';
		align-self: center;
		width: 100%;
		padding: 0rem 2rem;
		color: rgba(230, 230, 255, 0.3);
		font-weight: bold;
		font-family: 'Open Sans', sans-serif;
		font-size: 1.5rem;
		text-transform: uppercase;
	}

	input {
		position: absolute;
		opacity: 0;
	}
}

JavaScript

var cnv,
	ctx,
	cnv2,
	ctx2,
	upload,
	imgData = null,
	imgOrigData = null,
	image_is_loaded = false,
	width = 10,
	height = 10,
	max_width = 800,
	max_height= 1000,
	scale_factor = 1/6,
	gui = new dat.gui.GUI(),
	settings = {
		reProcess: function () {
			if (!image_is_loaded) return;
			processImage();
		},
		brightness: 0,
		contrast: 0,
		lightnessMethod: 'luma',
		samplingMethod: '2x2',
		edgeThreshold: 0,
	}
;

const radians = (degrees) => (Math.PI / 180) * degrees;
const degrees = (radians) => radians * (180 / Math.PI);
const lightnessMethods = {
	'average': (r, g, b, a) => parseInt((r + g + b) / 3),
	'luma': (r, g, b, a) => parseInt(r*0.299 + g*0.587 + b*0.114),
	'linear luminance': (r, g, b, a) => parseInt(r*0.2126 + g*0.715 + b*0.0722),
};

function initCanvas() {
	let div = document.getElementById('drawing');
	cnv = document.createElement('canvas');
	cnv.setAttribute('id', 'canvas1');
	div.appendChild(cnv);
	ctx = cnv.getContext('2d');

	cnv.width = width;
	cnv.height = height;

	// ctx.translate(Math.floor(width / 2), Math.floor(height / 2));
	// ctx.clearRect(-Math.floor(width / 2), -Math.floor(height / 2), width, height);
	ctx.clearRect(0, 0, width, height);

	upload = document.getElementById('input1');
	upload.addEventListener('change', handleImage, false);

	/*
	let dl = document.getElementById('download');
	dl.addEventListener('click', () => {
		var link = document.createElement('a');
		link.download = 'image.png';
		link.href = cnv.toDataURL();
		link.click();
	}, false);
	*/

	/*
	window.addEventListener('keydown', (e) => {
		if (e.code == 'Space') { // e.key == ' '
		} else if (e.code == 'ArrowLeft') {
		} else if (e.code == 'ArrowRight') {
		}
	}, false);
	*/
}

function handleImage(e) {
	var reader = new FileReader();
	reader.onload = (event) => {
		var img = new Image();
		img.onload = () => {
			// Calculation new dimensions
			let ratio = img.width / img.height;
			let w = max_width;
			let h = max_height;
			if (ratio > 1) {
				h =...