feat(ImageShow.svelte): add opencv.js support
BREAKING CHANGE:
This commit is contained in:
parent
8cf90b32a3
commit
84e1e312ab
|
|
@ -9,5 +9,6 @@
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<script type="module" src="/src/main.js"></script>
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
<script src="/src/opencv.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite --host 0.0.0.0",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,165 @@
|
||||||
|
<script>
|
||||||
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
|
import { fabric } from "fabric";
|
||||||
|
|
||||||
|
import Navbar from "./Navbar.svelte";
|
||||||
|
import { ImageProcessing } from "./utils";
|
||||||
|
|
||||||
|
export let url = "test.jpg";
|
||||||
|
|
||||||
|
let img_process = new ImageProcessing();
|
||||||
|
|
||||||
|
let canvas_dom;
|
||||||
|
let canvas;
|
||||||
|
let image;
|
||||||
|
let window_width;
|
||||||
|
let window_height;
|
||||||
|
let canvas_width = 0;
|
||||||
|
let canvas_height = 0;
|
||||||
|
let active;
|
||||||
|
|
||||||
|
function LabelItem(label, items) {
|
||||||
|
this.label = label;
|
||||||
|
|
||||||
|
this.items = items.map((e) => {
|
||||||
|
return new OperationItem(e[0], e[1], e[2]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function OperationItem(name, icon, handler = null) {
|
||||||
|
this.id = uuidv4();
|
||||||
|
this.name = name;
|
||||||
|
this.icon = icon;
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Menu = [
|
||||||
|
new LabelItem("采集操作", [
|
||||||
|
["确认并返回", "mdi mdi-checkbox-marked-circle-outline"],
|
||||||
|
["重新采集", "mdi mdi-reply-outline"],
|
||||||
|
["取消", "mdi mdi-alpha-x-circle-outline"],
|
||||||
|
]),
|
||||||
|
new LabelItem("图像操作", [
|
||||||
|
[
|
||||||
|
"向左旋转",
|
||||||
|
"mdi mdi-file-rotate-left-outline",
|
||||||
|
() => {
|
||||||
|
image.rotate(90);
|
||||||
|
},
|
||||||
|
],
|
||||||
|
["向右旋转", "mdi mdi-file-rotate-right-outline"],
|
||||||
|
["文本加强", "mdi mdi-image-filter-center-focus-strong"],
|
||||||
|
["裁剪", "mdi mdi-crop"],
|
||||||
|
["滚轮缩放", "mdi mdi-loupe"],
|
||||||
|
]),
|
||||||
|
new LabelItem("文件操作", [
|
||||||
|
["保存到本地", "mdi mdi-content-save-outline"],
|
||||||
|
["打印图片", "mdi mdi-printer-outline"],
|
||||||
|
]),
|
||||||
|
];
|
||||||
|
|
||||||
|
$: {
|
||||||
|
canvas_height = window_height - 64;
|
||||||
|
canvas_width = window_width * 0.8125;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resize() {
|
||||||
|
setTimeout(() => {
|
||||||
|
let scale = Math.min(
|
||||||
|
canvas_height / image.height,
|
||||||
|
canvas_width / image.width
|
||||||
|
);
|
||||||
|
|
||||||
|
canvas.setWidth(image.width * scale);
|
||||||
|
canvas.setHeight(image.height * scale);
|
||||||
|
|
||||||
|
image.scale(scale);
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function init_canvas() {
|
||||||
|
let img = new Image();
|
||||||
|
img.src = url;
|
||||||
|
img.onload = async function () {
|
||||||
|
setTimeout(() => {
|
||||||
|
canvas = new fabric.StaticCanvas(canvas_dom);
|
||||||
|
setTimeout(() => {
|
||||||
|
image = new fabric.Image(img);
|
||||||
|
let scale = Math.min(
|
||||||
|
canvas_height / image.height,
|
||||||
|
canvas_width / image.width
|
||||||
|
);
|
||||||
|
|
||||||
|
image.scale(scale);
|
||||||
|
canvas.setWidth(image.width * scale);
|
||||||
|
canvas.setHeight(image.height * scale);
|
||||||
|
canvas.add(image);
|
||||||
|
console.log(image);
|
||||||
|
}, 50);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
canvas_height = window_height - 64;
|
||||||
|
canvas_width = (window_width * 13) / 16;
|
||||||
|
init_canvas();
|
||||||
|
console.log(window)
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:window
|
||||||
|
bind:innerHeight={window_height}
|
||||||
|
bind:innerWidth={window_width}
|
||||||
|
on:resize={resize}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="disable-selection">
|
||||||
|
<Navbar />
|
||||||
|
<div class="columns is-gapless">
|
||||||
|
<div class="column is-2" style="margin: 10px">
|
||||||
|
<aside class="menu">
|
||||||
|
{#each Menu as m}
|
||||||
|
<p class="menu-label" style="font-size: 0.9em">{m.label}</p>
|
||||||
|
<ul class="menu-list">
|
||||||
|
{#each m.items as item}
|
||||||
|
<!-- svelte-ignore a11y-missing-attribute -->
|
||||||
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
class:is-active={active === item.id}
|
||||||
|
on:click={() => {
|
||||||
|
active = item.id;
|
||||||
|
if (item.handler) {
|
||||||
|
item.handler();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
><span class="icon-text">
|
||||||
|
<span class="icon">
|
||||||
|
<i class={item.icon} />
|
||||||
|
</span><span> {item.name}</span></span
|
||||||
|
>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
{/each}
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
<div class="column" style="text-align:center">
|
||||||
|
<canvas
|
||||||
|
bind:this={canvas_dom}
|
||||||
|
width={canvas_width}
|
||||||
|
height={canvas_height}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
canvas {
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -2,11 +2,11 @@
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
import { fabric } from "fabric";
|
|
||||||
|
|
||||||
import Navbar from "./Navbar.svelte";
|
import Navbar from "./Navbar.svelte";
|
||||||
import { ImageProcessing } from "./utils";
|
import { ImageProcessing } from "./utils";
|
||||||
|
|
||||||
|
const cv = window.cv;
|
||||||
|
|
||||||
export let url = "test.jpg";
|
export let url = "test.jpg";
|
||||||
|
|
||||||
let img_process = new ImageProcessing();
|
let img_process = new ImageProcessing();
|
||||||
|
|
@ -42,7 +42,13 @@
|
||||||
["取消", "mdi mdi-alpha-x-circle-outline"],
|
["取消", "mdi mdi-alpha-x-circle-outline"],
|
||||||
]),
|
]),
|
||||||
new LabelItem("图像操作", [
|
new LabelItem("图像操作", [
|
||||||
["向左旋转", "mdi mdi-file-rotate-left-outline"],
|
[
|
||||||
|
"向左旋转",
|
||||||
|
"mdi mdi-file-rotate-left-outline",
|
||||||
|
() => {
|
||||||
|
image.rotate(90);
|
||||||
|
},
|
||||||
|
],
|
||||||
["向右旋转", "mdi mdi-file-rotate-right-outline"],
|
["向右旋转", "mdi mdi-file-rotate-right-outline"],
|
||||||
["文本加强", "mdi mdi-image-filter-center-focus-strong"],
|
["文本加强", "mdi mdi-image-filter-center-focus-strong"],
|
||||||
["裁剪", "mdi mdi-crop"],
|
["裁剪", "mdi mdi-crop"],
|
||||||
|
|
@ -54,48 +60,55 @@
|
||||||
]),
|
]),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$: {
|
||||||
|
canvas_height = window_height - 64;
|
||||||
|
canvas_width = window_width * 0.8125;
|
||||||
|
}
|
||||||
|
|
||||||
function resize() {
|
function resize() {
|
||||||
setTimeout(() => {
|
/*setTimeout(() => {
|
||||||
console.log("test");
|
|
||||||
canvas_height = window_height - 64;
|
|
||||||
canvas_width = (window_width * 13) / 16;
|
|
||||||
let scale = Math.min(
|
let scale = Math.min(
|
||||||
canvas_height / image.height,
|
canvas_height / image.height,
|
||||||
canvas_width / image.width
|
canvas_width / image.width
|
||||||
);
|
);
|
||||||
|
|
||||||
canvas.setWidth(image.width * scale);
|
canvas.setWidth(image.width * scale);
|
||||||
canvas.setHeight(image.height * scale);
|
canvas.setHeight(image.height * scale);
|
||||||
|
|
||||||
image.scale(scale);
|
image.scale(scale);
|
||||||
/*fabric.Image.fromURL("test.jpg", function (oImg) {
|
}, 50);*/
|
||||||
let scale = Math.min(
|
|
||||||
canvas_height / oImg.height,
|
|
||||||
canvas_width / oImg.width
|
|
||||||
);
|
|
||||||
oImg.scale(scale);
|
|
||||||
oImg.set("selectable", false);
|
|
||||||
canvas.add(oImg);
|
|
||||||
});*/
|
|
||||||
}, 50);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function init_canvas() {
|
async function init_canvas() {
|
||||||
let img = new Image();
|
let img = new Image();
|
||||||
img.src = await img_process.init_image(url);
|
img.src = url;
|
||||||
img.onload = function () {
|
img.onload = function () {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
canvas = new fabric.StaticCanvas(canvas_dom);
|
setTimeout(() => {
|
||||||
image = new fabric.Image(img);
|
image = cv.imread(img);
|
||||||
let scale = Math.min(
|
let scale = Math.min(
|
||||||
canvas_height / image.height,
|
canvas_height / image.rows,
|
||||||
canvas_width / image.width
|
canvas_width / image.cols
|
||||||
);
|
);
|
||||||
image.scale(scale);
|
let dst = new cv.Mat();
|
||||||
canvas.setWidth(image.width * scale);
|
let dsize = new cv.Size(scale * image.cols, scale * image.rows);
|
||||||
canvas.setHeight(image.height * scale);
|
|
||||||
|
|
||||||
canvas.add(image);
|
cv.resize(image, dst, dsize, 0, 0, cv.INTER_AREA);
|
||||||
console.log(image.getSrc().toString());
|
cv.imshow("canvas", dst);
|
||||||
}, 50);
|
console.log(cv.im(".jpg", image).toString("base64"));
|
||||||
|
/* image = new fabric.Image(img);
|
||||||
|
let scale = Math.min(
|
||||||
|
canvas_height / image.height,
|
||||||
|
canvas_width / image.width
|
||||||
|
);
|
||||||
|
|
||||||
|
image.scale(scale);
|
||||||
|
canvas.setWidth(image.width * scale);
|
||||||
|
canvas.setHeight(image.height * scale);
|
||||||
|
canvas.add(image);
|
||||||
|
console.log(image);*/
|
||||||
|
}, 50);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,6 +116,7 @@
|
||||||
canvas_height = window_height - 64;
|
canvas_height = window_height - 64;
|
||||||
canvas_width = (window_width * 13) / 16;
|
canvas_width = (window_width * 13) / 16;
|
||||||
init_canvas();
|
init_canvas();
|
||||||
|
console.log(window);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -128,6 +142,9 @@
|
||||||
class:is-active={active === item.id}
|
class:is-active={active === item.id}
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
active = item.id;
|
active = item.id;
|
||||||
|
if (item.handler) {
|
||||||
|
item.handler();
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
><span class="icon-text">
|
><span class="icon-text">
|
||||||
<span class="icon">
|
<span class="icon">
|
||||||
|
|
@ -142,11 +159,7 @@
|
||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
<div class="column" style="text-align:center">
|
<div class="column" style="text-align:center">
|
||||||
<canvas
|
<canvas bind:this={canvas_dom} id="canvas" />
|
||||||
bind:this={canvas_dom}
|
|
||||||
width={canvas_width}
|
|
||||||
height={canvas_height}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import procedure from "../assets/Procedure.json";
|
import procedure from "../assets/Procedure.json";
|
||||||
import jimp from "jimp/es";
|
|
||||||
|
const jimp = window.jimp;
|
||||||
|
|
||||||
export function Operation(step) {
|
export function Operation(step) {
|
||||||
this.step = step;
|
this.step = step;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ import "@mdi/font/css/materialdesignicons.min.css";
|
||||||
|
|
||||||
import "bulma";
|
import "bulma";
|
||||||
import "./assets/DisableSelection.css"
|
import "./assets/DisableSelection.css"
|
||||||
|
import "./jimp"
|
||||||
|
|
||||||
import App from "./App.svelte";
|
import App from "./App.svelte";
|
||||||
|
|
||||||
const app = new App({
|
const app = new App({
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue