Skip to content

Commit

Permalink
examples: add seam carving
Browse files Browse the repository at this point in the history
  • Loading branch information
arrufat committed Dec 6, 2024
1 parent 2087d2c commit 926b31d
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 4 deletions.
1 change: 1 addition & 0 deletions examples/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub fn build(b: *std.Build) void {
_ = buildModule(b, "colorspace", target, optimize);
_ = buildModule(b, "face_alignment", target, optimize);
_ = buildModule(b, "perlin_noise", target, optimize);
_ = buildModule(b, "seam_carving", target, optimize);

const fmt_step = b.step("fmt", "Run zig fmt");
const fmt = b.addFmt(.{
Expand Down
1 change: 1 addition & 0 deletions examples/lib/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ <h2>Examples</h2>
<li><a href="colorspace.html">Colorspace</a></li>
<li><a href="face-alignment.html">Face aligment</a></li>
<li><a href="perlin-noise.html">Perlin noise</a></li>
<li><a href="seam-carving.html">Seam carving</a></li>
</ul>
</main>
<script src="main.js"></script>
Expand Down
2 changes: 1 addition & 1 deletion examples/lib/perlin-noise.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ <h1>Perlin Noise</h1>
<label for="lacunarity-range"><code><span id="lacunarity"></span></code></label>
</div>
</fieldset>
<canvas id="canvas" width="512" height="512"></canvas>
<canvas id="canvas-perlin" width="512" height="512"></canvas>
<script src="perlin-noise.js"></script>
</div>
</body>
Expand Down
2 changes: 1 addition & 1 deletion examples/lib/perlin-noise.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
wasm_exports = obj.instance.exports;
window.wasm = obj;
console.log("wasm loaded");
const canvas = document.getElementById("canvas");
const canvas = document.getElementById("canvas-perlin");
const ctx = canvas.getContext("2d");
const rows = 512;
const cols = 512;
Expand Down
23 changes: 23 additions & 0 deletions examples/lib/seam-carving.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Seam Carving</title>
<link rel="stylesheet" href="styles.css">
<link rel="icon" href="data:image/png;base64,AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////////////////////8AAD//AAAf/wAAD/8AAA4xB/4OMQf8DgEAAA8DAAAfAQAAGAAAABgAB/wMCAf8D4cAAB+HAAAfzwAAP/8AAH////////////////////////////////////////////8=">
</head>
<body>
<h1>Seam Carving</h1>
<div id="image-container">
<fieldset class="settings-container">
<legend style="color:black;font-weight:bold;font-family:sans-serif;">Settings</legend>
<div id="buttons-container">
<button id="remove-button">Remove seam</button>
</div>
<p id="size"></p>
</fieldset>
<canvas id="canvas-seam"></canvas>
<script src="seam-carving.js"></script>
</div>
</body>
</html>
128 changes: 128 additions & 0 deletions examples/lib/seam-carving.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
(function () {
let wasmPromise = fetch("seam_carving.wasm");
var wasmExports = null;
const text_decoder = new TextDecoder();
let image = null;

const removeButton = document.getElementById("remove-button");
const canvas = document.getElementById("canvas-seam");
const ctx = canvas.getContext("2d");
canvas.ondragover = function (event) {
event.preventDefault();
};

function displayImageSize() {
let sizeElement = document.getElementById("size");
sizeElement.textContent = "size: " + canvas.width + "×" + canvas.height + " px.";
}

canvas.ondrop = function (event) {
event.preventDefault();
let img = new Image();
img.onload = function () {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
image = ctx.getImageData(0, 0, canvas.width, canvas.height);
original = new ImageData(image.width, image.height);
original.data.set(image.data);
displayImageSize();
};
img.src = URL.createObjectURL(event.dataTransfer.files[0]);
};

function displayImage(file) {
const reader = new FileReader();
reader.onload = function (e) {
const imageData = e.target.result;
const img = document.createElement("img");
img.src = imageData;
img.onload = function () {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
image = ctx.getImageData(0, 0, canvas.width, canvas.height);
original = new ImageData(image.width, image.height);
original.data.set(image.data);
displayImageSize();
};
};
reader.readAsDataURL(file);
}

const fileInput = document.createElement("input");
fileInput.type = "file";
fileInput.style.display = "none";
fileInput.addEventListener("change", function (e) {
const file = e.target.files[0];
displayImage(file);
});

canvas.addEventListener("click", function () {
fileInput.click();
});

function decodeString(ptr, len) {
if (len === 0) return "";
return text_decoder.decode(new Uint8Array(wasmExports.memory.buffer, ptr, len));
}

WebAssembly.instantiateStreaming(wasmPromise, {
js: {
log: function (ptr, len) {
const msg = decodeString(ptr, len);
console.log(msg);
},
now: function () {
return performance.now();
},
},
}).then(function (obj) {
wasmExports = obj.instance.exports;
window.wasm = obj;
console.log("wasm loaded");

let copy = null;
function seamCarve() {
if (copy) {
ctx.putImageData(copy, 0, 0);
}
const rows = image.height;
const cols = image.width;
const rgbaSize = rows * cols * 4;
const rgbaPtr = wasmExports.alloc(rgbaSize);
const seamSize = rows * 4;
const seamPtr = wasmExports.alloc(seamSize);
const extraSize = rows * cols * 10;
const extraPtr = wasmExports.alloc(extraSize);
var rgba = new Uint8ClampedArray(wasmExports.memory.buffer, rgbaPtr, rgbaSize);
var seam = new Uint32Array(wasmExports.memory.buffer, seamPtr, image.height);
image = ctx.getImageData(0, 0, canvas.width, canvas.height);
rgba.set(image.data);
wasmExports.seam_carve(rgbaPtr, rows, cols, extraPtr, extraSize, seamPtr, rows);
canvas.width = cols - 1;
image = ctx.getImageData(0, 0, canvas.width, canvas.height);
rgba = new Uint8ClampedArray(wasmExports.memory.buffer, rgbaPtr, rgbaSize - 4 * rows);

image.data.set(rgba);
ctx.putImageData(image, 0, 0);
copy = ctx.getImageData(0, 0, canvas.width, canvas.height);
displayImageSize();

for (let i = 1; i < rows; ++i) {
ctx.beginPath();
ctx.moveTo(seam[i - 1], [i - 1]);
ctx.lineTo(seam[i], [i]);
ctx.strokeStyle = "red";
ctx.lineWidth = 1;
ctx.stroke();
}

wasmExports.free(rgbaPtr, rgbaSize);
wasmExports.free(extraPtr, extraSize);
}
removeButton.addEventListener("click", () => {
seamCarve();
});
});
})();
8 changes: 6 additions & 2 deletions examples/lib/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
margin: 10px;
}

#video {
position: absolute;
}

#canvas1 {
border: 1px dashed black;
vertical-align: center;
Expand All @@ -30,8 +34,8 @@

#canvas-seam{
border: 1px solid black;
width: 640px;
height: auto;
width: auto;
height: 640px;
}

#toggle-button {
Expand Down

0 comments on commit 926b31d

Please sign in to comment.