Select Git revision
-
Leo McElroy authoredLeo McElroy authored
helpers.js 30.03 KiB
const pipe = (first, ...more) => more.reduce((acc,curr) => (...arguments) => curr(acc(...arguments)) , first);
const offsetHelper = (distances, offset, width, height) => {
var w = width;
var h = height;
var offset = offset;
var input = distances;
var output = new Uint8ClampedArray(4 * h * w);
for (var row = 0; row < h; ++row) {
for (var col = 0; col < w; ++col) {
if (input[(h - 1 - row) * w + col] <= offset) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
}
}
}
const imgData = new ImageData(output, w, h);
return imgData;
};
const edgeDetectHelper = imageRGBA => {
var h = imageRGBA.height;
var w = imageRGBA.width;
var input = imageRGBA.data;
var output = new Uint8ClampedArray(h * w * 4);
var i00, i0m, i0p, im0, ip0, imm, imp, ipm, ipp, row, col;
//
// find edges - interior
//
for (row = 1; row < h - 1; ++row) {
for (col = 1; col < w - 1; ++col) {
i00 =
input[(h - 1 - row) * w * 4 + col * 4 + 0] +
input[(h - 1 - row) * w * 4 + col * 4 + 1] +
input[(h - 1 - row) * w * 4 + col * 4 + 2];
i0p =
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 0] +
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 1] +
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 2];
ip0 =
input[(h - 2 - row) * w * 4 + col * 4 + 0] +
input[(h - 2 - row) * w * 4 + col * 4 + 1] +
input[(h - 2 - row) * w * 4 + col * 4 + 2];
ipp =
input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 0] +
input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 1] +
input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 2];
i0m =
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 0] +
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 1] +
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 2];
im0 =
input[(h - row) * w * 4 + col * 4 + 0] +
input[(h - row) * w * 4 + col * 4 + 1] +
input[(h - row) * w * 4 + col * 4 + 2];
imm =
input[(h - row) * w * 4 + (col - 1) * 4 + 0] +
input[(h - row) * w * 4 + (col - 1) * 4 + 1] +
input[(h - row) * w * 4 + (col - 1) * 4 + 2];
imp =
input[(h - row) * w * 4 + (col + 1) * 4 + 0] +
input[(h - row) * w * 4 + (col + 1) * 4 + 1] +
input[(h - row) * w * 4 + (col + 1) * 4 + 2];
ipm =
input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 0] +
input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 1] +
input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 2];
if (
i00 != i0p ||
i00 != ip0 ||
i00 != ipp ||
i00 != i0m ||
i00 != im0 ||
i00 != imm ||
i00 != imp ||
i00 != ipm
) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else if (i00 == 0) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
}
}
}
//
// left and right edges
//
for (row = 1; row < h - 1; ++row) {
col = w - 1;
i00 =
input[(h - 1 - row) * w * 4 + col * 4 + 0] +
input[(h - 1 - row) * w * 4 + col * 4 + 1] +
input[(h - 1 - row) * w * 4 + col * 4 + 2];
i0m =
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 0] +
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 1] +
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 2];
imm =
input[(h - row) * w * 4 + (col - 1) * 4 + 0] +
input[(h - row) * w * 4 + (col - 1) * 4 + 1] +
input[(h - row) * w * 4 + (col - 1) * 4 + 2];
ipm =
input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 0] +
input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 1] +
input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 2];
im0 =
input[(h - row) * w * 4 + col * 4 + 0] +
input[(h - row) * w * 4 + col * 4 + 1] +
input[(h - row) * w * 4 + col * 4 + 2];
ip0 =
input[(h - 2 - row) * w * 4 + col * 4 + 0] +
input[(h - 2 - row) * w * 4 + col * 4 + 1] +
input[(h - 2 - row) * w * 4 + col * 4 + 2];
if (i00 != i0m || i00 != ip0 || i00 != ipm || i00 != im0 || i00 != imm) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else if (i00 == 0) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
}
col = 0;
i00 =
input[(h - 1 - row) * w * 4 + col * 4 + 0] +
input[(h - 1 - row) * w * 4 + col * 4 + 1] +
input[(h - 1 - row) * w * 4 + col * 4 + 2];
i0p =
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 0] +
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 1] +
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 2];
imp =
input[(h - row) * w * 4 + (col + 1) * 4 + 0] +
input[(h - row) * w * 4 + (col + 1) * 4 + 1] +
input[(h - row) * w * 4 + (col + 1) * 4 + 2];
ipp =
input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 0] +
input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 1] +
input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 2];
im0 =
input[(h - row) * w * 4 + col * 4 + 0] +
input[(h - row) * w * 4 + col * 4 + 1] +
input[(h - row) * w * 4 + col * 4 + 2];
ip0 =
input[(h - 2 - row) * w * 4 + col * 4 + 0] +
input[(h - 2 - row) * w * 4 + col * 4 + 1] +
input[(h - 2 - row) * w * 4 + col * 4 + 2];
if (i00 != i0p || i00 != ip0 || i00 != ipp || i00 != im0 || i00 != imp) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else if (i00 == 0) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
}
}
//
// top and bottom edges
//
for (col = 1; col < w - 1; ++col) {
row = h - 1;
i00 =
input[(h - 1 - row) * w * 4 + col * 4 + 0] +
input[(h - 1 - row) * w * 4 + col * 4 + 1] +
input[(h - 1 - row) * w * 4 + col * 4 + 2];
i0m =
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 0] +
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 1] +
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 2];
i0p =
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 0] +
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 1] +
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 2];
imm =
input[(h - row) * w * 4 + (col - 1) * 4 + 0] +
input[(h - row) * w * 4 + (col - 1) * 4 + 1] +
input[(h - row) * w * 4 + (col - 1) * 4 + 2];
im0 =
input[(h - row) * w * 4 + col * 4 + 0] +
input[(h - row) * w * 4 + col * 4 + 1] +
input[(h - row) * w * 4 + col * 4 + 2];
imp =
input[(h - row) * w * 4 + (col + 1) * 4 + 0] +
input[(h - row) * w * 4 + (col + 1) * 4 + 1] +
input[(h - row) * w * 4 + (col + 1) * 4 + 2];
if (i00 != i0m || i00 != i0p || i00 != imm || i00 != im0 || i00 != imp) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else if (i00 == 0) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
}
row = 0;
i00 =
input[(h - 1 - row) * w * 4 + col * 4 + 0] +
input[(h - 1 - row) * w * 4 + col * 4 + 1] +
input[(h - 1 - row) * w * 4 + col * 4 + 2];
i0m =
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 0] +
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 1] +
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 2];
i0p =
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 0] +
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 1] +
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 2];
ipm =
input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 0] +
input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 1] +
input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 2];
ip0 =
input[(h - 2 - row) * w * 4 + col * 4 + 0] +
input[(h - 2 - row) * w * 4 + col * 4 + 1] +
input[(h - 2 - row) * w * 4 + col * 4 + 2];
ipp =
input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 0] +
input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 1] +
input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 2];
if (i00 != i0m || i00 != i0p || i00 != ipm || i00 != ip0 || i00 != ipp) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else if (i00 == 0) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
}
}
//
// corners
//
row = 0;
col = 0;
i00 =
input[(h - 1 - row) * w * 4 + col * 4 + 0] +
input[(h - 1 - row) * w * 4 + col * 4 + 1] +
input[(h - 1 - row) * w * 4 + col * 4 + 2];
i0p =
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 0] +
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 1] +
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 2];
ip0 =
input[(h - 2 - row) * w * 4 + col * 4 + 0] +
input[(h - 2 - row) * w * 4 + col * 4 + 1] +
input[(h - 2 - row) * w * 4 + col * 4 + 2];
ipp =
input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 0] +
input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 1] +
input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 2];
if (i00 != i0p || i00 != ip0 || i00 != ipp) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else if (i00 == 0) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
}
row = 0;
col = w - 1;
i00 =
input[(h - 1 - row) * w * 4 + col * 4 + 0] +
input[(h - 1 - row) * w * 4 + col * 4 + 1] +
input[(h - 1 - row) * w * 4 + col * 4 + 2];
i0m =
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 0] +
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 1] +
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 2];
ip0 =
input[(h - 2 - row) * w * 4 + col * 4 + 0] +
input[(h - 2 - row) * w * 4 + col * 4 + 1] +
input[(h - 2 - row) * w * 4 + col * 4 + 2];
ipm =
input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 0] +
input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 1] +
input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 2];
if (i00 != i0m || i00 != ip0 || i00 != ipm) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else if (i00 == 0) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
}
row = h - 1;
col = 0;
i00 =
input[(h - 1 - row) * w * 4 + col * 4 + 0] +
input[(h - 1 - row) * w * 4 + col * 4 + 1] +
input[(h - 1 - row) * w * 4 + col * 4 + 2];
i0p =
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 0] +
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 1] +
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 2];
im0 =
input[(h - row) * w * 4 + col * 4 + 0] +
input[(h - row) * w * 4 + col * 4 + 1] +
input[(h - row) * w * 4 + col * 4 + 2];
imp =
input[(h - row) * w * 4 + (col + 1) * 4 + 0] +
input[(h - row) * w * 4 + (col + 1) * 4 + 1] +
input[(h - row) * w * 4 + (col + 1) * 4 + 2];
if (i00 != i0p || i00 != im0 || i00 != imp) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else if (i00 == 0) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
}
row = h - 1;
col = w - 1;
i00 =
input[(h - 1 - row) * w * 4 + col * 4 + 0] +
input[(h - 1 - row) * w * 4 + col * 4 + 1] +
input[(h - 1 - row) * w * 4 + col * 4 + 2];
i0m =
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 0] +
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 1] +
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 2];
im0 =
input[(h - row) * w * 4 + col * 4 + 0] +
input[(h - row) * w * 4 + col * 4 + 1] +
input[(h - row) * w * 4 + col * 4 + 2];
imm =
input[(h - row) * w * 4 + (col - 1) * 4 + 0] +
input[(h - row) * w * 4 + (col - 1) * 4 + 1] +
input[(h - row) * w * 4 + (col - 1) * 4 + 2];
if (i00 != i0m || i00 != im0 || i00 != imm) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else if (i00 == 0) {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
} else {
output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
}
const imgData = new ImageData(output, w, h);
return imgData;
};
const orientEdgesHelper = imageRGBA => {
var h = imageRGBA.height;
var w = imageRGBA.width;
var input = imageRGBA.data;
var output = new Uint8ClampedArray(h * w * 4);
var row, col;
var boundary = 0;
var interior = 1;
var exterior = 2;
var alpha = 3;
var northsouth = 0;
var north = 128;
var south = 64;
var eastwest = 1;
var east = 128;
var west = 64;
var startstop = 2;
var start = 128;
var stop = 64;
//
// orient body states
//
for (row = 1; row < h - 1; ++row) {
for (col = 1; col < w - 1; ++col) {
output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
if (input[(h - 1 - row) * w * 4 + col * 4 + boundary] != 0) {
if (
input[(h - 1 - (row + 1)) * w * 4 + col * 4 + boundary] != 0 &&
(input[(h - 1 - row) * w * 4 + (col + 1) * 4 + interior] != 0 ||
input[(h - 1 - (row + 1)) * w * 4 + (col + 1) * 4 + interior] !=
0)
)
output[(h - 1 - row) * w * 4 + col * 4 + northsouth] |= north;
if (
input[(h - 1 - (row - 1)) * w * 4 + col * 4 + boundary] != 0 &&
(input[(h - 1 - row) * w * 4 + (col - 1) * 4 + interior] != 0 ||
input[(h - 1 - (row - 1)) * w * 4 + (col - 1) * 4 + interior] !=
0)
)
output[(h - 1 - row) * w * 4 + col * 4 + northsouth] |= south;
if (
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + boundary] != 0 &&
(input[(h - 1 - (row - 1)) * w * 4 + col * 4 + interior] != 0 ||
input[(h - 1 - (row - 1)) * w * 4 + (col + 1) * 4 + interior] !=
0)
)
output[(h - 1 - row) * w * 4 + col * 4 + eastwest] |= east;
if (
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + boundary] != 0 &&
(input[(h - 1 - (row + 1)) * w * 4 + col * 4 + interior] != 0 ||
input[(h - 1 - (row + 1)) * w * 4 + (col - 1) * 4 + interior] !=
0)
)
output[(h - 1 - row) * w * 4 + col * 4 + eastwest] |= west;
}
}
}
//
// orient edge states
//
for (col = 1; col < w - 1; ++col) {
row = 0;
output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
if (input[(h - 1 - row) * w * 4 + col * 4 + boundary] != 0) {
if (
input[(h - 1 - (row + 1)) * w * 4 + col * 4 + boundary] != 0 &&
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + interior] != 0
) {
output[(h - 1 - row) * w * 4 + col * 4 + northsouth] |= north;
output[(h - 1 - row) * w * 4 + col * 4 + startstop] |= start;
}
if (input[(h - 1 - row) * w * 4 + (col - 1) * 4 + interior] != 0)
output[(h - 1 - row) * w * 4 + col * 4 + startstop] |= stop;
}
row = h - 1;
output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
if (input[(h - 1 - row) * w * 4 + col * 4 + boundary] != 0) {
if (input[(h - 1 - row) * w * 4 + (col + 1) * 4 + interior] != 0)
output[(h - 1 - row) * w * 4 + col * 4 + startstop] |= stop;
if (
input[(h - 1 - (row - 1)) * w * 4 + col * 4 + boundary] != 0 &&
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + interior] != 0
) {
output[(h - 1 - row) * w * 4 + col * 4 + northsouth] |= south;
output[(h - 1 - row) * w * 4 + col * 4 + startstop] |= start;
}
}
}
for (row = 1; row < h - 1; ++row) {
col = 0;
output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
if (input[(h - 1 - row) * w * 4 + col * 4 + boundary] != 0) {
if (
input[(h - 1 - row) * w * 4 + (col + 1) * 4 + boundary] != 0 &&
input[(h - 1 - (row - 1)) * w * 4 + col * 4 + interior] != 0
) {
output[(h - 1 - row) * w * 4 + col * 4 + eastwest] |= east;
output[(h - 1 - row) * w * 4 + col * 4 + startstop] |= start;
}
if (input[(h - 1 - (row + 1)) * w * 4 + col * 4 + interior] != 0)
output[(h - 1 - row) * w * 4 + col * 4 + startstop] |= stop;
}
col = w - 1;
output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
if (input[(h - 1 - row) * w * 4 + col * 4 + boundary] != 0) {
if (input[(h - 1 - (row - 1)) * w * 4 + col * 4 + interior] != 0)
output[(h - 1 - row) * w * 4 + col * 4 + startstop] |= stop;
if (
input[(h - 1 - row) * w * 4 + (col - 1) * 4 + boundary] != 0 &&
input[(h - 1 - (row + 1)) * w * 4 + col * 4 + interior] != 0
) {
output[(h - 1 - row) * w * 4 + col * 4 + eastwest] |= west;
output[(h - 1 - row) * w * 4 + col * 4 + startstop] |= start;
}
}
}
//
// orient corner states (todo)
//
row = 0;
col = 0;
output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
row = h - 1;
col = 0;
output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
row = 0;
col = w - 1;
output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
row = h - 1;
col = w - 1;
output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
// var display = new Uint8ClampedArray(h*w*4)
// var r,g,b,i
// for (row = 0; row < h; ++row) {
// for (col = 0; col < w; ++col) {
// r = output[(h-1-row)*w*4+col*4+0]
// g = output[(h-1-row)*w*4+col*4+1]
// b = output[(h-1-row)*w*4+col*4+2]
// i = r+g+b
// if (i != 0) {
// display[(h-1-row)*w*4+col*4+0] = output[(h-1-row)*w*4+col*4+0]
// display[(h-1-row)*w*4+col*4+1] = output[(h-1-row)*w*4+col*4+1]
// display[(h-1-row)*w*4+col*4+2] = output[(h-1-row)*w*4+col*4+2]
// display[(h-1-row)*w*4+col*4+3] = output[(h-1-row)*w*4+col*4+3]
// }
// else {
// display[(h-1-row)*w*4+col*4+0] = 255
// display[(h-1-row)*w*4+col*4+1] = 255
// display[(h-1-row)*w*4+col*4+2] = 255
// display[(h-1-row)*w*4+col*4+3] = 255
// }
// }
// }
const imgData = new ImageData(output, w, h);
return imgData;
};
const vectorizeHelper = (imageRGBA, vectorFit = 1, sort = true) => {
var h = imageRGBA.height;
var w = imageRGBA.width;
var input = imageRGBA.data;
var northsouth = 0;
var north = 128;
var south = 64;
var eastwest = 1;
var east = 128;
var west = 64;
var startstop = 2;
var start = 128;
var stop = 64;
var path = [];
//
// edge follower
//
function follow_edges(row, col) {
if (
input[(h - 1 - row) * w * 4 + col * 4 + northsouth] != 0 ||
input[(h - 1 - row) * w * 4 + col * 4 + eastwest] != 0
) {
path[path.length] = [[col, row]];
while (1) {
if (
input[(h - 1 - row) * w * 4 + col * 4 + northsouth] & north
) {
input[(h - 1 - row) * w * 4 + col * 4 + northsouth] =
input[(h - 1 - row) * w * 4 + col * 4 + northsouth] &
~north;
row += 1;
path[path.length - 1][path[path.length - 1].length] = [
col,
row
];
} else if (
input[(h - 1 - row) * w * 4 + col * 4 + northsouth] & south
) {
input[(h - 1 - row) * w * 4 + col * 4 + northsouth] =
input[(h - 1 - row) * w * 4 + col * 4 + northsouth] &
~south;
row -= 1;
path[path.length - 1][path[path.length - 1].length] = [
col,
row
];
} else if (
input[(h - 1 - row) * w * 4 + col * 4 + eastwest] & east
) {
input[(h - 1 - row) * w * 4 + col * 4 + eastwest] =
input[(h - 1 - row) * w * 4 + col * 4 + eastwest] & ~east;
col += 1;
path[path.length - 1][path[path.length - 1].length] = [
col,
row
];
} else if (
input[(h - 1 - row) * w * 4 + col * 4 + eastwest] & west
) {
input[(h - 1 - row) * w * 4 + col * 4 + eastwest] =
input[(h - 1 - row) * w * 4 + col * 4 + eastwest] & ~west;
col -= 1;
path[path.length - 1][path[path.length - 1].length] = [
col,
row
];
} else break;
}
}
}
//
// follow boundary starts
//
for (var row = 1; row < h - 1; ++row) {
col = 0;
follow_edges(row, col);
col = w - 1;
follow_edges(row, col);
}
for (var col = 1; col < w - 1; ++col) {
row = 0;
follow_edges(row, col);
row = h - 1;
follow_edges(row, col);
}
//
// follow interior paths
//
for (var row = 1; row < h - 1; ++row) {
for (var col = 1; col < w - 1; ++col) {
follow_edges(row, col);
}
}
//
// vectorize path
//
var error = vectorFit;
var vecpath = [];
for (var seg = 0; seg < path.length; ++seg) {
var x0 = path[seg][0][0];
var y0 = path[seg][0][1];
vecpath[vecpath.length] = [[x0, y0]];
var xsum = x0;
var ysum = y0;
var sum = 1;
for (var pt = 1; pt < path[seg].length; ++pt) {
var xold = x;
var yold = y;
var x = path[seg][pt][0];
var y = path[seg][pt][1];
if (sum == 1) {
xsum += x;
ysum += y;
sum += 1;
} else {
var xmean = xsum / sum;
var ymean = ysum / sum;
var dx = xmean - x0;
var dy = ymean - y0;
var d = Math.sqrt(dx * dx + dy * dy);
var nx = dy / d;
var ny = -dx / d;
var l = Math.abs(nx * (x - x0) + ny * (y - y0));
if (l < error) {
xsum += x;
ysum += y;
sum += 1;
} else {
vecpath[vecpath.length - 1][
vecpath[vecpath.length - 1].length
] = [xold, yold];
x0 = xold;
y0 = yold;
xsum = xold;
ysum = yold;
sum = 1;
}
}
if (pt == path[seg].length - 1) {
vecpath[vecpath.length - 1][
vecpath[vecpath.length - 1].length
] = [x, y];
}
}
}
//
// sort path
//
if (vecpath.length > 1 && sort == true) {
var dmin = w * w + h * h;
var segmin = null;
for (var seg = 0; seg < vecpath.length; ++seg) {
var x = vecpath[seg][0][0];
var y = vecpath[seg][0][0];
var d = x * x + y * y;
if (d < dmin) {
dmin = d;
segmin = seg;
}
}
if (segmin != null) {
var sortpath = [vecpath[segmin]];
vecpath.splice(segmin, 1);
}
while (vecpath.length > 0) {
var dmin = w * w + h * h;
var x0 =
sortpath[sortpath.length - 1][
sortpath[sortpath.length - 1].length - 1
][0];
var y0 =
sortpath[sortpath.length - 1][
sortpath[sortpath.length - 1].length - 1
][1];
segmin = null;
for (var seg = 0; seg < vecpath.length; ++seg) {
var x = vecpath[seg][0][0];
var y = vecpath[seg][0][1];
var d = (x - x0) * (x - x0) + (y - y0) * (y - y0);
if (d < dmin) {
dmin = d;
segmin = seg;
}
}
if (segmin != null) {
sortpath[sortpath.length] = vecpath[segmin];
vecpath.splice(segmin, 1);
}
}
} else if (
(vecpath.length > 1 && sort == false) ||
vecpath.length == 1
)
sortpath = vecpath;
else sortpath = [];
return sortpath;
};
const test = () => console.log("import is working");