optimize the image comparison component

This commit is contained in:
2024-12-13 23:23:03 +08:00
parent 6ea5038f5b
commit 7896541c2d
19 changed files with 1108 additions and 1476 deletions

View File

@@ -5,7 +5,7 @@ import i18n from "@/locales";
import {NSFWJS} from "nsfwjs";
import localForage from "localforage";
import {message} from "ant-design-vue";
import Module from "@/workers/imghelper.js";
import Module from "@/workers/imghelper.ts";
import Img from "@/workers/image.ts";
@@ -27,6 +27,11 @@ export const useUpscaleStore = defineStore(
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d', {willReadFrequently: true});
const imgLoaded = ref<boolean>(false);
// 处理后的图片
const processedImg = ref<HTMLImageElement>(new Image());
/**
* 图片上传前的校验
* @param file
@@ -39,32 +44,23 @@ export const useUpscaleStore = defineStore(
if (!window.FileReader) return false;
const reader = new FileReader();
reader.readAsDataURL(file); // 文件转换
return new Promise((resolve, reject) => {
reader.onload = async function () {
image.src = reader.result as string;
// 等待图片加载完成
await new Promise((innerResolve, innerReject) => {
image.onload = innerResolve;
image.onerror = innerReject;
});
// 图片 NSFW 检测
const nsfw: NSFWJS = await initNSFWJs();
const isNSFW: boolean = await predictNSFW(nsfw, image);
if (isNSFW) {
message.error(i18n.global.t('comment.illegalImage'));
fileList.value.pop();
uploading.value = false;
reject(false);
}
fileList.value.push(image.src);
// 加载图片
await loadImg(image.src);
reader.onload = async function () {
image.src = reader.result as string;
// 图片 NSFW 检测
const nsfw: NSFWJS = await initNSFWJs();
const isNSFW: boolean = await predictNSFW(nsfw, image);
if (isNSFW) {
message.error(i18n.global.t('comment.illegalImage'));
fileList.value.pop();
uploading.value = false;
resolve(true);
};
reader.onerror = reject;
});
return false;
}
fileList.value.push(image.src);
// 加载图片
await loadImg(image.src);
uploading.value = false;
return true;
};
}
/**
@@ -88,38 +84,35 @@ export const useUpscaleStore = defineStore(
* @param src
*/
async function loadImg(src: string) {
return new Promise((resolve, reject) => {
img.value.src = src;
img.value.onload = async () => {
wasmModule.value = await Module();
if (ctx) {
canvas.width = img.value.width;
canvas.height = img.value.height;
ctx.drawImage(img.value, 0, 0);
const imageData = ctx.getImageData(0, 0, img.value.width, img.value.height);
const data = new Uint8Array(imageData.data.buffer);
input.value = new Img(img.value.width, img.value.height, data);
const numPixels = input.value.width * input.value.height;
const bytesPerImage = numPixels * 4;
const sourcePtr = wasmModule.value._malloc(bytesPerImage);
const targetPtr = wasmModule.value._malloc(bytesPerImage);
wasmModule.value.HEAPU8.set(input.value.data, sourcePtr);
hasAlpha.value = wasmModule.value._check_alpha(sourcePtr, numPixels);
if (hasAlpha.value) {
inputAlpha.value = new Img(img.value.width, img.value.height);
wasmModule.value._copy_alpha_to_rgb(sourcePtr, targetPtr, numPixels);
inputAlpha.value.data.set(
wasmModule.value.HEAPU8.subarray(targetPtr, targetPtr + bytesPerImage)
);
}
wasmModule.value._free(sourcePtr);
wasmModule.value._free(targetPtr);
img.value.src = src;
img.value.onload = async () => {
wasmModule.value = await Module();
if (ctx) {
canvas.width = img.value.width;
canvas.height = img.value.height;
ctx.drawImage(img.value, 0, 0);
const imageData = ctx.getImageData(0, 0, img.value.width, img.value.height);
const data = new Uint8Array(imageData.data.buffer);
input.value = new Img(img.value.width, img.value.height, data);
const numPixels = input.value.width * input.value.height;
const bytesPerImage = numPixels * 4;
const sourcePtr = wasmModule.value._malloc(bytesPerImage);
const targetPtr = wasmModule.value._malloc(bytesPerImage);
wasmModule.value.HEAPU8.set(input.value.data, sourcePtr);
hasAlpha.value = wasmModule.value._check_alpha(sourcePtr, numPixels);
if (hasAlpha.value) {
inputAlpha.value = new Img(img.value.width, img.value.height);
wasmModule.value._copy_alpha_to_rgb(sourcePtr, targetPtr, numPixels);
inputAlpha.value.data.set(
wasmModule.value.HEAPU8.subarray(targetPtr, targetPtr + bytesPerImage)
);
}
resolve(true);
wasmModule.value._free(sourcePtr);
wasmModule.value._free(targetPtr);
imgLoaded.value = true;
}
};
};
img.value.onerror = reject;
});
}
@@ -131,6 +124,9 @@ export const useUpscaleStore = defineStore(
hasAlpha,
inputAlpha,
wasmModule,
img,
processedImg,
imgLoaded,
beforeUpload,
customUploadRequest,
removeImage,
@@ -144,7 +140,12 @@ export const useUpscaleStore = defineStore(
persist: true,
storage: localForage,
key: 'upscale',
includePaths: ['imageList', 'fileList']
includePaths: [
'imageList',
'fileList',
'img',
'processedImg',
]
}
}
)