some improvements
This commit is contained in:
parent
149bacbcc0
commit
ae74e5d211
5 changed files with 96 additions and 18 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -4,4 +4,4 @@ pkg/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
dist/
|
dist/
|
||||||
*.iml
|
*.iml
|
||||||
.idea
|
.idea/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
|
use image::imageops::FilterType;
|
||||||
use image::{GenericImage, GenericImageView, Pixel, Rgba, RgbaImage};
|
use image::{GenericImage, GenericImageView, Pixel, Rgba, RgbaImage};
|
||||||
use photon_rs::PhotonImage;
|
use photon_rs::PhotonImage;
|
||||||
use image::imageops::FilterType;
|
|
||||||
|
|
||||||
mod samples;
|
mod samples;
|
||||||
|
|
||||||
|
|
@ -19,9 +19,19 @@ pub fn spiegel(photon_image: PhotonImage, median_kernelsize: u32, preview: bool)
|
||||||
let i1 = RgbaImage::from_vec(width, height, raw_pixels).unwrap();
|
let i1 = RgbaImage::from_vec(width, height, raw_pixels).unwrap();
|
||||||
|
|
||||||
let i2 = if preview {
|
let i2 = if preview {
|
||||||
image::imageops::resize(&i1, u32::min(500, width >> 1), u32::min(500, height >> 1), FilterType::Nearest)
|
image::imageops::resize(
|
||||||
|
&i1,
|
||||||
|
u32::min(500, width >> 1),
|
||||||
|
u32::min(500, height >> 1),
|
||||||
|
FilterType::Nearest,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
image::imageops::resize(&i1, u32::min(500, width), u32::min(500, height), FilterType::Nearest)
|
image::imageops::resize(
|
||||||
|
&i1,
|
||||||
|
u32::min(500, width),
|
||||||
|
u32::min(500, height),
|
||||||
|
FilterType::Nearest,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
let mut i3 = imageproc::filter::median_filter(&i2, median_kernelsize, median_kernelsize);
|
let mut i3 = imageproc::filter::median_filter(&i2, median_kernelsize, median_kernelsize);
|
||||||
let i4 = if !preview {
|
let i4 = if !preview {
|
||||||
|
|
@ -80,16 +90,16 @@ fn fill(
|
||||||
let yy = y % height;
|
let yy = y % height;
|
||||||
dest.unsafe_put_pixel(x, y, sample.unsafe_get_pixel(xx, yy));
|
dest.unsafe_put_pixel(x, y, sample.unsafe_get_pixel(xx, yy));
|
||||||
src.unsafe_put_pixel(x, y, BLACK);
|
src.unsafe_put_pixel(x, y, BLACK);
|
||||||
if x > 1 {
|
if x > 1 && src.unsafe_get_pixel(x - 1, y) != BLACK {
|
||||||
points.push(Coord(x - 1, y));
|
points.push(Coord(x - 1, y));
|
||||||
}
|
}
|
||||||
if y > 1 {
|
if y > 1 && src.unsafe_get_pixel(x, y - 1) != BLACK {
|
||||||
points.push(Coord(x, y - 1));
|
points.push(Coord(x, y - 1));
|
||||||
}
|
}
|
||||||
if x < src.width() - 1 {
|
if x < src.width() - 1 && src.unsafe_get_pixel(x + 1, y) != BLACK {
|
||||||
points.push(Coord(x + 1, y));
|
points.push(Coord(x + 1, y));
|
||||||
}
|
}
|
||||||
if y < src.height() - 1 {
|
if y < src.height() - 1 && src.unsafe_get_pixel(x, y + 1) != BLACK {
|
||||||
points.push(Coord(x, y + 1));
|
points.push(Coord(x, y + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
<div id="slidecontainer" class="hide">
|
<div id="slidecontainer" class="hide">
|
||||||
<label for="slider">Brush stroke size</label><input type="range" id="slider" value="0" min="0" max="100" class="slider"/>
|
<label for="slider">Brush stroke size</label><input type="range" id="slider" value="0" min="0" max="100" class="slider"/>
|
||||||
<button id="apply">Apply</button>
|
<button id="apply">Apply</button>
|
||||||
|
<button id="reset" onclick="location.reload()">Reset</button>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
<div class="main-content">
|
<div class="main-content">
|
||||||
|
|
@ -36,6 +37,12 @@
|
||||||
<canvas id="canvas" style="visibility: hidden;"></canvas>
|
<canvas id="canvas" style="visibility: hidden;"></canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="clock-overlay">
|
||||||
|
<div class="clock">
|
||||||
|
<div class="hand hour-hand"></div>
|
||||||
|
<div class="hand minute-hand"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
function allowDrop(event) {
|
function allowDrop(event) {
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,59 @@ li:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#clock-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(255, 255, 255, 0.6);
|
||||||
|
display: none;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
#clock-overlay.visible {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clock {
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
border: 6px solid #555;
|
||||||
|
border-radius: 50%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform-origin: bottom center;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hour-hand {
|
||||||
|
width: 5px;
|
||||||
|
height: 22px;
|
||||||
|
margin-left: -2.5px;
|
||||||
|
animation: rotate 6s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.minute-hand {
|
||||||
|
width: 3px;
|
||||||
|
height: 30px;
|
||||||
|
margin-left: -1.5px;
|
||||||
|
animation: rotate 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotate {
|
||||||
|
from { transform: rotate(0deg); }
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
.slidecontainer {
|
.slidecontainer {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,14 @@ let canvas,
|
||||||
|
|
||||||
import("../../image-processor/pkg").then((module) => {
|
import("../../image-processor/pkg").then((module) => {
|
||||||
const slider = document.querySelector("#slider");
|
const slider = document.querySelector("#slider");
|
||||||
let debounceTimer;
|
let debounceTimer = null;
|
||||||
slider.oninput = (event) => {
|
slider.oninput = (event) => {
|
||||||
strokeSize = parseInt(event.target.value) / 5;
|
strokeSize = parseInt(event.target.value) / 5;
|
||||||
clearTimeout(debounceTimer);
|
clearTimeout(debounceTimer);
|
||||||
debounceTimer = setTimeout(() => filterImage(event, true), 200);
|
debounceTimer = setTimeout(() => {
|
||||||
|
debounceTimer = null;
|
||||||
|
filterImage(event, true);
|
||||||
|
}, 500);
|
||||||
};
|
};
|
||||||
slider.value = 0;
|
slider.value = 0;
|
||||||
const applyButton = document.querySelector("#apply");
|
const applyButton = document.querySelector("#apply");
|
||||||
|
|
@ -24,16 +27,21 @@ import("../../image-processor/pkg").then((module) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
function filterImage(event, preview) {
|
function filterImage(event, preview) {
|
||||||
ctx.drawImage(sourceImage, 0, 0);
|
const overlay = document.querySelector("#clock-overlay");
|
||||||
|
overlay.setAttribute("class", "visible");
|
||||||
|
setTimeout(() => {
|
||||||
|
ctx.drawImage(sourceImage, 0, 0);
|
||||||
|
|
||||||
let rust_image = module.open_image(canvas, ctx);
|
let rust_image = module.open_image(canvas, ctx);
|
||||||
const out = module.spiegel(rust_image, strokeSize, preview);
|
const out = module.spiegel(rust_image, strokeSize, preview);
|
||||||
|
|
||||||
module.putImageData(canvas, ctx, out);
|
module.putImageData(canvas, ctx, out);
|
||||||
canvas.setAttribute(
|
canvas.setAttribute(
|
||||||
"style",
|
"style",
|
||||||
`visibility:visible;position:absolute;top:${canvasTop}px`,
|
`visibility:visible;position:absolute;top:${canvasTop}px`,
|
||||||
);
|
);
|
||||||
|
overlay.setAttribute("class", "");
|
||||||
|
}, 50);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
document.querySelector("#spieghel").src = spiegel;
|
document.querySelector("#spieghel").src = spiegel;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue