From 7896541c2dd3abeb079b26d782820fb2b4a7a760 Mon Sep 17 00:00:00 2001 From: landaiqing Date: Fri, 13 Dec 2024 23:23:03 +0800 Subject: [PATCH] :wheelchair: optimize the image comparison component --- auto-import.d.ts | 302 ++++++++++ components.d.ts | 5 +- index.html | 2 +- package.json | 6 +- .../AnimatedSvgIllustration.vue | 459 --------------- .../AnimatedSvgIllustration/index.scss | 24 - src/components/EffectsCard/EffectsCard.vue | 373 ------------ .../VueCompareImage/VueCompareImage.vue | 2 +- src/store/modules/upscaleStore.ts | 115 ++-- src/utils/upscale/handler.ts | 270 --------- src/views/Photograph/AllPhoto/AllPhoto.vue | 13 +- src/views/Upscale/CompareImage.vue | 532 ++++++++++++++++++ .../{CompareResult.vue => ProcessResult.vue} | 0 src/views/Upscale/Upscale.vue | 205 +++---- src/views/Upscale/index.scss | 91 --- src/workers/imghelper.c | 2 +- src/workers/{imghelper.js => imghelper.ts} | 158 +++--- src/workers/upscale.worker.ts | 4 +- vite.config.ts | 21 +- 19 files changed, 1108 insertions(+), 1476 deletions(-) delete mode 100644 src/components/AnimatedSvgIllustration/AnimatedSvgIllustration.vue delete mode 100644 src/components/AnimatedSvgIllustration/index.scss delete mode 100644 src/components/EffectsCard/EffectsCard.vue delete mode 100644 src/utils/upscale/handler.ts create mode 100644 src/views/Upscale/CompareImage.vue rename src/views/Upscale/{CompareResult.vue => ProcessResult.vue} (100%) delete mode 100644 src/views/Upscale/index.scss rename src/workers/{imghelper.js => imghelper.ts} (81%) diff --git a/auto-import.d.ts b/auto-import.d.ts index 2ee14ff..e8673cf 100644 --- a/auto-import.d.ts +++ b/auto-import.d.ts @@ -307,3 +307,305 @@ declare global { export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue' import('vue') } + +// for vue template auto import +import { UnwrapRef } from 'vue' +declare module 'vue' { + interface GlobalComponents {} + interface ComponentCustomProperties { + readonly EffectScope: UnwrapRef + readonly acceptHMRUpdate: UnwrapRef + readonly asyncComputed: UnwrapRef + readonly autoResetRef: UnwrapRef + readonly computed: UnwrapRef + readonly computedAsync: UnwrapRef + readonly computedEager: UnwrapRef + readonly computedInject: UnwrapRef + readonly computedWithControl: UnwrapRef + readonly controlledComputed: UnwrapRef + readonly controlledRef: UnwrapRef + readonly createApp: UnwrapRef + readonly createEventHook: UnwrapRef + readonly createGlobalState: UnwrapRef + readonly createInjectionState: UnwrapRef + readonly createPinia: UnwrapRef + readonly createReactiveFn: UnwrapRef + readonly createReusableTemplate: UnwrapRef + readonly createSharedComposable: UnwrapRef + readonly createTemplatePromise: UnwrapRef + readonly createUnrefFn: UnwrapRef + readonly customRef: UnwrapRef + readonly debouncedRef: UnwrapRef + readonly debouncedWatch: UnwrapRef + readonly defineAsyncComponent: UnwrapRef + readonly defineComponent: UnwrapRef + readonly defineStore: UnwrapRef + readonly eagerComputed: UnwrapRef + readonly effectScope: UnwrapRef + readonly extendRef: UnwrapRef + readonly getActivePinia: UnwrapRef + readonly getCurrentInstance: UnwrapRef + readonly getCurrentScope: UnwrapRef + readonly h: UnwrapRef + readonly ignorableWatch: UnwrapRef + readonly inject: UnwrapRef + readonly injectLocal: UnwrapRef + readonly isDefined: UnwrapRef + readonly isProxy: UnwrapRef + readonly isReactive: UnwrapRef + readonly isReadonly: UnwrapRef + readonly isRef: UnwrapRef + readonly makeDestructurable: UnwrapRef + readonly mapActions: UnwrapRef + readonly mapGetters: UnwrapRef + readonly mapState: UnwrapRef + readonly mapStores: UnwrapRef + readonly mapWritableState: UnwrapRef + readonly markRaw: UnwrapRef + readonly nextTick: UnwrapRef + readonly onActivated: UnwrapRef + readonly onBeforeMount: UnwrapRef + readonly onBeforeRouteLeave: UnwrapRef + readonly onBeforeRouteUpdate: UnwrapRef + readonly onBeforeUnmount: UnwrapRef + readonly onBeforeUpdate: UnwrapRef + readonly onClickOutside: UnwrapRef + readonly onDeactivated: UnwrapRef + readonly onErrorCaptured: UnwrapRef + readonly onKeyStroke: UnwrapRef + readonly onLongPress: UnwrapRef + readonly onMounted: UnwrapRef + readonly onRenderTracked: UnwrapRef + readonly onRenderTriggered: UnwrapRef + readonly onScopeDispose: UnwrapRef + readonly onServerPrefetch: UnwrapRef + readonly onStartTyping: UnwrapRef + readonly onUnmounted: UnwrapRef + readonly onUpdated: UnwrapRef + readonly onWatcherCleanup: UnwrapRef + readonly pausableWatch: UnwrapRef + readonly provide: UnwrapRef + readonly provideLocal: UnwrapRef + readonly reactify: UnwrapRef + readonly reactifyObject: UnwrapRef + readonly reactive: UnwrapRef + readonly reactiveComputed: UnwrapRef + readonly reactiveOmit: UnwrapRef + readonly reactivePick: UnwrapRef + readonly readonly: UnwrapRef + readonly ref: UnwrapRef + readonly refAutoReset: UnwrapRef + readonly refDebounced: UnwrapRef + readonly refDefault: UnwrapRef + readonly refThrottled: UnwrapRef + readonly refWithControl: UnwrapRef + readonly resolveComponent: UnwrapRef + readonly resolveRef: UnwrapRef + readonly resolveUnref: UnwrapRef + readonly setActivePinia: UnwrapRef + readonly setMapStoreSuffix: UnwrapRef + readonly shallowReactive: UnwrapRef + readonly shallowReadonly: UnwrapRef + readonly shallowRef: UnwrapRef + readonly storeToRefs: UnwrapRef + readonly syncRef: UnwrapRef + readonly syncRefs: UnwrapRef + readonly templateRef: UnwrapRef + readonly throttledRef: UnwrapRef + readonly throttledWatch: UnwrapRef + readonly toRaw: UnwrapRef + readonly toReactive: UnwrapRef + readonly toRef: UnwrapRef + readonly toRefs: UnwrapRef + readonly toValue: UnwrapRef + readonly triggerRef: UnwrapRef + readonly tryOnBeforeMount: UnwrapRef + readonly tryOnBeforeUnmount: UnwrapRef + readonly tryOnMounted: UnwrapRef + readonly tryOnScopeDispose: UnwrapRef + readonly tryOnUnmounted: UnwrapRef + readonly unref: UnwrapRef + readonly unrefElement: UnwrapRef + readonly until: UnwrapRef + readonly useActiveElement: UnwrapRef + readonly useAnimate: UnwrapRef + readonly useArrayDifference: UnwrapRef + readonly useArrayEvery: UnwrapRef + readonly useArrayFilter: UnwrapRef + readonly useArrayFind: UnwrapRef + readonly useArrayFindIndex: UnwrapRef + readonly useArrayFindLast: UnwrapRef + readonly useArrayIncludes: UnwrapRef + readonly useArrayJoin: UnwrapRef + readonly useArrayMap: UnwrapRef + readonly useArrayReduce: UnwrapRef + readonly useArraySome: UnwrapRef + readonly useArrayUnique: UnwrapRef + readonly useAsyncQueue: UnwrapRef + readonly useAsyncState: UnwrapRef + readonly useAttrs: UnwrapRef + readonly useBase64: UnwrapRef + readonly useBattery: UnwrapRef + readonly useBluetooth: UnwrapRef + readonly useBreakpoints: UnwrapRef + readonly useBroadcastChannel: UnwrapRef + readonly useBrowserLocation: UnwrapRef + readonly useCached: UnwrapRef + readonly useClipboard: UnwrapRef + readonly useClipboardItems: UnwrapRef + readonly useCloned: UnwrapRef + readonly useColorMode: UnwrapRef + readonly useConfirmDialog: UnwrapRef + readonly useCounter: UnwrapRef + readonly useCssModule: UnwrapRef + readonly useCssVar: UnwrapRef + readonly useCssVars: UnwrapRef + readonly useCurrentElement: UnwrapRef + readonly useCycleList: UnwrapRef + readonly useDark: UnwrapRef + readonly useDateFormat: UnwrapRef + readonly useDebounce: UnwrapRef + readonly useDebounceFn: UnwrapRef + readonly useDebouncedRefHistory: UnwrapRef + readonly useDeviceMotion: UnwrapRef + readonly useDeviceOrientation: UnwrapRef + readonly useDevicePixelRatio: UnwrapRef + readonly useDevicesList: UnwrapRef + readonly useDisplayMedia: UnwrapRef + readonly useDocumentVisibility: UnwrapRef + readonly useDraggable: UnwrapRef + readonly useDropZone: UnwrapRef + readonly useElementBounding: UnwrapRef + readonly useElementByPoint: UnwrapRef + readonly useElementHover: UnwrapRef + readonly useElementSize: UnwrapRef + readonly useElementVisibility: UnwrapRef + readonly useEventBus: UnwrapRef + readonly useEventListener: UnwrapRef + readonly useEventSource: UnwrapRef + readonly useEyeDropper: UnwrapRef + readonly useFavicon: UnwrapRef + readonly useFetch: UnwrapRef + readonly useFileDialog: UnwrapRef + readonly useFileSystemAccess: UnwrapRef + readonly useFocus: UnwrapRef + readonly useFocusWithin: UnwrapRef + readonly useFps: UnwrapRef + readonly useFullscreen: UnwrapRef + readonly useGamepad: UnwrapRef + readonly useGeolocation: UnwrapRef + readonly useId: UnwrapRef + readonly useIdle: UnwrapRef + readonly useImage: UnwrapRef + readonly useInfiniteScroll: UnwrapRef + readonly useIntersectionObserver: UnwrapRef + readonly useInterval: UnwrapRef + readonly useIntervalFn: UnwrapRef + readonly useKeyModifier: UnwrapRef + readonly useLastChanged: UnwrapRef + readonly useLink: UnwrapRef + readonly useLocalStorage: UnwrapRef + readonly useMagicKeys: UnwrapRef + readonly useManualRefHistory: UnwrapRef + readonly useMediaControls: UnwrapRef + readonly useMediaQuery: UnwrapRef + readonly useMemoize: UnwrapRef + readonly useMemory: UnwrapRef + readonly useModel: UnwrapRef + readonly useMounted: UnwrapRef + readonly useMouse: UnwrapRef + readonly useMouseInElement: UnwrapRef + readonly useMousePressed: UnwrapRef + readonly useMutationObserver: UnwrapRef + readonly useNavigatorLanguage: UnwrapRef + readonly useNetwork: UnwrapRef + readonly useNow: UnwrapRef + readonly useObjectUrl: UnwrapRef + readonly useOffsetPagination: UnwrapRef + readonly useOnline: UnwrapRef + readonly usePageLeave: UnwrapRef + readonly useParallax: UnwrapRef + readonly useParentElement: UnwrapRef + readonly usePerformanceObserver: UnwrapRef + readonly usePermission: UnwrapRef + readonly usePointer: UnwrapRef + readonly usePointerLock: UnwrapRef + readonly usePointerSwipe: UnwrapRef + readonly usePreferredColorScheme: UnwrapRef + readonly usePreferredContrast: UnwrapRef + readonly usePreferredDark: UnwrapRef + readonly usePreferredLanguages: UnwrapRef + readonly usePreferredReducedMotion: UnwrapRef + readonly usePrevious: UnwrapRef + readonly useRafFn: UnwrapRef + readonly useRefHistory: UnwrapRef + readonly useResizeObserver: UnwrapRef + readonly useRoute: UnwrapRef + readonly useRouter: UnwrapRef + readonly useScreenOrientation: UnwrapRef + readonly useScreenSafeArea: UnwrapRef + readonly useScriptTag: UnwrapRef + readonly useScroll: UnwrapRef + readonly useScrollLock: UnwrapRef + readonly useSessionStorage: UnwrapRef + readonly useShare: UnwrapRef + readonly useSlots: UnwrapRef + readonly useSorted: UnwrapRef + readonly useSpeechRecognition: UnwrapRef + readonly useSpeechSynthesis: UnwrapRef + readonly useStepper: UnwrapRef + readonly useStorage: UnwrapRef + readonly useStorageAsync: UnwrapRef + readonly useStyleTag: UnwrapRef + readonly useSupported: UnwrapRef + readonly useSwipe: UnwrapRef + readonly useTemplateRef: UnwrapRef + readonly useTemplateRefsList: UnwrapRef + readonly useTextDirection: UnwrapRef + readonly useTextSelection: UnwrapRef + readonly useTextareaAutosize: UnwrapRef + readonly useThrottle: UnwrapRef + readonly useThrottleFn: UnwrapRef + readonly useThrottledRefHistory: UnwrapRef + readonly useTimeAgo: UnwrapRef + readonly useTimeout: UnwrapRef + readonly useTimeoutFn: UnwrapRef + readonly useTimeoutPoll: UnwrapRef + readonly useTimestamp: UnwrapRef + readonly useTitle: UnwrapRef + readonly useToNumber: UnwrapRef + readonly useToString: UnwrapRef + readonly useToggle: UnwrapRef + readonly useTransition: UnwrapRef + readonly useUrlSearchParams: UnwrapRef + readonly useUserMedia: UnwrapRef + readonly useVModel: UnwrapRef + readonly useVModels: UnwrapRef + readonly useVibrate: UnwrapRef + readonly useVirtualList: UnwrapRef + readonly useWakeLock: UnwrapRef + readonly useWebNotification: UnwrapRef + readonly useWebSocket: UnwrapRef + readonly useWebWorker: UnwrapRef + readonly useWebWorkerFn: UnwrapRef + readonly useWindowFocus: UnwrapRef + readonly useWindowScroll: UnwrapRef + readonly useWindowSize: UnwrapRef + readonly watch: UnwrapRef + readonly watchArray: UnwrapRef + readonly watchAtMost: UnwrapRef + readonly watchDebounced: UnwrapRef + readonly watchDeep: UnwrapRef + readonly watchEffect: UnwrapRef + readonly watchIgnorable: UnwrapRef + readonly watchImmediate: UnwrapRef + readonly watchOnce: UnwrapRef + readonly watchPausable: UnwrapRef + readonly watchPostEffect: UnwrapRef + readonly watchSyncEffect: UnwrapRef + readonly watchThrottled: UnwrapRef + readonly watchTriggerable: UnwrapRef + readonly watchWithFilter: UnwrapRef + readonly whenever: UnwrapRef + } +} \ No newline at end of file diff --git a/components.d.ts b/components.d.ts index 82e896d..ea5bc85 100644 --- a/components.d.ts +++ b/components.d.ts @@ -33,7 +33,6 @@ declare module 'vue' { AMenuItemGroup: typeof import('ant-design-vue/es')['MenuItemGroup'] AModal: typeof import('ant-design-vue/es')['Modal'] AnimatedNature: typeof import('./src/components/AnimatedNature/AnimatedNature.vue')['default'] - AnimatedSvgIllustration: typeof import('./src/components/AnimatedSvgIllustration/AnimatedSvgIllustration.vue')['default'] APopover: typeof import('ant-design-vue/es')['Popover'] AProgress: typeof import('ant-design-vue/es')['Progress'] AQrcode: typeof import('ant-design-vue/es')['QRCode'] @@ -62,6 +61,7 @@ declare module 'vue' { CommentInput: typeof import('./src/components/CommentReply/src/CommentInput/CommentInput.vue')['default'] CommentList: typeof import('./src/components/CommentReply/src/CommentList/CommentList.vue')['default'] CommentReply: typeof import('./src/components/CommentReply/index.vue')['default'] + CompareImage: typeof import('./src/views/Upscale/CompareImage.vue')['default'] CompareResult: typeof import('./src/views/Upscale/CompareResult.vue')['default'] Countdown: typeof import('./src/components/MyUI/Countdown/Countdown.vue')['default'] DatePicker: typeof import('./src/components/MyUI/DatePicker/DatePicker.vue')['default'] @@ -70,7 +70,6 @@ declare module 'vue' { Divider: typeof import('./src/components/MyUI/Divider/Divider.vue')['default'] Drawer: typeof import('./src/components/MyUI/Drawer/Drawer.vue')['default'] DynamicTitle: typeof import('./src/components/DynamicTitle/DynamicTitle.vue')['default'] - EffectsCard: typeof import('./src/components/EffectsCard/EffectsCard.vue')['default'] Ellipsis: typeof import('./src/components/MyUI/Ellipsis/Ellipsis.vue')['default'] Empty: typeof import('./src/components/MyUI/Empty/Empty.vue')['default'] Flex: typeof import('./src/components/MyUI/Flex/Flex.vue')['default'] @@ -102,6 +101,7 @@ declare module 'vue' { Phoalbum: typeof import('./src/views/Album/Phoalbum/Phoalbum.vue')['default'] Popconfirm: typeof import('./src/components/MyUI/Popconfirm/Popconfirm.vue')['default'] Popover: typeof import('./src/components/MyUI/Popover/Popover.vue')['default'] + ProcessResult: typeof import('./src/views/Upscale/ProcessResult.vue')['default'] Progress: typeof import('./src/components/MyUI/Progress/Progress.vue')['default'] QRCode: typeof import('./src/components/MyUI/QRCode/QRCode.vue')['default'] QRLogin: typeof import('./src/views/QRLogin/QRLogin.vue')['default'] @@ -134,6 +134,7 @@ declare module 'vue' { TabletOutlined: typeof import('@ant-design/icons-vue')['TabletOutlined'] Tabs: typeof import('./src/components/MyUI/Tabs/Tabs.vue')['default'] Tag: typeof import('./src/components/MyUI/Tag/Tag.vue')['default'] + TestCompare: typeof import('./src/views/Upscale/TestCompare.vue')['default'] Textarea: typeof import('./src/components/MyUI/Textarea/Textarea.vue')['default'] TextScroll: typeof import('./src/components/MyUI/TextScroll/TextScroll.vue')['default'] ThingAlbum: typeof import('./src/views/Album/ThingAlbum/ThingAlbum.vue')['default'] diff --git a/index.html b/index.html index c6e747f..e9a676e 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ - + <%- title %> diff --git a/package.json b/package.json index 07e9709..f8a7e0c 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "qrcode": "^1", "seedrandom": "^3.0.5", "swiper": "^11.1.15", - "unplugin-auto-import": "^0.18.6", + "unplugin-auto-import": "^0.19.0", "vite-plugin-compression": "^0.5.1", "vite-plugin-html": "^3.2.2", "vite-plugin-node-polyfills": "^0.22.0", @@ -62,13 +62,13 @@ "@vitejs/plugin-vue": "^5.2.1", "eslint-plugin-vue": "^9.32.0", "globals": "^15.13.0", - "sass": "^1.82.0", + "sass": "^1.83.0", "typescript": "^5.7.2", "typescript-eslint": "^8.18.0", "unplugin-vue-components": "^0.27.5", "vite": "^6.0.3", "vite-plugin-bundle-obfuscator": "1.4.0", "vite-plugin-chunk-split": "^0.5.0", - "vue-tsc": "^2.1.10" + "vue-tsc": "https://pkg.pr.new/vuejs/language-tools/vue-tsc@3fb59af" } } diff --git a/src/components/AnimatedSvgIllustration/AnimatedSvgIllustration.vue b/src/components/AnimatedSvgIllustration/AnimatedSvgIllustration.vue deleted file mode 100644 index 1e7cf79..0000000 --- a/src/components/AnimatedSvgIllustration/AnimatedSvgIllustration.vue +++ /dev/null @@ -1,459 +0,0 @@ - - - - - diff --git a/src/components/AnimatedSvgIllustration/index.scss b/src/components/AnimatedSvgIllustration/index.scss deleted file mode 100644 index a41a211..0000000 --- a/src/components/AnimatedSvgIllustration/index.scss +++ /dev/null @@ -1,24 +0,0 @@ -svg { - width: 100%; - height: auto; -} - -#card1_bg-white, #card2_bg-white, #card3_bg-white, #card4_bg-white { - transform-origin: 2% 8%; - transform-style: preserve-3D; -} - -#card3_bg-white, -#card4_bg-white, -#card5_bg-white { - transform: scale(0); -} - -#plane1 { - transform-origin: 620px 580px; -} - -#plane2 { - transform: scaleX(-1) translate(-1500px, -150px); - transform-origin: 500px 650px; -} diff --git a/src/components/EffectsCard/EffectsCard.vue b/src/components/EffectsCard/EffectsCard.vue deleted file mode 100644 index 32627c6..0000000 --- a/src/components/EffectsCard/EffectsCard.vue +++ /dev/null @@ -1,373 +0,0 @@ - - - diff --git a/src/components/VueCompareImage/VueCompareImage.vue b/src/components/VueCompareImage/VueCompareImage.vue index 6113b60..51b72b3 100644 --- a/src/components/VueCompareImage/VueCompareImage.vue +++ b/src/components/VueCompareImage/VueCompareImage.vue @@ -82,7 +82,7 @@ const horizontal = !vertical.value; const containerRef = ref(); const rightImageRef = ref(null); const leftImageRef = ref(null); -const sliderPosition = ref(sliderPositionPercentage.value); +const sliderPosition = ref(sliderPositionPercentage.value); const containerWidth = ref(0); const containerHeight = ref(0); const leftImgLoaded = ref(false); diff --git a/src/store/modules/upscaleStore.ts b/src/store/modules/upscaleStore.ts index 778f910..4beb57c 100644 --- a/src/store/modules/upscaleStore.ts +++ b/src/store/modules/upscaleStore.ts @@ -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(false); + + // 处理后的图片 + const processedImg = ref(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', + ] } } ) diff --git a/src/utils/upscale/handler.ts b/src/utils/upscale/handler.ts deleted file mode 100644 index 0b88e63..0000000 --- a/src/utils/upscale/handler.ts +++ /dev/null @@ -1,270 +0,0 @@ -import * as tf from "@tensorflow/tfjs"; - -import Img from "@/workers/image.ts"; -import {ImageData} from "@/types/upscale"; -import upscale from "@/workers/upscale.ts"; -// import "@tensorflow/tfjs-backend-webgpu"; -import "@tensorflow/tfjs-backend-webgl"; - - -/** - * 加载模型 - * @param model_type 模型类型,可选值:realesrgan、realcugan - * @param model 模型名称,例如 realesrgan_x4 - * @param tile_size 块大小,例如:64 - * @param factor 超分辨率因子,例如:4 - * @param backend 后端,可选值:webgpu、webgl - */ -export async function loadModel(model_type: string, model: string, tile_size: number, factor: number, backend: string): Promise { - let model_url: string; - let model_name: string; - - if (model_type === "realesrgan") { - model_url = `/tfjs/realesrgan/${model}-${tile_size}/model.json`; - model_name = `realesrgan-${model}-${tile_size}`; - } else { - model_url = `/tfjs/realcugan/${factor}x-${model}-${tile_size}/model.json`; - model_name = `realcugan-${factor}x-${model}-${tile_size}`; - } - - await tf.ready(); - if (backend === "webgpu") { - await import("@tensorflow/tfjs-backend-webgpu"); - } - try { - if (!(await tf.setBackend(backend || "webgl"))) { - console.error(`${backend} 后端在您的浏览器中不被支持。`); - return null; - } - console.log(`当前使用后端: ${tf.getBackend()}`); - } catch (error) { - console.error("设置后端时发生错误:", error); - console.log("支持的后端列表:", tf.getBackend()); - return null; - } - - try { - const Model = await tf.loadGraphModel(`indexeddb://${model_name}`); - console.log("模型加载成功"); - return Model; - } catch (error) { - console.error("模型加载失败,开始下载模型:", error); - try { - const fetchedModel = await tf.loadGraphModel(model_url); - await fetchedModel.save(`indexeddb://${model_name}`); - console.log("模型下载并保存成功"); - return fetchedModel; - } catch (error) { - console.error("模型下载失败:", error); - return null; - } - } -} - -/** - * 处理图片 - * @param data - */ -export async function processImage(data: ImageData) { - const Model: tf.GraphModel | null = await loadModel(data.model_type, data.model, data.tile_size, data.factor, data.backend); - if (!Model) { - return null; - } - const input = new Img(data.width, data.height, new Uint8Array(data.input)); - const width_ori = input.width; - const height_ori = input.height; - input.padToTileSize(data.tile_size || 64); - let withPadding = false; - if (input.width !== width_ori || input.height !== height_ori) { - withPadding = true; - } - const hasAlpha = data.hasAlpha; - - const factor = data.factor || 4; - const tile_size = data.tile_size || 64; - const min_lap = data.min_lap || 12; - const start = Date.now(); - - const output = await enlargeImageWithFixedInput( - Model, - input, - factor, - tile_size, - min_lap, - hasAlpha - ); - - if (withPadding) { - output.cropToOriginalSize(width_ori * factor, height_ori * factor); - } - const end = Date.now(); - console.log("Time:", end - start); - return output.data.buffer; - -} - -/** - * 超分辨率 - * @param model - * @param inputImg - * @param factor - * @param input_size - * @param min_lap - * @param hasAlpha - */ -async function enlargeImageWithFixedInput( - model: tf.GraphModel, - inputImg: Img, - factor = 4, - input_size = 64, - min_lap = 12, - hasAlpha = false, -) { - const width = inputImg.width; - const height = inputImg.height; - const output = new Img(width * factor, height * factor); - let num_x = 1; - for (; (input_size * num_x - width) / (num_x - 1) < min_lap; num_x++) ; - let num_y = 1; - for (; (input_size * num_y - height) / (num_y - 1) < min_lap; num_y++) ; - const locs_x = new Array(num_x); - const locs_y = new Array(num_y); - const pad_left = new Array(num_x); - const pad_top = new Array(num_y); - const pad_right = new Array(num_x); - const pad_bottom = new Array(num_y); - const total_lap_x = input_size * num_x - width; - const total_lap_y = input_size * num_y - height; - const base_lap_x = Math.floor(total_lap_x / (num_x - 1)); - const base_lap_y = Math.floor(total_lap_y / (num_y - 1)); - const extra_lap_x = total_lap_x - base_lap_x * (num_x - 1); - const extra_lap_y = total_lap_y - base_lap_y * (num_y - 1); - locs_x[0] = 0; - for (let i = 1; i < num_x; i++) { - if (i <= extra_lap_x) { - locs_x[i] = locs_x[i - 1] + input_size - base_lap_x - 1; - } else { - locs_x[i] = locs_x[i - 1] + input_size - base_lap_x; - } - } - locs_y[0] = 0; - for (let i = 1; i < num_y; i++) { - if (i <= extra_lap_y) { - locs_y[i] = locs_y[i - 1] + input_size - base_lap_y - 1; - } else { - locs_y[i] = locs_y[i - 1] + input_size - base_lap_y; - } - } - pad_left[0] = 0; - pad_top[0] = 0; - pad_right[num_x - 1] = 0; - pad_bottom[num_y - 1] = 0; - for (let i = 1; i < num_x; i++) { - pad_left[i] = Math.floor((locs_x[i - 1] + input_size - locs_x[i]) / 2); - } - for (let i = 1; i < num_y; i++) { - pad_top[i] = Math.floor((locs_y[i - 1] + input_size - locs_y[i]) / 2); - } - for (let i = 0; i < num_x - 1; i++) { - pad_right[i] = locs_x[i] + input_size - locs_x[i + 1] - pad_left[i + 1]; - } - for (let i = 0; i < num_y - 1; i++) { - pad_bottom[i] = locs_y[i] + input_size - locs_y[i + 1] - pad_top[i + 1]; - } - // const total = num_x * num_y; - // let current = 0; - // const useModel = new Array(total).fill(false); - if (hasAlpha) { - for (let i = 0; i < num_x; i++) { - for (let j = 0; j < num_y; j++) { - const x1 = locs_x[i]; - const y1 = locs_y[j]; - const x2 = locs_x[i] + input_size; - const y2 = locs_y[j] + input_size; - const tile = new Img(input_size, input_size); - tile.getImageCrop(0, 0, inputImg, x1, y1, x2, y2); - for (let k = 4; k < tile.data.length; k += 4) { - if (tile.data[k + 3] !== tile.data[3]) { - // useModel[current] = true; - break; - } - } - // if (useModel[current]) { - // current++; - // continue; - // } - const scaled = new Img(tile.width * factor, tile.height * factor); - for (let k = 0; k < scaled.data.length; k += 4) { - scaled.data[k] = tile.data[3]; - scaled.data[k + 1] = tile.data[3]; - scaled.data[k + 2] = tile.data[3]; - } - output.getImageCrop( - (x1 + pad_left[i]) * factor, - (y1 + pad_top[j]) * factor, - scaled, - pad_left[i] * factor, - pad_top[j] * factor, - scaled.width - pad_right[i] * factor, - scaled.height - pad_bottom[j] * factor - ); - // current++; - } - } - // current = 0; - for (let i = 0; i < num_x; i++) { - for (let j = 0; j < num_y; j++) { - // if (!useModel[current]) { - // current++; - // const progress = (current / total) * 100; - // sendprogress(progress); - // continue; - // } - const x1 = locs_x[i]; - const y1 = locs_y[j]; - const x2 = locs_x[i] + input_size; - const y2 = locs_y[j] + input_size; - const tile = new Img(input_size, input_size); - tile.getImageCrop(0, 0, inputImg, x1, y1, x2, y2); - const scaled = await upscale(tile, model, true); - output.getImageCrop( - (x1 + pad_left[i]) * factor, - (y1 + pad_top[j]) * factor, - scaled, - pad_left[i] * factor, - pad_top[j] * factor, - scaled.width - pad_right[i] * factor, - scaled.height - pad_bottom[j] * factor - ); - // current++; - // const progress = (current / total) * 100; - // sendprogress(progress); - } - } - } else { - for (let i = 0; i < num_x; i++) { - for (let j = 0; j < num_y; j++) { - const x1 = locs_x[i]; - const y1 = locs_y[j]; - const x2 = locs_x[i] + input_size; - const y2 = locs_y[j] + input_size; - const tile = new Img(input_size, input_size); - tile.getImageCrop(0, 0, inputImg, x1, y1, x2, y2); - const scaled = await upscale(tile, model); - output.getImageCrop( - (x1 + pad_left[i]) * factor, - (y1 + pad_top[j]) * factor, - scaled, - pad_left[i] * factor, - pad_top[j] * factor, - scaled.width - pad_right[i] * factor, - scaled.height - pad_bottom[j] * factor - ); - // current++; - // const progress = (current / total) * 100; - // sendprogress(progress); - } - } - } - return output; -} diff --git a/src/views/Photograph/AllPhoto/AllPhoto.vue b/src/views/Photograph/AllPhoto/AllPhoto.vue index 5b870fa..2448955 100644 --- a/src/views/Photograph/AllPhoto/AllPhoto.vue +++ b/src/views/Photograph/AllPhoto/AllPhoto.vue @@ -1,15 +1,10 @@ + - - - diff --git a/src/views/Upscale/CompareImage.vue b/src/views/Upscale/CompareImage.vue new file mode 100644 index 0000000..442addf --- /dev/null +++ b/src/views/Upscale/CompareImage.vue @@ -0,0 +1,532 @@ + + + diff --git a/src/views/Upscale/CompareResult.vue b/src/views/Upscale/ProcessResult.vue similarity index 100% rename from src/views/Upscale/CompareResult.vue rename to src/views/Upscale/ProcessResult.vue diff --git a/src/views/Upscale/Upscale.vue b/src/views/Upscale/Upscale.vue index bd752d5..3d4c18b 100644 --- a/src/views/Upscale/Upscale.vue +++ b/src/views/Upscale/Upscale.vue @@ -23,7 +23,7 @@ 模型: + :options="modes.map((item: any) => ({label: item, value: item}))"> @@ -32,7 +32,7 @@ 比列: + :options="scales.map((item: any) => ({label: item, value: item}))"> @@ -40,7 +40,7 @@ 分块大小: + :options="tileSize.map((item: any) => ({label: item, value: item}))"> @@ -50,14 +50,14 @@ 重复: + :options="overlapList.map((item: any) => ({label: item, value: item}))">
运行环境: + :options="backendList.map((item: any) => ({label: item, value: item}))">
@@ -74,7 +74,7 @@
- +
@@ -84,7 +84,7 @@ import UploadImage from "@/views/Upscale/UploadImage.vue"; import ai from "@/assets/svgs/ai.svg"; import run from "@/assets/svgs/run.svg"; -import CompareResult from "@/views/Upscale/CompareResult.vue"; +import ProcessResult from "@/views/Upscale/ProcessResult.vue"; import useStore from "@/store"; import {message} from "ant-design-vue"; import Img from "@/workers/image.ts"; @@ -158,96 +158,10 @@ const backendList = ['webgl', 'webgpu']; const backend = ref(backendList[0]); // ********************处理图片******************* -/** - * 函数写法:已废弃,改用WebWorker - */ -// const output = ref(); -// const resultUrl = ref(); -// -// async function startTask() { -// if (!upscale.input) return; -// let outputData: any; -// if (upscale.hasAlpha && upscale.inputAlpha) { -// outputData = await processImage( -// { -// input: upscale.inputAlpha.data.buffer, -// factor: factor.value, -// tile_size: tile_size.value, -// min_lap: min_lap.value, -// model_type: model_type.value, -// width: upscale.inputAlpha.width, -// height: upscale.inputAlpha.height, -// model: model.value, -// backend: backend.value, -// hasAlpha: true, -// } -// ); -// } else { -// outputData = await processImage({ -// input: upscale.input.data.buffer, -// factor: factor.value, -// tile_size: tile_size.value, -// min_lap: min_lap.value, -// model_type: model_type.value, -// width: upscale.input.width, -// height: upscale.input.height, -// model: model.value, -// backend: backend.value, -// hasAlpha: false -// }); -// } -// -// if (outputData) { -// if (!upscale.hasAlpha || (upscale.hasAlpha && upscale.inputAlpha)) { -// if (upscale.input) { -// output.value = new Img( -// factor.value * upscale.input.width, -// factor.value * upscale.input.height, -// new Uint8Array(outputData) -// ); -// } -// } -// if (upscale.hasAlpha && upscale.wasmModule) { -// const outputArray = new Uint8Array(outputData); -// const sourcePtr = upscale.wasmModule._malloc(outputArray.length); -// const targetPtr = upscale.wasmModule._malloc(outputArray.length); -// const numPixels = outputArray.length / 4; -// upscale.wasmModule.HEAPU8.set(outputArray, sourcePtr); -// upscale.wasmModule.HEAPU8.set(output.value.data, targetPtr); -// upscale.wasmModule._copy_alpha_channel(sourcePtr, targetPtr, numPixels); -// output.value.data.set( -// upscale.wasmModule.HEAPU8.subarray( -// targetPtr, -// targetPtr + outputArray.length -// ) -// ); -// upscale.wasmModule._free(sourcePtr); -// upscale.wasmModule._free(targetPtr); -// upscale.wasmModule = null; -// } -// -// const imgCanvas = document.createElement("canvas"); -// const imgCtx = imgCanvas.getContext("2d"); -// imgCanvas.width = output.value.width; -// imgCanvas.height = output.value.height; -// if (imgCtx) { -// let outImg = imgCtx.createImageData(output.value.width, output.value.height); -// outImg.data.set(output.value.data); -// imgCtx.putImageData(outImg, 0, 0); -// let type = "image/jpeg"; -// let quality = 0.92; -// if (upscale.hasAlpha) type = "image/png"; -// resultUrl.value = imgCanvas.toDataURL(type, quality); -// console.log(resultUrl.value); -// } -// } -// } - const isProcessing = ref(false); const msg = ref(""); const progressBar = ref(0); const outputData = ref(); -const processedImg = ref(new Image()); const isDone = ref(false); const imgCanvas = document.createElement("canvas"); @@ -256,7 +170,7 @@ const worker = new Worker(new URL("@/workers/upscale.worker.ts", import.meta.url }); /** - * WebWorker写法:使用workerStore + * WebWorker 处理图片 */ async function startTask() { if (upscale.input === null) return; @@ -340,27 +254,24 @@ async function startTask() { outputData.value = null; imgCtx.putImageData(outImg, 0, 0); let type = "image/jpeg"; - let quality = 0.92; + const quality = 0.92; if (upscale.hasAlpha) type = "image/png"; - if (processedImg.value) { + if (upscale.processedImg) { imgCanvas.toBlob( (blob: any) => { - processedImg.value.src = URL.createObjectURL(blob); + upscale.processedImg.src = URL.createObjectURL(blob); }, type, quality ); - processedImg.value.onload = () => { + upscale.processedImg.onload = () => { msg.value = "Done! Time used: " + (Date.now() - start) / 1000 + "s"; }; } isProcessing.value = false; isDone.value = true; - console.log(processedImg.value); - console.log(msg.value); worker.terminate(); } - } }; if (upscale.input) { @@ -382,6 +293,96 @@ async function startTask() { } } - diff --git a/src/views/Upscale/index.scss b/src/views/Upscale/index.scss deleted file mode 100644 index dc0d0ea..0000000 --- a/src/views/Upscale/index.scss +++ /dev/null @@ -1,91 +0,0 @@ -.upscale-container { - display: flex; - flex-direction: column; - width: 100%; - height: 100%; - - - .upscale-title { - font-size: 16px; - font-weight: bold; - margin-left: 5px; - } - - .upscale-content { - width: 100%; - height: 100%; - margin-top: 5px; - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - - .upscale-content-left { - width: 49%; - height: 100%; - display: flex; - flex-direction: column; - justify-content: center; - - .upscale-content-left-container { - width: 100%; - height: 100%; - overflow: auto; - - .upscale-divider-title { - font-size: 13px; - color: rgba(126, 126, 135, 0.99); - } - - .upscale-content-left-params { - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - - .upscale-content-params-left { - width: 80%; - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - - .upscale-content-params-item { - width: 30%; - display: flex; - flex-direction: column; - justify-content: center; - - .upscale-content-params-title { - font-size: 13px; - color: rgba(126, 126, 135, 0.99); - } - } - } - - .upscale-content-params-right { - width: 20%; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - } - } - } - } - - .upscale-content-right { - width: 50%; - height: 100%; - - .upscale-content-right-container { - width: 100%; - height: 100%; - overflow: auto; - } - - } - } -} - - diff --git a/src/workers/imghelper.c b/src/workers/imghelper.c index ec9f80e..74e433d 100644 --- a/src/workers/imghelper.c +++ b/src/workers/imghelper.c @@ -2,7 +2,7 @@ #include // Usage - generate js and wasm files -// emcc imghelper.c -o imghelper.js -O2 -s WASM=1 -s EXPORTED_FUNCTIONS="['_copy_alpha_to_rgb','_check_alpha','_copy_alpha_channel','_malloc','_free']" -s EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap']" -s ALLOW_MEMORY_GROWTH=1 -s MODULARIZE=1 -s EXPORT_ES6=1 +// emcc imghelper.c -o imghelper.ts -O2 -s WASM=1 -s EXPORTED_FUNCTIONS="['_copy_alpha_to_rgb','_check_alpha','_copy_alpha_channel','_malloc','_free']" -s EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap']" -s ALLOW_MEMORY_GROWTH=1 -s MODULARIZE=1 -s EXPORT_ES6=1 bool check_alpha(uint8_t *data, int pixelCount) { diff --git a/src/workers/imghelper.js b/src/workers/imghelper.ts similarity index 81% rename from src/workers/imghelper.js rename to src/workers/imghelper.ts index 5d38297..8befc03 100644 --- a/src/workers/imghelper.js +++ b/src/workers/imghelper.ts @@ -1,12 +1,15 @@ +/* eslint-disable */ +// @ts-nocheck +// This file is a modified version of the original imghelper.ts file from Emscripten. const Module = (() => { - let _scriptDir = import.meta.url; + const _scriptDir = import.meta.url; return ( async function (moduleArg = {}) { - let Module = moduleArg; + const Module = moduleArg; let readyPromiseResolve, readyPromiseReject; - let readyPromise = new Promise((resolve, reject) => { + const readyPromise = new Promise((resolve, reject) => { readyPromiseResolve = resolve; readyPromiseReject = reject; }); @@ -16,9 +19,9 @@ const Module = (() => { let quit_ = (_status, toThrow) => { throw toThrow; }; - let ENVIRONMENT_IS_WEB = typeof window == "object"; - let ENVIRONMENT_IS_WORKER = typeof importScripts == "function"; - let ENVIRONMENT_IS_NODE = typeof process == "object" && typeof process.versions == "object" && typeof process.versions.node == "string"; + const ENVIRONMENT_IS_WEB = typeof window == "object"; + const ENVIRONMENT_IS_WORKER = typeof importScripts == "function"; + const ENVIRONMENT_IS_NODE = typeof process == "object" && typeof process.versions == "object" && typeof process.versions.node == "string"; let scriptDirectory = ""; function locateFile(path) { @@ -31,9 +34,9 @@ const Module = (() => { let read_, readAsync, readBinary; if (ENVIRONMENT_IS_NODE) { const {createRequire: createRequire} = await import("module"); - let require = createRequire(import.meta.url); - let fs = require("fs"); - let nodePath = require("path"); + const require = createRequire(import.meta.url); + const fs = require("fs"); + const nodePath = require("path"); if (ENVIRONMENT_IS_WORKER) { scriptDirectory = nodePath.dirname(scriptDirectory) + "/"; } else { @@ -80,14 +83,14 @@ const Module = (() => { } { read_ = url => { - let xhr = new XMLHttpRequest; + const xhr = new XMLHttpRequest; xhr.open("GET", url, false); xhr.send(null); return xhr.responseText; }; if (ENVIRONMENT_IS_WORKER) { readBinary = url => { - let xhr = new XMLHttpRequest; + const xhr = new XMLHttpRequest; xhr.open("GET", url, false); xhr.responseType = "arraybuffer"; xhr.send(null); @@ -95,7 +98,7 @@ const Module = (() => { }; } readAsync = (url, onload, onerror) => { - let xhr = new XMLHttpRequest; + const xhr = new XMLHttpRequest; xhr.open("GET", url, true); xhr.responseType = "arraybuffer"; xhr.onload = () => { @@ -110,28 +113,27 @@ const Module = (() => { }; } } - // eslint-disable-next-line @typescript-eslint/no-unused-vars - let out = Module["print"] || console.log.bind(console); - let err = Module["printErr"] || console.error.bind(console); + const out = Module["print"] || console.log.bind(console); + const err = Module["printErr"] || console.error.bind(console); Object.assign(Module, moduleOverrides); moduleOverrides = null; - // eslint-disable-next-line @typescript-eslint/no-unused-vars + if (Module["arguments"]) arguments_ = Module["arguments"]; - // eslint-disable-next-line @typescript-eslint/no-unused-vars + if (Module["thisProgram"]) thisProgram = Module["thisProgram"]; - // eslint-disable-next-line @typescript-eslint/no-unused-vars + if (Module["quit"]) quit_ = Module["quit"]; let wasmBinary; if (Module["wasmBinary"]) wasmBinary = Module["wasmBinary"]; let wasmMemory; let ABORT = false; - // eslint-disable-next-line @typescript-eslint/no-unused-vars + let EXITSTATUS; - // eslint-disable-next-line @typescript-eslint/no-unused-vars + let HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64; function updateMemoryViews() { - let b = wasmMemory.buffer; + const b = wasmMemory.buffer; Module["HEAP8"] = HEAP8 = new Int8Array(b); Module["HEAP16"] = HEAP16 = new Int16Array(b); Module["HEAPU8"] = HEAPU8 = new Uint8Array(b); @@ -142,10 +144,10 @@ const Module = (() => { Module["HEAPF64"] = HEAPF64 = new Float64Array(b); } - let __ATPRERUN__ = []; - let __ATINIT__ = []; - let __ATPOSTRUN__ = []; - // eslint-disable-next-line @typescript-eslint/no-unused-vars + const __ATPRERUN__ = []; + const __ATINIT__ = []; + const __ATPOSTRUN__ = []; + let runtimeInitialized = false; function preRun() { @@ -203,7 +205,7 @@ const Module = (() => { runDependencyWatcher = null; } if (dependenciesFulfilled) { - let callback = dependenciesFulfilled; + const callback = dependenciesFulfilled; dependenciesFulfilled = null; callback(); } @@ -217,14 +219,14 @@ const Module = (() => { ABORT = true; EXITSTATUS = 1; what += ". Build with -sASSERTIONS for more info."; - let e = new WebAssembly.RuntimeError(what); + const e = new WebAssembly.RuntimeError(what); readyPromiseReject(e); throw e; } - let dataURIPrefix = "data:application/octet-stream;base64,"; - let isDataURI = filename => filename.startsWith(dataURIPrefix); - let isFileURI = filename => filename.startsWith("file://"); + const dataURIPrefix = "data:application/octet-stream;base64,"; + const isDataURI = filename => filename.startsWith(dataURIPrefix); + const isFileURI = filename => filename.startsWith("file://"); let wasmBinaryFile; if (Module["locateFile"]) { wasmBinaryFile = "imghelper.wasm"; @@ -273,7 +275,7 @@ const Module = (() => { function instantiateAsync(binary, binaryFile, imports, callback) { if (!binary && typeof WebAssembly.instantiateStreaming == "function" && !isDataURI(binaryFile) && !isFileURI(binaryFile) && !ENVIRONMENT_IS_NODE && typeof fetch == "function") { return fetch(binaryFile, {credentials: "same-origin"}).then(response => { - let result = WebAssembly.instantiateStreaming(response, imports); + const result = WebAssembly.instantiateStreaming(response, imports); return result.then(callback, function (reason) { err(`wasm streaming compile failed: ${reason}`); err("falling back to ArrayBuffer instantiation"); @@ -285,7 +287,7 @@ const Module = (() => { } function createWasm() { - let info = {"env": wasmImports, "wasi_snapshot_preview1": wasmImports}; + const info = {"env": wasmImports, "wasi_snapshot_preview1": wasmImports}; function receiveInstance(instance, _module) { wasmExports = instance.exports; @@ -314,19 +316,19 @@ const Module = (() => { return {}; } - let callRuntimeCallbacks = callbacks => { + const callRuntimeCallbacks = callbacks => { while (callbacks.length > 0) { callbacks.shift()(Module); } }; - // eslint-disable-next-line @typescript-eslint/no-unused-vars - let noExitRuntime = Module["noExitRuntime"] || true; - let stackRestore = val => __emscripten_stack_restore(val); - let stackSave = () => _emscripten_stack_get_current(); - let getHeapMax = () => 2147483648; - let growMemory = size => { - let b = wasmMemory.buffer; - let pages = (size - b.byteLength + 65535) / 65536; + + const noExitRuntime = Module["noExitRuntime"] || true; + const stackRestore = val => __emscripten_stack_restore(val); + const stackSave = () => _emscripten_stack_get_current(); + const getHeapMax = () => 2147483648; + const growMemory = size => { + const b = wasmMemory.buffer; + const pages = (size - b.byteLength + 65535) / 65536; try { wasmMemory.grow(pages); updateMemoryViews(); @@ -334,36 +336,36 @@ const Module = (() => { } catch (_e) { /* empty */ } }; - let _emscripten_resize_heap = requestedSize => { - let oldSize = HEAPU8.length; + const _emscripten_resize_heap = requestedSize => { + const oldSize = HEAPU8.length; requestedSize >>>= 0; - let maxHeapSize = getHeapMax(); + const maxHeapSize = getHeapMax(); if (requestedSize > maxHeapSize) { return false; } - let alignUp = (x, multiple) => x + (multiple - x % multiple) % multiple; + const alignUp = (x, multiple) => x + (multiple - x % multiple) % multiple; for (let cutDown = 1; cutDown <= 4; cutDown *= 2) { let overGrownHeapSize = oldSize * (1 + .2 / cutDown); overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296); - let newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536)); - let replacement = growMemory(newSize); + const newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536)); + const replacement = growMemory(newSize); if (replacement) { return true; } } return false; }; - let getCFunc = ident => { - let func = Module["_" + ident]; + const getCFunc = ident => { + const func = Module["_" + ident]; return func; }; - let writeArrayToMemory = (array, buffer) => { + const writeArrayToMemory = (array, buffer) => { HEAP8.set(array, buffer); }; - let lengthBytesUTF8 = str => { + const lengthBytesUTF8 = str => { let len = 0; for (let i = 0; i < str.length; ++i) { - let c = str.charCodeAt(i); + const c = str.charCodeAt(i); if (c <= 127) { len++; } else if (c <= 2047) { @@ -377,14 +379,14 @@ const Module = (() => { } return len; }; - let stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => { + const stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => { if (!(maxBytesToWrite > 0)) return 0; - let startIdx = outIdx; - let endIdx = outIdx + maxBytesToWrite - 1; + const startIdx = outIdx; + const endIdx = outIdx + maxBytesToWrite - 1; for (let i = 0; i < str.length; ++i) { let u = str.charCodeAt(i); if (u >= 55296 && u <= 57343) { - let u1 = str.charCodeAt(++i); + const u1 = str.charCodeAt(++i); u = 65536 + ((u & 1023) << 10) | u1 & 1023; } if (u <= 127) { @@ -410,17 +412,17 @@ const Module = (() => { heap[outIdx] = 0; return outIdx - startIdx; }; - let stringToUTF8 = (str, outPtr, maxBytesToWrite) => stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite); - let stackAlloc = sz => __emscripten_stack_alloc(sz); - let stringToUTF8OnStack = str => { - let size = lengthBytesUTF8(str) + 1; - let ret = stackAlloc(size); + const stringToUTF8 = (str, outPtr, maxBytesToWrite) => stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite); + const stackAlloc = sz => __emscripten_stack_alloc(sz); + const stringToUTF8OnStack = str => { + const size = lengthBytesUTF8(str) + 1; + const ret = stackAlloc(size); stringToUTF8(str, ret, size); return ret; }; - let UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder("utf8") : undefined; - let UTF8ArrayToString = (heapOrArray, idx, maxBytesToRead) => { - let endIdx = idx + maxBytesToRead; + const UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder("utf8") : undefined; + const UTF8ArrayToString = (heapOrArray, idx, maxBytesToRead) => { + const endIdx = idx + maxBytesToRead; let endPtr = idx; while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr; if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) { @@ -433,12 +435,12 @@ const Module = (() => { str += String.fromCharCode(u0); continue; } - let u1 = heapOrArray[idx++] & 63; + const u1 = heapOrArray[idx++] & 63; if ((u0 & 224) == 192) { str += String.fromCharCode((u0 & 31) << 6 | u1); continue; } - let u2 = heapOrArray[idx++] & 63; + const u2 = heapOrArray[idx++] & 63; if ((u0 & 240) == 224) { u0 = (u0 & 15) << 12 | u1 << 6 | u2; } else { @@ -447,15 +449,15 @@ const Module = (() => { if (u0 < 65536) { str += String.fromCharCode(u0); } else { - let ch = u0 - 65536; + const ch = u0 - 65536; str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023); } } return str; }; - let UTF8ToString = (ptr, maxBytesToRead) => ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ""; - let ccall = (ident, returnType, argTypes, args, _opts) => { - let toC = { + const UTF8ToString = (ptr, maxBytesToRead) => ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ""; + const ccall = (ident, returnType, argTypes, args, _opts) => { + const toC = { "string": str => { let ret = 0; if (str !== null && str !== undefined && str !== 0) { @@ -463,7 +465,7 @@ const Module = (() => { } return ret; }, "array": arr => { - let ret = stackAlloc(arr.length); + const ret = stackAlloc(arr.length); writeArrayToMemory(arr, ret); return ret; } @@ -477,12 +479,12 @@ const Module = (() => { return ret; } - let func = getCFunc(ident); - let cArgs = []; + const func = getCFunc(ident); + const cArgs = []; let stack = 0; if (args) { for (let i = 0; i < args.length; i++) { - let converter = toC[argTypes[i]]; + const converter = toC[argTypes[i]]; if (converter) { if (stack === 0) stack = stackSave(); cArgs[i] = converter(args[i]); @@ -501,15 +503,15 @@ const Module = (() => { ret = onDone(ret); return ret; }; - let cwrap = (ident, returnType, argTypes, opts) => { - let numericArgs = !argTypes || argTypes.every(type => type === "number" || type === "boolean"); - let numericRet = returnType !== "string"; + const cwrap = (ident, returnType, argTypes, opts) => { + const numericArgs = !argTypes || argTypes.every(type => type === "number" || type === "boolean"); + const numericRet = returnType !== "string"; if (numericRet && numericArgs && !opts) { return getCFunc(ident); } return (...args) => ccall(ident, returnType, argTypes, args, opts); }; - let wasmImports = {emscripten_resize_heap: _emscripten_resize_heap}; + const wasmImports = {emscripten_resize_heap: _emscripten_resize_heap}; let wasmExports = createWasm(); let ___wasm_call_ctors = () => (___wasm_call_ctors = wasmExports["__wasm_call_ctors"])(); let _check_alpha = Module["_check_alpha"] = (a0, a1) => (_check_alpha = Module["_check_alpha"] = wasmExports["check_alpha"])(a0, a1); diff --git a/src/workers/upscale.worker.ts b/src/workers/upscale.worker.ts index bbb84e6..77ba6d7 100644 --- a/src/workers/upscale.worker.ts +++ b/src/workers/upscale.worker.ts @@ -25,9 +25,9 @@ self.onmessage = async function (e: MessageEvent): Promise { try { Model = await tf.loadGraphModel(`indexeddb://${model_name}`); console.log("Model loaded successfully"); - self.postMessage({info: "Loaded from cache"}); + self.postMessage({info: "Model loaded from cache successfully"}); } catch (_error) { - self.postMessage({info: "Downloading model"}); + self.postMessage({info: "Downloading model..."}); Model = await (async () => { const fetchedModel = await tf.loadGraphModel(model_url); await fetchedModel.save(`indexeddb://${model_name}`); diff --git a/vite.config.ts b/vite.config.ts index fd98727..48fb66f 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -83,16 +83,31 @@ export default defineConfig(({mode}: { mode: string }): object => { ], }), AutoImport({ - //安装两行后你会发现在组件中不用再导入ref,reactive等 + include: [ + /\.[tj]sx?$/, // .ts, .tsx, .js, .jsx + /\.vue$/, + /\.vue\?vue/, // .vue + /\.md$/, // .md + ], imports: ['vue', 'vue-router', 'pinia', '@vueuse/core'], - dts: 'auto-import.d.ts', + dts: './auto-import.d.ts', + defaultExportByFilename: true, + dirsScanOptions: { + types: true + }, + vueTemplate: true, + vueDirectives: true, + viteOptimizeDeps: true, + injectAtEnd: true, //ant-design-vue resolvers: [AntDesignVueResolver({ importStyle: false, resolveIcons: true })], eslintrc: { - enabled: false // 1、改为true用于生成eslint配置。2、生成后改回false,避免重复生成消耗 + enabled: false, + filepath: './.eslintrc-auto-import.json', + globalsPropValue: true } }), nodePolyfills(),