✨ add image upscale
8
components.d.ts
vendored
@@ -47,6 +47,8 @@ declare module 'vue' {
|
||||
ARadio: typeof import('ant-design-vue/es')['Radio']
|
||||
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
|
||||
ARow: typeof import('ant-design-vue/es')['Row']
|
||||
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
||||
ASkeleton: typeof import('ant-design-vue/es')['Skeleton']
|
||||
ASpace: typeof import('ant-design-vue/es')['Space']
|
||||
ASpin: typeof import('ant-design-vue/es')['Spin']
|
||||
@@ -57,6 +59,7 @@ declare module 'vue' {
|
||||
ATextarea: typeof import('ant-design-vue/es')['Textarea']
|
||||
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
||||
AUpload: typeof import('ant-design-vue/es')['Upload']
|
||||
AUploadDragger: typeof import('ant-design-vue/es')['UploadDragger']
|
||||
Avatar: typeof import('./src/components/MyUI/Avatar/Avatar.vue')['default']
|
||||
BackgroundAnimation: typeof import('./src/components/BackgroundAnimation/BackgroundAnimation.vue')['default']
|
||||
BackTop: typeof import('./src/components/MyUI/BackTop/BackTop.vue')['default']
|
||||
@@ -74,6 +77,7 @@ declare module 'vue' {
|
||||
CloseCircleOutlined: typeof import('@ant-design/icons-vue')['CloseCircleOutlined']
|
||||
Clouds: typeof import('./src/components/Clouds/Clouds.vue')['default']
|
||||
CloudServerOutlined: typeof import('@ant-design/icons-vue')['CloudServerOutlined']
|
||||
CloudUploadOutlined: typeof import('@ant-design/icons-vue')['CloudUploadOutlined']
|
||||
Col: typeof import('./src/components/MyUI/Grid/Col.vue')['default']
|
||||
Collapse: typeof import('./src/components/MyUI/Collapse/Collapse.vue')['default']
|
||||
CommentInput: typeof import('./src/components/CommentReply/src/CommentInput/CommentInput.vue')['default']
|
||||
@@ -81,6 +85,7 @@ declare module 'vue' {
|
||||
CommentOutlined: typeof import('@ant-design/icons-vue')['CommentOutlined']
|
||||
CommentReply: typeof import('./src/components/CommentReply/index.vue')['default']
|
||||
CompareImage: typeof import('./src/components/ImageCompare/CompareImage.vue')['default']
|
||||
CompareResult: typeof import('./src/views/Upscale/CompareResult.vue')['default']
|
||||
Countdown: typeof import('./src/components/MyUI/Countdown/Countdown.vue')['default']
|
||||
CustomerServiceOutlined: typeof import('@ant-design/icons-vue')['CustomerServiceOutlined']
|
||||
DatePicker: typeof import('./src/components/MyUI/DatePicker/DatePicker.vue')['default']
|
||||
@@ -104,6 +109,7 @@ declare module 'vue' {
|
||||
ImageCompare: typeof import('./src/components/ImageCompare/ImageCompare.vue')['default']
|
||||
ImageInPainting: typeof import('./src/views/Upscale/Upscale.vue')['default']
|
||||
ImageShare: typeof import('./src/views/ImageShare/ImageShare.vue')['default']
|
||||
InboxOutlined: typeof import('@ant-design/icons-vue')['InboxOutlined']
|
||||
Input: typeof import('./src/components/MyUI/Input/Input.vue')['default']
|
||||
InputSearch: typeof import('./src/components/MyUI/InputSearch/InputSearch.vue')['default']
|
||||
LandingPage: typeof import('./src/views/Landing/LandingPage.vue')['default']
|
||||
@@ -140,6 +146,7 @@ declare module 'vue' {
|
||||
ReplyInput: typeof import('./src/components/CommentReply/src/ReplyInput/ReplyInput.vue')['default']
|
||||
ReplyList: typeof import('./src/components/CommentReply/src/ReplyList/ReplyList.vue')['default']
|
||||
ReplyReply: typeof import('./src/components/CommentReply/src/ReplyReplyInput/ReplyReply.vue')['default']
|
||||
RestOutlined: typeof import('@ant-design/icons-vue')['RestOutlined']
|
||||
Result: typeof import('./src/components/MyUI/Result/Result.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
@@ -174,6 +181,7 @@ declare module 'vue' {
|
||||
TreeChart: typeof import('./src/components/MyUI/TreeChart/TreeChart.vue')['default']
|
||||
UngroupOutlined: typeof import('@ant-design/icons-vue')['UngroupOutlined']
|
||||
Upload: typeof import('./src/components/MyUI/Upload/Upload.vue')['default']
|
||||
UploadImage: typeof import('./src/views/Upscale/UploadImage.vue')['default']
|
||||
Upscale: typeof import('./src/views/Upscale/Upscale.vue')['default']
|
||||
UserInfoCard: typeof import('./src/components/CommentReply/src/UserInfoCard/UserInfoCard.vue')['default']
|
||||
UserOutlined: typeof import('@ant-design/icons-vue')['UserOutlined']
|
||||
|
@@ -42,7 +42,7 @@
|
||||
"nprogress": "^0.2.0",
|
||||
"nsfwjs": "^4.2.1",
|
||||
"pinia": "^2.3.0",
|
||||
"pinia-plugin-persistedstate": "^4.1.3",
|
||||
"pinia-plugin-persistedstate-2": "^2.0.27",
|
||||
"qrcode": "^1",
|
||||
"seedrandom": "^3.0.5",
|
||||
"swiper": "^11.1.15",
|
||||
@@ -63,7 +63,7 @@
|
||||
"globals": "^15.13.0",
|
||||
"sass": "^1.82.0",
|
||||
"typescript": "^5.7.2",
|
||||
"typescript-eslint": "^8.17.0",
|
||||
"typescript-eslint": "^8.18.0",
|
||||
"unplugin-vue-components": "^0.27.5",
|
||||
"vite": "^6.0.3",
|
||||
"vite-plugin-bundle-obfuscator": "1.3.2",
|
||||
|
1
src/assets/svgs/download.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1733799768960" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="34134" width="200" height="200"><path d="M514 912c-219.9 0-398.9-178.9-398.9-398.8S294 114.3 514 114.3c219.9 0 398.8 178.9 398.8 398.9C912.8 733.1 733.9 912 514 912z m0-701.5c-166.9 0-302.7 135.8-302.7 302.7S347.1 815.9 514 815.9s302.7-135.8 302.7-302.7S680.9 210.5 514 210.5z" fill="#BDD2EF" p-id="34135"></path><path d="M555.6 642l164.1-164.1c22.9-22.9 22.9-60.2 0-83.1-22.9-22.9-60.2-22.9-83.1 0l-63.8 63.8V229.9c0-32.5-26.3-58.8-58.8-58.8s-58.8 26.3-58.8 58.8v228.7l-63.8-63.8c-11.5-11.5-26.5-17.2-41.5-17.2s-30.1 5.7-41.5 17.2c-22.9 22.9-22.9 60.2 0 83.1L472.5 642c22.9 23 60.1 23 83.1 0z" fill="#2867CE" p-id="34136"></path><path d="M679.5 714H351c-14.8 0-26.7-12-26.7-26.7s12-26.7 26.7-26.7h328.5c14.8 0 26.7 12 26.7 26.7S694.3 714 679.5 714z" fill="#2867CE" p-id="34137"></path></svg>
|
After Width: | Height: | Size: 908 B |
1
src/assets/svgs/empty.svg
Normal file
After Width: | Height: | Size: 6.2 KiB |
@@ -1 +1 @@
|
||||
<svg t="1733393188492" class="icon" viewBox="0 0 1089 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="28883" width="200" height="200"><path d="M32.628594 863.170688C16.851704 625.805116 30.306304 391.05104 79.527611 158.550188c14.563947-54.20689 67.726238-104.222436 115.596472-109.587873 184.237813-19.506365 368.475627-23.965333 552.71344-13.376903 47.883184 2.917969 96.116007 52.786754 105.543292 109.337514a2391.284402 2391.284402 0 0 1-9.535198 112.225269" fill="#F2C84B" p-id="28884"></path><path d="M626.86698 252.343905c116.835315 1.044598 233.670629 4.584147 350.505944 10.610013 56.870184 3.306456 98.951962 49.454398 89.244103 103.005176-29.352353 157.389043-82.488745 322.711855-144.888395 493.123847-21.440167 58.19104-92.377898 110.904413-156.193366 114.146121-213.957071 10.756774-427.914142 5.244575-641.871213-16.540914-63.828418-6.923702-103.18647-57.064427-84.8283-110.68427 52.670208-155.040855 118.971993-317.49318 186.400391-483.398722 23.861736-57.737805 77.891649-106.812349 119.977743-107.956228 42.457315-1.083447 77.196688-1.58848 77.196688-1.592796" fill="#FFE287" p-id="28885"></path><path d="M540.53653 511.784174m-80.42113 0a80.421131 80.421131 0 1 0 160.842261 0 80.421131 80.421131 0 1 0-160.842261 0Z" opacity=".4" p-id="28886"></path><path d="M683.163067 873.206603c55.229905 0 114.957627-36.781088 132.737383-81.73767l88.903098-224.813125c17.771123-44.952265-2.874804-57.370901-45.888951-27.578262l-203.019003 140.580504c-43.005514 29.784005-99.931812 33.478949-126.495692 8.201393-26.559563-25.277556-81.767886-19.868953-122.684202 12.038781l-147.871112 115.298633c-40.916317 31.903418-29.196958 58.001113 26.037264 58.001113l398.281215 0.008633z" opacity=".4" p-id="28887"></path></svg>
|
||||
<svg t="1733731565547" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14899" width="200" height="200"><path d="M235.466 195.356v249.398H39.548v-179.51c0-38.59 31.296-69.888 69.888-69.888h35.726z" fill="#BED8FB" p-id="14900"></path><path d="M984.44 393.056v548.778c0 45.39-36.756 82.166-82.126 82.166H227.34c-29.072 0-54.6-15.102-69.208-37.87a81.72 81.72 0 0 1-10.714-25.136l-0.308-46.976-1.916-279.756V82.166C145.194 36.778 181.972 0 227.34 0h364.066c32.718 0 138.662 90.348 232.326 185.494 85.486 86.844 160.708 177.686 160.708 207.562z" fill="#DDEAFB" p-id="14901"></path><path d="M984.452 393.056v201.03c0-0.226-0.02-0.454-0.02-0.7C978.25 346.72 777.324 335.306 711.62 269.6l112.124-84.104c85.464 86.842 160.708 177.684 160.708 207.56z" fill="#CBE2FF" p-id="14902"></path><path d="M591.386 0H390.356c0.226 0 0.454 0.02 0.7 0.02 246.666 6.182 258.08 207.108 323.786 272.812l84.104-112.124C712.102 75.244 621.26 0 591.386 0z" fill="#CBE2FF" p-id="14903"></path><path d="M984.45 393.066v34.754c0-73.172-59.336-132.506-132.506-132.506h-80.648c-45.368 0-82.162-36.794-82.162-82.162V132.506C689.134 59.334 629.8 0 556.628 0h34.754c62.58 0 122.616 24.866 166.866 69.114l157.086 157.086a236.008 236.008 0 0 1 69.116 166.866zM701.41 693.93v184.278c0 59.606-48.316 107.922-107.922 107.922H158.132a81.72 81.72 0 0 1-10.714-25.136l-0.308-46.976-1.916-279.756v-48.254h448.294c59.606 0 107.922 48.316 107.922 107.922z" fill="#BED8FB" p-id="14904"></path><path d="M771.298 443.052v375.384c0 59.606-48.316 107.922-107.922 107.922H109.448c-2.08 0-4.12-0.082-6.16-0.288-35.706-3.09-63.726-33.068-63.726-69.6V265.244c0 19.286 7.83 36.756 20.48 49.408 11.27 11.29 26.394 18.75 43.246 20.192 2.04 0.206 4.08 0.288 6.16 0.288h553.928c59.608-0.002 107.922 48.314 107.922 107.92z" fill="#617881" p-id="14905"></path><path d="M668.278 492.9v275.676c0 5.068-0.68 9.972-1.978 14.608-6.388 23.158-27.608 40.156-52.786 40.156H192.438a49.648 49.648 0 0 1-39.106-18.956 49.52 49.52 0 0 1-10.756-30.906V487.996c0-27.526 22.314-49.84 49.86-49.84h421.076c30.248 0 54.766 24.52 54.766 54.744z" fill="#80B4FB" p-id="14906"></path><path d="M277.946 558.042m-53.742 0a53.742 53.742 0 1 0 107.484 0 53.742 53.742 0 1 0-107.484 0Z" fill="#F1D333" p-id="14907"></path><path d="M411.228 823.342H192.438a49.648 49.648 0 0 1-39.106-18.956l119.11-114.844z" fill="#EAB14D" p-id="14908"></path><path d="M666.3 783.186c-6.388 23.158-27.608 40.156-52.786 40.156H314.06l196.93-189.904z" fill="#F1D333" p-id="14909"></path><path d="M103.288 334.842v591.228c-35.706-3.09-63.726-33.068-63.726-69.6V265.244c0 19.286 7.83 36.756 20.48 49.408 11.27 11.29 26.392 18.748 43.246 20.19z" fill="#475959" p-id="14910"></path></svg>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.7 KiB |
1
src/assets/svgs/package-download.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1733800047141" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="39002" width="200" height="200"><path d="M737.882353 584.282353c0 48.188235-39.152941 84.329412-84.329412 84.329412h-286.117647c-48.188235 0-84.329412-39.152941-84.329412-84.329412v-150.588235c0-48.188235 39.152941-84.329412 84.329412-84.329412 12.047059 0 21.082353 9.035294 21.082353 21.082353 0 12.047059-9.035294 21.082353-21.082353 21.082353-24.094118 0-42.164706 18.070588-42.164706 42.164706v150.588235c0 24.094118 18.070588 42.164706 42.164706 42.164706h286.117647c24.094118 0 42.164706-18.070588 42.164706-42.164706v-150.588235c0-24.094118-18.070588-42.164706-42.164706-42.164706-12.047059 0-21.082353-9.035294-21.082353-21.082353 0-12.047059 9.035294-21.082353 21.082353-21.082353 48.188235 0 84.329412 39.152941 84.329412 84.329412v150.588235z m-307.2-87.341177c0 18.070588-15.058824 33.129412-33.129412 33.129412-18.070588 0-33.129412-15.058824-33.129412-33.129412 0-18.070588 15.058824-33.129412 33.129412-33.129411 21.082353 3.011765 33.129412 15.058824 33.129412 33.129411z m78.305882-30.117647c18.070588 0 33.129412 15.058824 33.129412 33.129412 0 18.070588-15.058824 33.129412-33.129412 33.129412s-33.129412-15.058824-33.129411-33.129412c3.011765-21.082353 18.070588-33.129412 33.129411-33.129412z m51.2-189.741176c18.070588 0 33.129412 15.058824 33.129412 33.129412s-15.058824 33.129412-33.129412 33.129411-33.129412-15.058824-33.129411-33.129411 18.070588-33.129412 33.129411-33.129412zM508.988235 30.117647C243.952941 30.117647 27.105882 246.964706 27.105882 512s216.847059 481.882353 481.882353 481.882353 481.882353-216.847059 481.882353-481.882353-213.835294-481.882353-481.882353-481.882353z" fill="#7B9CFF" p-id="39003"></path></svg>
|
After Width: | Height: | Size: 1.7 KiB |
1
src/assets/svgs/qr-phone.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1733761095875" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="50680" width="200" height="200"><path d="M471.87259 871.430008a41.629505 41.629505 0 0 0 41.629506 41.629506 40.98575 40.98575 0 0 0 38.625314-41.629506 40.55658 40.55658 0 0 0-39.912825-40.98575h-1.072925a40.98575 40.98575 0 0 0-39.26907 40.98575z" fill="#B8BDCC" p-id="50681"></path><path d="M738.601844 55.792121a77.036044 77.036044 0 0 1 77.036044 77.036043v758.343672a77.036044 77.036044 0 0 1-77.036044 77.036043H285.398156a77.036044 77.036044 0 0 1-77.036044-77.036043V132.828164A77.036044 77.036044 0 0 1 285.398156 55.792121h453.203688m0-55.792121H285.398156A132.828164 132.828164 0 0 0 152.569992 132.828164v758.343672a132.828164 132.828164 0 0 0 132.828164 132.828164h453.203688a132.828164 132.828164 0 0 0 132.828164-132.828164V132.828164A132.828164 132.828164 0 0 0 738.601844 0z" fill="#B8BDCC" p-id="50682"></path><path d="M713.49539 793.964795H310.50461a39.483655 39.483655 0 0 1-41.629505-36.694049v-519.295893a39.26907 39.26907 0 0 1 41.629505-36.479463h402.99078a39.26907 39.26907 0 0 1 41.629505 36.479463v518.437553A39.483655 39.483655 0 0 1 713.49539 793.964795z" fill="#E3E5EB" p-id="50683"></path><path d="M425.736798 103.430008m25.964795 0l120.596814 0q25.964795 0 25.964795 25.964795l0 0q0 25.964795-25.964795 25.964795l-120.596814 0q-25.964795 0-25.964795-25.964795l0 0q0-25.964795 25.964795-25.964795Z" fill="#B8BDCC" p-id="50684"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
1
src/assets/svgs/remove.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1733762218316" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="53040" width="200" height="200"><path d="M514.5 511.5m-434.5 0a434.5 434.5 0 1 0 869 0 434.5 434.5 0 1 0-869 0Z" fill="#DB3131" p-id="53041"></path><path d="M453.13 319c14.68-0.64 39.84-1.5 68.42-1.5 28.21 0 53.61 0.87 68.42 1.51a13 13 0 0 0 13.59-13 82 82 0 0 0-82-82 82 82 0 0 0-82 82A13 13 0 0 0 453.13 319zM750.24 371l-61-4.87c-51.18-4.09-121.36-5.93-168.19-5.9-46.66 0-116.49 1.84-167.3 5.9L292.86 371a31.38 31.38 0 1 0 5 62.57l40-3.2a38.64 38.64 0 0 0-0.28 5.92c2.28 74.62 14.47 236.63 15.5 249.25l2 24.2c3.09 37.81 33.75 67.84 72.36 70.87l24.71 1.93c21.46 1.68 49.6 2.52 71.12 2.51s49.39-0.84 70.73-2.51l25.1-1.92c39.34-3 70.36-34 72.62-72.61l1.28-22.52c1-12.62 13.22-174.63 15.5-249.26a38.08 38.08 0 0 0-0.25-5.67l37 3c0.85 0.07 1.7 0.1 2.54 0.1a31.38 31.38 0 0 0 2.45-62.66zM459.83 716c-0.8 0.06-1.6 0.1-2.39 0.1a27.47 27.47 0 0 1-27.33-25.1c-1.16-13.46-8.79-164.6-8.79-189.52a27.46 27.46 0 0 1 54.92 0c0 24.21 7.66 173.94 8.59 184.8a27.47 27.47 0 0 1-25 29.72z m155.45-25A27.47 27.47 0 0 1 588 716.08c-0.79 0-1.59 0-2.39-0.1a27.46 27.46 0 0 1-25-29.72c1.6-18.63 8.59-168.89 8.59-184.8a27.46 27.46 0 0 1 54.92 0c-0.05 19.45-7.36 172.33-8.84 189.54z" fill="#FFFFFF" p-id="53042"></path></svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
src/assets/svgs/run.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1733748093314" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3982" width="200" height="200"><path d="M170.666667 0h682.666666c93.866667 0 170.666667 76.8 170.666667 170.666667v682.666666c0 93.866667-76.8 170.666667-170.666667 170.666667H170.666667c-93.866667 0-170.666667-76.8-170.666667-170.666667V170.666667c0-93.866667 76.8-170.666667 170.666667-170.666667z" fill="#32B84C" opacity=".2" p-id="3983"></path><path d="M200.533333 72.533333h622.933334c72.533333 0 128 55.466667 128 128v622.933334c0 72.533333-55.466667 128-128 128H200.533333c-72.533333 0-128-55.466667-128-128V200.533333c0-68.266667 59.733333-128 128-128z" fill="#32B84C" opacity=".3" p-id="3984"></path><path d="M230.4 145.066667h558.933333c46.933333 0 85.333333 38.4 85.333334 85.333333v558.933333c0 46.933333-38.4 85.333333-85.333334 85.333334H230.4c-46.933333 0-85.333333-38.4-85.333333-85.333334V230.4c0-46.933333 38.4-85.333333 85.333333-85.333333z" fill="#32B84C" opacity=".38" p-id="3985"></path><path d="M669.866667 537.6l-234.666667 149.333333c-29.866667 21.333333-68.266667-8.533333-68.266667-42.666666V341.333333c0-34.133333 38.4-64 68.266667-42.666666l234.666667 149.333333c34.133333 21.333333 34.133333 68.266667 0 89.6" fill="#26AE40" p-id="3986"></path></svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
src/assets/svgs/save.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1733799474807" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="32161" width="200" height="200"><path d="M826.026667 314.026667l-114.346667-114.346667c-29.013333-29.013333-68.266667-44.373333-109.226667-44.373333H256c-56.32 0-102.4 46.08-102.4 102.4v512c0 56.32 46.08 102.4 102.4 102.4h512c56.32 0 102.4-46.08 102.4-102.4V421.546667c0-40.96-15.36-78.506667-44.373333-107.52zM204.8 409.6h460.8v307.2H204.8V409.6z m614.4 358.4c0 29.013333-22.186667 51.2-51.2 51.2H256c-29.013333 0-51.2-22.186667-51.2-51.2h494.933333c10.24 0 17.066667-6.826667 17.066667-17.066667V375.466667c0-10.24-6.826667-17.066667-17.066667-17.066667H204.8v-102.4c0-29.013333 22.186667-51.2 51.2-51.2h346.453333c27.306667 0 52.906667 10.24 71.68 30.72l114.346667 114.346667c18.773333 18.773333 30.72 44.373333 30.72 71.68V768z" fill="#335056" p-id="32162"></path><path d="M256 256h204.8v51.2H256zM563.2 512h51.2v102.4h-51.2z" fill="#335056" p-id="32163"></path><path d="M204.8 409.6v307.2h460.8V409.6H204.8z m409.6 204.8h-51.2v-102.4h51.2v102.4z" fill="#78BDCC" p-id="32164"></path></svg>
|
After Width: | Height: | Size: 1.1 KiB |
@@ -6,12 +6,13 @@ import router from "@/router/router.ts";
|
||||
import "go-captcha-vue/dist/style.css";
|
||||
import GoCaptcha from "go-captcha-vue";
|
||||
import {createPinia, Pinia} from "pinia";
|
||||
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
|
||||
import {createPersistedStatePlugin} from 'pinia-plugin-persistedstate-2';
|
||||
import VueDOMPurifyHTML from 'vue-dompurify-html';
|
||||
import {registerDirectives} from "@/directives";
|
||||
|
||||
const pinia: Pinia = createPinia();
|
||||
pinia.use(piniaPluginPersistedstate);
|
||||
const installPersistedStatePlugin = createPersistedStatePlugin();
|
||||
pinia.use((context) => installPersistedStatePlugin(context));
|
||||
const app = createApp(App);
|
||||
registerDirectives(app);
|
||||
app.use(pinia);
|
||||
|
@@ -3,6 +3,7 @@ import {useThemeStore} from "@/store/modules/themeStore.ts";
|
||||
import {langStore} from "@/store/modules/langStore.ts";
|
||||
import {useCommentStore} from "@/store/modules/commentStore.ts";
|
||||
import {useWebSocketStore} from "@/store/modules/websocketStore.ts";
|
||||
import {useUpscaleStore} from "@/store/modules/upscaleStore.ts";
|
||||
|
||||
export default function useStore() {
|
||||
return {
|
||||
@@ -11,5 +12,6 @@ export default function useStore() {
|
||||
lang: langStore(),
|
||||
comment: useCommentStore(),
|
||||
websocket: useWebSocketStore(),
|
||||
upscale: useUpscaleStore(),
|
||||
};
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@ import QQ_EMOJI from "@/constant/qq_emoji.ts";
|
||||
import {initNSFWJs, predictNSFW} from "@/utils/nsfw/nsfw.ts";
|
||||
import {NSFWJS} from "nsfwjs";
|
||||
import i18n from "@/locales";
|
||||
import localForage from "localforage";
|
||||
|
||||
export const useCommentStore = defineStore(
|
||||
'comment',
|
||||
@@ -325,10 +326,16 @@ export const useCommentStore = defineStore(
|
||||
},
|
||||
{
|
||||
// 开启数据持久化
|
||||
persist: {
|
||||
// persist: {
|
||||
// key: 'comment',
|
||||
// storage: localStorage,
|
||||
// pick: ["emojiList", "commentList", "replyVisibility", "commentMap"],
|
||||
// }
|
||||
persistedState: {
|
||||
persist: true,
|
||||
storage: localForage,
|
||||
key: 'comment',
|
||||
storage: localStorage,
|
||||
pick: ["emojiList", "commentList", "replyVisibility", "commentMap"],
|
||||
includePaths: ["emojiList", "commentList", "replyVisibility", "commentMap"]
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import {defineStore} from 'pinia';
|
||||
import {ref} from "vue";
|
||||
|
||||
|
||||
export const langStore = defineStore(
|
||||
'lang',
|
||||
() => {
|
||||
@@ -11,10 +12,11 @@ export const langStore = defineStore(
|
||||
},
|
||||
{
|
||||
// 开启数据持久化
|
||||
persist: {
|
||||
key: 'lang',
|
||||
persistedState: {
|
||||
persist: true,
|
||||
storage: localStorage,
|
||||
pick: ["lang"],
|
||||
key: 'lang',
|
||||
includePaths: ['lang']
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@@ -37,10 +37,11 @@ export const useThemeStore = defineStore(
|
||||
return {themeName, themeConfig, darkMode, setThemeName, toggleDarkMode};
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
key: 'theme',
|
||||
persistedState: {
|
||||
persist: true,
|
||||
storage: localStorage,
|
||||
pick: ["themeName", "darkMode"],
|
||||
key: 'theme',
|
||||
includePaths: ['themeName', 'darkMode']
|
||||
}
|
||||
}
|
||||
);
|
||||
|
88
src/store/modules/upscaleStore.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import {defineStore} from 'pinia';
|
||||
import {initNSFWJs, predictNSFW} from "@/utils/nsfw/nsfw.ts";
|
||||
import i18n from "@/locales";
|
||||
import message from "@/components/MyUI/Message/Message.vue";
|
||||
import {NSFWJS} from "nsfwjs";
|
||||
import localForage from "localforage";
|
||||
|
||||
export const useUpscaleStore = defineStore(
|
||||
'upscale',
|
||||
() => {
|
||||
const imageList = ref<string[]>([]);
|
||||
const fileList = ref<string[]>([]);
|
||||
const uploading = ref<boolean>(false);
|
||||
|
||||
/**
|
||||
* 图片上传前的校验
|
||||
* @param file
|
||||
*/
|
||||
async function beforeUpload(file: any) {
|
||||
if (fileList.value.length >= 5) {
|
||||
return false;
|
||||
}
|
||||
uploading.value = true;
|
||||
if (!window.FileReader) return false;
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file); // 文件转换
|
||||
reader.onloadend = async function () {
|
||||
const img: HTMLImageElement = document.createElement('img');
|
||||
img.src = reader.result as string;
|
||||
img.onload = async () => {
|
||||
// 图片 NSFW 检测
|
||||
const nsfw: NSFWJS = await initNSFWJs();
|
||||
const isNSFW: boolean = await predictNSFW(nsfw, img);
|
||||
if (isNSFW) {
|
||||
message.error(i18n.global.t('comment.illegalImage'));
|
||||
fileList.value.pop();
|
||||
return false;
|
||||
}
|
||||
fileList.value.push(img.src);
|
||||
};
|
||||
|
||||
uploading.value = false;
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义上传图片请求
|
||||
*/
|
||||
async function customUploadRequest() {
|
||||
imageList.value = fileList.value;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除图片
|
||||
* @param index
|
||||
*/
|
||||
async function removeImage(index: number) {
|
||||
fileList.value.splice(index, 1);
|
||||
imageList.value.splice(index, 1);
|
||||
}
|
||||
|
||||
return {
|
||||
imageList,
|
||||
fileList,
|
||||
uploading,
|
||||
beforeUpload,
|
||||
customUploadRequest,
|
||||
removeImage
|
||||
};
|
||||
}
|
||||
|
||||
,
|
||||
{
|
||||
// 开启数据持久化
|
||||
persistedState: {
|
||||
persist: true,
|
||||
storage:
|
||||
localForage,
|
||||
key:
|
||||
'upscale',
|
||||
includePaths:
|
||||
['imageList', 'fileList']
|
||||
}
|
||||
}
|
||||
)
|
||||
;
|
@@ -144,10 +144,16 @@ export const useAuthStore = defineStore(
|
||||
},
|
||||
{
|
||||
// 开启数据持久化
|
||||
persist: {
|
||||
key: 'user',
|
||||
// persist: {
|
||||
// key: 'user',
|
||||
// storage: localStorage,
|
||||
// pick: ['user', "clientId", "githubRedirectUrl", "giteeRedirectUrl", "qqRedirectUrl"],
|
||||
// }
|
||||
persistedState: {
|
||||
persist: true,
|
||||
storage: localStorage,
|
||||
pick: ['user', "clientId", "githubRedirectUrl", "giteeRedirectUrl", "qqRedirectUrl"],
|
||||
key: 'user',
|
||||
includePaths: ['user', "clientId", "githubRedirectUrl", "giteeRedirectUrl", "qqRedirectUrl"]
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@@ -49,5 +49,7 @@ export const useWebSocketStore = defineStore('websocket', () => {
|
||||
getReadyState
|
||||
};
|
||||
}, {
|
||||
persist: false,
|
||||
persistedState: {
|
||||
persist: false,
|
||||
}
|
||||
});
|
||||
|
@@ -9,7 +9,7 @@ let isInit: boolean = false;
|
||||
const initNSFWJs = async (): Promise<NSFWJS> => {
|
||||
tf.enableProdMode();
|
||||
if (!isInit) {
|
||||
const initialLoad: nsfwjs.NSFWJS = await nsfwjs.load("/nsfw/model/mobilenet_v2_mid/", {
|
||||
const initialLoad: nsfwjs.NSFWJS = await nsfwjs.load("/nsfw/mobilenet_v2_mid/", {
|
||||
size: 224,
|
||||
type: "graph"
|
||||
});
|
||||
|
@@ -3,23 +3,20 @@
|
||||
flex-direction: column;
|
||||
background-color: #eaeef6;
|
||||
color: var(--text-color);
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
|
||||
.main-header {
|
||||
|
||||
}
|
||||
width: 100vw;
|
||||
|
||||
.main-content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
height: calc(100vh - 70px);
|
||||
|
||||
.main-content-container {
|
||||
width: calc(100% - 230px);
|
||||
height: calc(100% - 110px);
|
||||
padding: 20px;
|
||||
overflow: scroll;
|
||||
|
||||
width: calc(100vw - 230px);
|
||||
height: calc(100vh - 100px);
|
||||
max-height: calc(100vh - 100px);
|
||||
padding: 15px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
}
|
||||
|
184
src/views/Upscale/CompareResult.vue
Normal file
@@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<div class="upscale-comparison-result">
|
||||
<div class="upscale-comparison-top">
|
||||
<div class="upscale-comparison-top-left">
|
||||
|
||||
<VueCompareImage :left-image="bg" :right-image="bg2"
|
||||
style="width: 45vw; height: 60vh;border-radius: 10px;box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);"
|
||||
rightImageLabel="修复后"
|
||||
leftImageLabel="原图"
|
||||
/>
|
||||
|
||||
</div>
|
||||
<div class="upscale-comparison-top-right" ref="avatarContainer">
|
||||
<ABadge style="margin-top: 5px;" v-for="(item, index) in upscale.imageList"
|
||||
:key="index">
|
||||
<template #count>
|
||||
<AButton type="text" size="small" class="upscale-file-btn" @click="upscale.removeImage(index)">
|
||||
<template #icon>
|
||||
<AAvatar shape="square" :size="20" :src="remove"/>
|
||||
</template>
|
||||
</AButton>
|
||||
</template>
|
||||
<AAvatar shape="square" :size="avatarSize" @click="bg = item">
|
||||
<template #icon>
|
||||
<AImage :src="item" width="100%" height="100%" :preview="true"/>
|
||||
</template>
|
||||
</AAvatar>
|
||||
</ABadge>
|
||||
</div>
|
||||
</div>
|
||||
<ADivider orientation="center" :plain="true"><span class="upscale-comparison-divider-text">保存下载</span>
|
||||
</ADivider>
|
||||
<div class="upscale-comparison-bottom">
|
||||
<AFlex :vertical="false" align="center" justify="space-between" gap="large">
|
||||
<AButton type="text" size="large" style="width: 50px; height: 50px;">
|
||||
<template #icon>
|
||||
<AAvatar shape="square" :size="40" :src="download"/>
|
||||
</template>
|
||||
</AButton>
|
||||
<AButton type="text" style="width: 50px; height: 50px;">
|
||||
<template #icon>
|
||||
<AAvatar shape="square" :size="40" :src="save"/>
|
||||
</template>
|
||||
</AButton>
|
||||
<AButton type="text" style="width: 50px; height: 50px;">
|
||||
<template #icon>
|
||||
<AAvatar shape="square" :size="35" :src="share"/>
|
||||
</template>
|
||||
</AButton>
|
||||
<AButton type="text" style="width: 50px; height: 50px;">
|
||||
<template #icon>
|
||||
<AAvatar shape="square" :size="35" :src="packageDownload"/>
|
||||
</template>
|
||||
</AButton>
|
||||
</AFlex>
|
||||
<ADivider type="vertical" style="height: 30px;"/>
|
||||
<AFlex :vertical="false" align="center" justify="space-between" gap="large" style="margin-left: 1%">
|
||||
<AFlex :vertical="true" align="flex-start" justify="flex-start" gap="small">
|
||||
<AFlex :vertical="false" align="center" justify="space-between">
|
||||
<span class="upscale-comparison-bottom-text">处理数量:</span>
|
||||
<ATag color="orange">{{ 5 }}</ATag>
|
||||
</AFlex>
|
||||
<AFlex :vertical="false" align="center" justify="space-between">
|
||||
<span class="upscale-comparison-bottom-text">处理大小:</span>
|
||||
<ATag color="green">{{ upscale.imageList.length }} /mb</ATag>
|
||||
|
||||
</AFlex>
|
||||
</AFlex>
|
||||
<AFlex :vertical="true" align="flex-start" justify="center" gap="small">
|
||||
<AFlex :vertical="false" align="center" justify="space-between">
|
||||
<span class="upscale-comparison-bottom-text">消耗时间:</span>
|
||||
<ATag color="cyan">{{ upscale.imageList.length }} /s</ATag>
|
||||
</AFlex>
|
||||
<AFlex :vertical="false" align="center" justify="space-between">
|
||||
<span class="upscale-comparison-bottom-text">内存消耗:</span>
|
||||
<ATag color="purple">{{ upscale.imageList.length }} /mb</ATag>
|
||||
</AFlex>
|
||||
</AFlex>
|
||||
</AFlex>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
import {VueCompareImage} from "@/components/VueCompareImage";
|
||||
import bg1 from "@/assets/images/background.jpg";
|
||||
import bg2 from "@/assets/images/background.png";
|
||||
import useStore from "@/store";
|
||||
import remove from "@/assets/svgs/remove.svg";
|
||||
import download from "@/assets/svgs/download.svg";
|
||||
import save from "@/assets/svgs/save.svg";
|
||||
import share from "@/assets/svgs/share.svg";
|
||||
import packageDownload from "@/assets/svgs/package-download.svg";
|
||||
|
||||
const upscale = useStore().upscale;
|
||||
const avatarSize = ref<number>(60);
|
||||
const avatarContainer = ref<HTMLDivElement | null>();
|
||||
const bg = ref<string>(bg1);
|
||||
|
||||
|
||||
/**
|
||||
* 更新大小
|
||||
*/
|
||||
const updateSize = () => {
|
||||
if (avatarContainer.value) {
|
||||
// 设置图片列表大小
|
||||
const container = avatarContainer.value?.clientWidth || 0;
|
||||
avatarSize.value = Math.min(0.7 * container, 300); // 设置头像大小为容器宽度的10%,最大不超过100
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
updateSize();
|
||||
window.addEventListener('resize', updateSize);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('resize', updateSize);
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.upscale-comparison-result {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.upscale-comparison-top {
|
||||
width: 100%;
|
||||
height: 80%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
|
||||
.upscale-comparison-top-left {
|
||||
width: 85%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.upscale-comparison-image {
|
||||
width: 40vw;
|
||||
height: 60vh;
|
||||
}
|
||||
}
|
||||
|
||||
.upscale-comparison-top-right {
|
||||
width: 14%;
|
||||
height: 60vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
overflow-y: scroll;
|
||||
border: 1px solid rgba(126, 126, 135, 0.48);
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.upscale-comparison-divider-text {
|
||||
font-size: 13px;
|
||||
color: rgba(126, 126, 135, 0.99);
|
||||
}
|
||||
|
||||
.upscale-comparison-bottom {
|
||||
width: 100%;
|
||||
height: 20%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
|
||||
.upscale-comparison-bottom-text {
|
||||
font-size: 13px;
|
||||
color: rgba(126, 126, 135, 0.99);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
211
src/views/Upscale/UploadImage.vue
Normal file
@@ -0,0 +1,211 @@
|
||||
<template>
|
||||
<div class="upscale-upload-container">
|
||||
<div class="upscale-upload-content">
|
||||
<Spin :spinning="upscale.uploading" indicator="magic-ring">
|
||||
<AUploadDragger
|
||||
name="image"
|
||||
accept="image/*"
|
||||
:multiple="false"
|
||||
:directory="false"
|
||||
:maxCount="5"
|
||||
:beforeUpload="upscale.beforeUpload"
|
||||
:custom-request="upscale.customUploadRequest"
|
||||
:disabled="upscale.uploading"
|
||||
:showUploadList="false">
|
||||
<div class="upscale-upload-content-main">
|
||||
<div class="upscale-upload-content-left">
|
||||
<ABadge :count="upscale.imageList.length" :offset="[-10, 10]">
|
||||
<AAvatar shape="square" :size="70" :src="file"/>
|
||||
</ABadge>
|
||||
<span class="upscale-upload-text">
|
||||
点击或拖拽上传图片
|
||||
</span>
|
||||
<span class="upscale-upload-tip">最多一次处理5张图片</span>
|
||||
</div>
|
||||
<div class="upscale-upload-content-right" ref="qrcodeContainer">
|
||||
<AQrcode :value="'https://www.baidu.com'"
|
||||
class="upscale-upload-qrcode"
|
||||
:icon="qrphone"
|
||||
:iconSize="iconSize"
|
||||
:bordered="false"
|
||||
:size="qrcodeSize"
|
||||
color="rgba(126, 126, 135, 1)"/>
|
||||
<span class="upscale-upload-qr-text">手机扫码上传</span>
|
||||
</div>
|
||||
</div>
|
||||
</AUploadDragger>
|
||||
</Spin>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ADivider orientation="center" :plain="true"><span class="upscale-file-list-title">图片列表</span></ADivider>
|
||||
<div class="upscale-file-list" ref="fileListContainer">
|
||||
<div v-if="upscale.imageList.length > 0">
|
||||
<AImagePreviewGroup>
|
||||
<ABadge style="margin-left: 10px;" v-for="(item, index) in upscale.imageList"
|
||||
:key="index">
|
||||
<template #count>
|
||||
<AButton type="text" size="small" class="upscale-file-btn" @click="upscale.removeImage(index)">
|
||||
<template #icon>
|
||||
<AAvatar shape="square" :size="20" :src="remove"/>
|
||||
</template>
|
||||
</AButton>
|
||||
</template>
|
||||
<AAvatar shape="square" :size="avatarSize" v-if="item">
|
||||
<template #icon>
|
||||
<AImage :src="item" width="100%" height="100%"/>
|
||||
</template>
|
||||
</AAvatar>
|
||||
</ABadge>
|
||||
</AImagePreviewGroup>
|
||||
</div>
|
||||
</div>
|
||||
<AEmpty :image="empty" v-if="upscale.imageList.length === 0" :description="null"/>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import file from "@/assets/svgs/file.svg";
|
||||
import qrphone from "@/assets/svgs/qr-phone.svg";
|
||||
import empty from "@/assets/svgs/empty.svg";
|
||||
import useStore from "@/store";
|
||||
import Spin from "@/components/MyUI/Spin/Spin.vue";
|
||||
import remove from '@/assets/svgs/remove.svg';
|
||||
|
||||
const upscale = useStore().upscale;
|
||||
const qrcodeSize = ref<number>(160);
|
||||
const iconSize = ref<number>(30);
|
||||
const qrcodeContainer = ref<HTMLElement | null>(null);
|
||||
const avatarSize = ref<number>(80);
|
||||
const fileListContainer = ref<HTMLDivElement | null>(null);
|
||||
|
||||
/**
|
||||
* 更新大小
|
||||
*/
|
||||
const updateSize = () => {
|
||||
if (qrcodeContainer.value && fileListContainer.value) {
|
||||
// 设置 QRCode 大小
|
||||
const containerWidth = qrcodeContainer.value.clientWidth;
|
||||
qrcodeSize.value = containerWidth * 0.5; // 设置 QRCode 为父盒子宽度的80%
|
||||
iconSize.value = Math.min(containerWidth * 0.1, 50); // 设置 icon 大小为父盒子宽度的10%
|
||||
|
||||
// 设置图片列表大小
|
||||
const container = fileListContainer.value.clientWidth;
|
||||
avatarSize.value = Math.min(0.17 * container, 300); // 设置头像大小为容器宽度的10%,最大不超过100
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
updateSize();
|
||||
window.addEventListener('resize', updateSize);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('resize', updateSize);
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.upscale-upload-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
|
||||
.upscale-upload-content {
|
||||
width: 100%;
|
||||
height: 30vh;
|
||||
|
||||
.upscale-upload-content-main {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
overflow: scroll;
|
||||
|
||||
.upscale-upload-content-left {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
|
||||
.upscale-upload-text {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.upscale-upload-btn {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.upscale-upload-tip {
|
||||
font-size: 12px;
|
||||
color: rgba(126, 126, 135, 0.99);
|
||||
}
|
||||
}
|
||||
|
||||
.upscale-upload-content-right {
|
||||
width: 50%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.upscale-upload-qr-text {
|
||||
font-size: 12px;
|
||||
color: rgba(126, 126, 135, 0.99);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.upscale-file-list-title {
|
||||
font-size: 13px;
|
||||
color: rgba(126, 126, 135, 0.99);
|
||||
}
|
||||
|
||||
.upscale-file-list {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.upscale-file-remove-icon {
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
color: #ff0000;
|
||||
//transform: scale(1.2);
|
||||
}
|
||||
|
||||
@media (max-width: 1300px) {
|
||||
.upscale-upload-text {
|
||||
display: none !important;
|
||||
}
|
||||
.upscale-upload-btn {
|
||||
display: none !important;
|
||||
}
|
||||
.upscale-upload-qr-text {
|
||||
display: none !important;
|
||||
}
|
||||
.upscale-upload-content-left {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
}
|
||||
.upscale-upload-content-right {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,15 +1,122 @@
|
||||
<template>
|
||||
<div class="upscale-container">
|
||||
<AFlex :vertical="false" align="center" justify="flex-start">
|
||||
<AAvatar shape="square" :size="30" :src="ai"/>
|
||||
<span class="upscale-title">图像修复</span>
|
||||
</AFlex>
|
||||
<AFlex :vertical="false" align="center" justify="flex-start">
|
||||
<AFlex class="upscale-content" :vertical="false" align="center" justify="flex-start">
|
||||
<div class="upscale-content-left">
|
||||
<ACard class="upscale-content-left-container">
|
||||
<UploadImage/>
|
||||
<ADivider orientation="center" :plain="true"><span class="upscale-divider-title">参数设置</span></ADivider>
|
||||
<div class="upscale-content-left-params">
|
||||
<div class="upscale-content-params-left">
|
||||
<div class="upscale-content-params-item">
|
||||
<div class="upscale-content-params-item-content">
|
||||
<span class="upscale-content-params-title">类型:</span>
|
||||
<ASelect style="width: 100%" size="default"
|
||||
v-model:value="type"
|
||||
:options="TypeData.map(item => ({label: item, value: item}))">
|
||||
</ASelect>
|
||||
</div>
|
||||
<div class="upscale-content-params-item-content">
|
||||
<span class="upscale-content-params-title">模型:</span>
|
||||
<ASelect style="width: 100%" size="default"
|
||||
v-model:value="model"
|
||||
:options="modes.map(item => ({label: item, value: item}))">
|
||||
</ASelect>
|
||||
</div>
|
||||
</div>
|
||||
<div class="upscale-content-params-item">
|
||||
<div class="upscale-content-params-item-content">
|
||||
<span class="upscale-content-params-title">比列:</span>
|
||||
<ASelect style="width: 100%" size="default"
|
||||
v-model:value="scale"
|
||||
:options="ScaleData.map(item => ({label: item, value: item}))">
|
||||
|
||||
</ASelect>
|
||||
</div>
|
||||
<div class="upscale-content-params-item-content">
|
||||
<span class="upscale-content-params-title">分块大小:</span>
|
||||
<ASelect style="width: 100%" size="default"
|
||||
v-model:value="tileSize"
|
||||
:options="tileSizes.map(item => ({label: item, value: item}))">
|
||||
|
||||
</ASelect>
|
||||
</div>
|
||||
</div>
|
||||
<div class="upscale-content-params-item">
|
||||
<div class="upscale-content-params-item-content">
|
||||
<span class="upscale-content-params-title">重复:</span>
|
||||
<ASelect style="width: 100%" size="default"
|
||||
v-model:value="overlap"
|
||||
:options="overlapList.map(item => ({label: item, value: item}))">
|
||||
</ASelect>
|
||||
</div>
|
||||
<div class="upscale-content-params-item-content">
|
||||
<span class="upscale-content-params-title">运行环境:</span>
|
||||
<ASelect style="width: 100%" size="default"
|
||||
v-model:value="runOn"
|
||||
:options="runOnList.map(item => ({label: item, value: item}))">
|
||||
</ASelect>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="upscale-content-params-right">
|
||||
<AButton type="text" style="width: 60px;height: 60px;">
|
||||
<template #icon>
|
||||
<AAvatar shape="square" :size="50" :src="run"/>
|
||||
</template>
|
||||
</AButton>
|
||||
</div>
|
||||
</div>
|
||||
</ACard>
|
||||
</div>
|
||||
<div class="upscale-content-right">
|
||||
<ACard class="upscale-content-right-container">
|
||||
<CompareResult/>
|
||||
</ACard>
|
||||
</div>
|
||||
</AFlex>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
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";
|
||||
|
||||
const TypeData = ['Real-ESRGAN', 'Real-CUGAN'];
|
||||
|
||||
const type = ref<string>(TypeData[0]);
|
||||
|
||||
const ModelData = {
|
||||
'Real-ESRGAN': ['anime_fast', 'anime_plus', 'general_fast', 'general_plus'],
|
||||
'Real-CUGAN': ['conservative', 'no-denoise', 'denoise3x'],
|
||||
};
|
||||
const model = ref(ModelData[type.value][0]);
|
||||
const modes = computed(() => {
|
||||
return ModelData[type.value];
|
||||
});
|
||||
watch(type, val => {
|
||||
model.value = ModelData[val][0];
|
||||
});
|
||||
|
||||
// Scale
|
||||
const ScaleData = [2, 4];
|
||||
const scale = ref<number>(ScaleData[0]);
|
||||
|
||||
//tile size
|
||||
const tileSizes = [32, 48, 64, 96, 128, 192, 256, 384, 512];
|
||||
const tileSize = ref<number>(tileSizes[4]);
|
||||
|
||||
// overlap
|
||||
const overlapList = [0, 4, 8, 12, 16, 20];
|
||||
const overlap = ref<number>(overlapList[3]);
|
||||
|
||||
// run on
|
||||
const runOnList = ['WebGL', 'WebGPU'];
|
||||
const runOn = [runOnList[0]];
|
||||
</script>
|
||||
<style scoped lang="scss" src="./index.scss">
|
||||
|
||||
|
@@ -4,8 +4,88 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
|
||||
.upscale-title {
|
||||
font-size: 20px;
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|