optimize and improve image enhancement

This commit is contained in:
2024-12-17 00:16:47 +08:00
parent 7896541c2d
commit b11641f62e
19 changed files with 737 additions and 805 deletions

View File

@@ -5,131 +5,120 @@ import i18n from "@/locales";
import {NSFWJS} from "nsfwjs";
import localForage from "localforage";
import {message} from "ant-design-vue";
import Module from "@/workers/imghelper.ts";
import Img from "@/workers/image.ts";
import Module from "@/workers/imghelper.ts";
export const useUpscaleStore = defineStore(
'upscale',
() => {
const image: HTMLImageElement = document.createElement('img');
const imageList = ref<string[]>([]);
const fileList = ref<string[]>([]);
const imageData = ref<string>();
const fileData = ref<string>();
const uploading = ref<boolean>(false);
// 加载图片数据
const img = ref<HTMLImageElement>(new Image());
const wasmModule = ref<any>();
const hasAlpha = ref(false);
const input = ref<Img | null>(null);
const inputAlpha = ref<Img | null>(null);
const wasmModule = ref<any>(null);
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d', {willReadFrequently: true});
const imgLoaded = ref<boolean>(false);
// 处理后的图片
const processedImg = ref<HTMLImageElement>(new Image());
const processedImg = ref<string>('');
const isDone = ref<boolean>(false);
const isProcessing = ref<boolean>(false);
const msg = ref<string>("");
const progressBar = ref<number>(0);
/**
* 图片上传前的校验
* @param file
*/
async function beforeUpload(file: any) {
if (fileList.value.length >= 5) {
async function beforeUpload(file: File) {
uploading.value = true;
const urlData = URL.createObjectURL(file);
image.src = urlData;
// 图片 NSFW 检测
const nsfw: NSFWJS = await initNSFWJs();
const isNSFW: boolean = await predictNSFW(nsfw, image);
if (isNSFW) {
message.error(i18n.global.t('comment.illegalImage'));
fileData.value = '';
uploading.value = false;
return false;
}
uploading.value = true;
if (!window.FileReader) return false;
const reader = new FileReader();
reader.readAsDataURL(file); // 文件转换
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;
return false;
}
fileList.value.push(image.src);
// 加载图片
await loadImg(image.src);
uploading.value = false;
return true;
};
fileData.value = urlData;
await loadImg(image);
uploading.value = false;
imageData.value = "";
processedImg.value = "";
isDone.value = false;
msg.value = "";
progressBar.value = 0;
return true;
}
/**
* 自定义上传图片请求
*/
async function customUploadRequest() {
imageList.value = fileList.value;
}
async function customUploadRequest(_file: any) {
/**
* 移除图片
* @param index
*/
async function removeImage(index: number) {
fileList.value.splice(index, 1);
imageList.value.splice(index, 1);
imageData.value = fileData.value;
}
/**
* 加载图片
* @param src
* @param img
*/
async function loadImg(src: string) {
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);
imgLoaded.value = true;
async function loadImg(img: HTMLImageElement) {
wasmModule.value = await Module();
if (ctx && wasmModule.value) {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, img.width, img.height);
const data = new Uint8Array(imageData.data.buffer);
input.value = new Img(img.width, img.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.width, img.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);
}
}
return {
imageList,
fileList,
uploading,
imageData,
input,
hasAlpha,
inputAlpha,
wasmModule,
img,
processedImg,
imgLoaded,
wasmModule,
isDone,
isProcessing,
msg,
progressBar,
beforeUpload,
customUploadRequest,
removeImage,
};
}
@@ -137,15 +126,10 @@ export const useUpscaleStore = defineStore(
{
// 开启数据持久化
persistedState: {
persist: true,
persist: false,
storage: localForage,
key: 'upscale',
includePaths: [
'imageList',
'fileList',
'img',
'processedImg',
]
includePaths: [],
}
}
)