├── .gitignore ├── LICENSE ├── README.md ├── assets ├── 0-嵌入.gif ├── 1-裁切.gif ├── 2-扩图.gif ├── 3-擦除.gif ├── 4-移除背景.gif ├── 5-提升解析度.gif └── pixpro.svg ├── example ├── js │ ├── index.html │ ├── src │ │ ├── css │ │ │ ├── AddNewColor.css │ │ │ ├── AngleAdjustment.css │ │ │ ├── ColoredBtn.css │ │ │ ├── EraserSizeSlider.css │ │ │ ├── SvgIcon.css │ │ │ └── index.css │ │ ├── img │ │ │ └── icon │ │ │ │ ├── 11.svg │ │ │ │ ├── 169.svg │ │ │ │ ├── 43.svg │ │ │ │ ├── 916.svg │ │ │ │ ├── add.svg │ │ │ │ ├── close.svg │ │ │ │ ├── compress-btn.svg │ │ │ │ ├── crop-btn.svg │ │ │ │ ├── erase-btn.svg │ │ │ │ ├── expand-btn.svg │ │ │ │ ├── flip-l.svg │ │ │ │ ├── flip-r.svg │ │ │ │ ├── flip-x.svg │ │ │ │ ├── flip-y.svg │ │ │ │ ├── hd-btn.svg │ │ │ │ ├── loading.svg │ │ │ │ ├── logo.svg │ │ │ │ ├── original.svg │ │ │ │ ├── pointer.svg │ │ │ │ ├── remove-bg-btn.svg │ │ │ │ └── step.svg │ │ └── js │ │ │ ├── components │ │ │ ├── AngleAdjustment.js │ │ │ ├── ColoredBtn.js │ │ │ └── EraserSizeSlider.js │ │ │ ├── config.js │ │ │ ├── index copy.js │ │ │ ├── index.js │ │ │ ├── useColors.js │ │ │ └── useProgressBar.js │ └── vite.config.js ├── react │ ├── index.html │ ├── src │ │ ├── App.css │ │ ├── App.tsx │ │ ├── Canvas.tsx │ │ ├── Layout.css │ │ ├── Layout.tsx │ │ ├── PixProSkin │ │ │ ├── AddNewColor.less │ │ │ ├── AddNewColor.tsx │ │ │ ├── AngleAdjustment.less │ │ │ ├── AngleAdjustment.tsx │ │ │ ├── ColoredBtn.less │ │ │ ├── ColoredBtn.tsx │ │ │ ├── EraserSizeSlider.css │ │ │ ├── EraserSizeSlider.tsx │ │ │ ├── SvgIcon.css │ │ │ ├── SvgIcon.tsx │ │ │ ├── _constant.less │ │ │ ├── assets │ │ │ │ ├── icon │ │ │ │ │ ├── 11.svg │ │ │ │ │ ├── 169.svg │ │ │ │ │ ├── 43.svg │ │ │ │ │ ├── 916.svg │ │ │ │ │ ├── add.svg │ │ │ │ │ ├── close.svg │ │ │ │ │ ├── compress-btn.svg │ │ │ │ │ ├── crop-btn.svg │ │ │ │ │ ├── erase-btn.svg │ │ │ │ │ ├── expand-btn.svg │ │ │ │ │ ├── flip-l.svg │ │ │ │ │ ├── flip-r.svg │ │ │ │ │ ├── flip-x.svg │ │ │ │ │ ├── flip-y.svg │ │ │ │ │ ├── hd-btn.svg │ │ │ │ │ ├── loading.svg │ │ │ │ │ ├── logo.svg │ │ │ │ │ ├── original.svg │ │ │ │ │ ├── pointer.svg │ │ │ │ │ ├── remove-bg-btn.svg │ │ │ │ │ └── step.svg │ │ │ │ └── style │ │ │ │ │ ├── _constant.less │ │ │ │ │ └── index.less │ │ │ ├── hooks │ │ │ │ ├── config.ts │ │ │ │ └── useColors.ts │ │ │ ├── icon │ │ │ │ ├── 11.svg │ │ │ │ ├── 169.svg │ │ │ │ ├── 43.svg │ │ │ │ ├── 916.svg │ │ │ │ ├── close.svg │ │ │ │ ├── compress-btn.svg │ │ │ │ ├── crop-btn.svg │ │ │ │ ├── erase-btn.svg │ │ │ │ ├── expand-btn.svg │ │ │ │ ├── flip-l.svg │ │ │ │ ├── flip-r.svg │ │ │ │ ├── flip-x.svg │ │ │ │ ├── flip-y.svg │ │ │ │ ├── hd-btn.svg │ │ │ │ ├── loading.svg │ │ │ │ ├── logo.svg │ │ │ │ ├── original.svg │ │ │ │ ├── pointer.svg │ │ │ │ ├── remove-bg-btn.svg │ │ │ │ └── step.svg │ │ │ ├── index.less │ │ │ ├── index.tsx │ │ │ ├── types.ts │ │ │ └── useProgressBar.tsx │ │ ├── PixProVue.tsx │ │ ├── Rotate.tsx │ │ ├── Test.css │ │ ├── Test.tsx │ │ ├── bg.jpg │ │ ├── bg1.jpg │ │ ├── env.d.ts │ │ ├── index.css │ │ ├── main.tsx │ │ └── types.d.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── vue │ ├── index.html │ ├── src │ │ ├── App.vue │ │ ├── PixProSkin │ │ │ ├── assets │ │ │ │ ├── icon │ │ │ │ │ ├── 11.svg │ │ │ │ │ ├── 169.svg │ │ │ │ │ ├── 43.svg │ │ │ │ │ ├── 916.svg │ │ │ │ │ ├── add.svg │ │ │ │ │ ├── ai-loading.lottie │ │ │ │ │ ├── close.svg │ │ │ │ │ ├── compress-btn.svg │ │ │ │ │ ├── crop-btn.svg │ │ │ │ │ ├── erase-btn.svg │ │ │ │ │ ├── expand-btn.svg │ │ │ │ │ ├── flip-l.svg │ │ │ │ │ ├── flip-r.svg │ │ │ │ │ ├── flip-x.svg │ │ │ │ │ ├── flip-y.svg │ │ │ │ │ ├── hd-btn.svg │ │ │ │ │ ├── loading.svg │ │ │ │ │ ├── logo.svg │ │ │ │ │ ├── original.svg │ │ │ │ │ ├── pointer.svg │ │ │ │ │ ├── remove-bg-btn.svg │ │ │ │ │ └── step.svg │ │ │ │ ├── images │ │ │ │ │ └── loading.png │ │ │ │ └── style │ │ │ │ │ ├── _constant.less │ │ │ │ │ └── index.less │ │ │ ├── components │ │ │ │ ├── AddNewColor.vue │ │ │ │ ├── AiLoading.vue │ │ │ │ ├── AngleAdjustment.vue │ │ │ │ ├── ColoredBtn.vue │ │ │ │ ├── EraserSizeSlider.vue │ │ │ │ └── SvgIcon.vue │ │ │ ├── hooks │ │ │ │ ├── config.ts │ │ │ │ ├── useColors.ts │ │ │ │ └── useProgressBar.ts │ │ │ └── index.vue │ │ ├── PixProVue.vue │ │ ├── env.d.ts │ │ └── main.ts │ └── vite.config.ts └── vue2 │ ├── index.html │ ├── src │ ├── App.vue │ ├── PixProSkin │ │ ├── assets │ │ │ ├── icon │ │ │ │ ├── 11.svg │ │ │ │ ├── 169.svg │ │ │ │ ├── 43.svg │ │ │ │ ├── 916.svg │ │ │ │ ├── add.svg │ │ │ │ ├── ai-loading.lottie │ │ │ │ ├── close.svg │ │ │ │ ├── compress-btn.svg │ │ │ │ ├── crop-btn.svg │ │ │ │ ├── erase-btn.svg │ │ │ │ ├── expand-btn.svg │ │ │ │ ├── flip-l.svg │ │ │ │ ├── flip-r.svg │ │ │ │ ├── flip-x.svg │ │ │ │ ├── flip-y.svg │ │ │ │ ├── hd-btn.svg │ │ │ │ ├── loading.svg │ │ │ │ ├── logo.svg │ │ │ │ ├── original.svg │ │ │ │ ├── pointer.svg │ │ │ │ ├── remove-bg-btn.svg │ │ │ │ └── step.svg │ │ │ ├── images │ │ │ │ └── loading.png │ │ │ └── style │ │ │ │ ├── _constant.less │ │ │ │ └── index.less │ │ ├── components │ │ │ ├── AddNewColor.vue │ │ │ ├── AiLoading.vue │ │ │ ├── AngleAdjustment.vue │ │ │ ├── ColoredBtn.vue │ │ │ ├── EraserSizeSlider.vue │ │ │ └── SvgIcon.vue │ │ ├── hooks │ │ │ ├── config.js │ │ │ ├── useColors.js │ │ │ └── useProgressBar.js │ │ └── index.vue │ ├── PixProVue.vue │ └── main.js │ ├── vite.config.js │ └── yarn.lock ├── package.json ├── packages ├── pixpro-core │ ├── README.md │ ├── package.json │ ├── rollup.config.mjs │ ├── src │ │ ├── ai │ │ │ ├── ai-background.ts │ │ │ ├── ai-compress.ts │ │ │ ├── ai-enhanceResolution.ts │ │ │ ├── ai-erase.ts │ │ │ └── ai-expand.ts │ │ ├── assets │ │ │ ├── style.css │ │ │ └── style.css.d.ts │ │ ├── config │ │ │ ├── constants.ts │ │ │ └── default.ts │ │ ├── global.d.ts │ │ ├── index.ts │ │ ├── templates │ │ │ └── App.ts │ │ ├── types │ │ │ ├── IType.ts │ │ │ └── libs.d.ts │ │ └── utils │ │ │ ├── CustomFetch.ts │ │ │ ├── cache │ │ │ ├── constants.ts │ │ │ └── index.ts │ │ │ ├── compressImage.ts │ │ │ ├── dragCalculator.ts │ │ │ ├── dragHandle.ts │ │ │ ├── eraser.ts │ │ │ ├── event.ts │ │ │ ├── exportImage.ts │ │ │ ├── imageData.ts │ │ │ ├── imageToBase64.ts │ │ │ ├── traceId.ts │ │ │ ├── utils.ts │ │ │ └── weakTip.ts │ ├── tsconfig.json │ └── yarn.lock ├── pixpro-js │ ├── index.html │ ├── src │ │ ├── css │ │ │ ├── AddNewColor.css │ │ │ ├── AngleAdjustment.css │ │ │ ├── ColoredBtn.css │ │ │ ├── EraserSizeSlider.css │ │ │ ├── SvgIcon.css │ │ │ └── index.css │ │ ├── img │ │ │ ├── icon │ │ │ │ ├── 11.svg │ │ │ │ ├── 169.svg │ │ │ │ ├── 43.svg │ │ │ │ ├── 916.svg │ │ │ │ ├── add.svg │ │ │ │ ├── close.svg │ │ │ │ ├── compress-btn.svg │ │ │ │ ├── crop-btn.svg │ │ │ │ ├── erase-btn.svg │ │ │ │ ├── expand-btn.svg │ │ │ │ ├── flip-l.svg │ │ │ │ ├── flip-r.svg │ │ │ │ ├── flip-x.svg │ │ │ │ ├── flip-y.svg │ │ │ │ ├── hd-btn.svg │ │ │ │ ├── loading.svg │ │ │ │ ├── logo.svg │ │ │ │ ├── original.svg │ │ │ │ ├── pointer.svg │ │ │ │ ├── remove-bg-btn.svg │ │ │ │ └── step.svg │ │ │ └── loading.png │ │ └── js │ │ │ ├── components │ │ │ ├── AiLoading.js │ │ │ ├── AngleAdjustment.js │ │ │ ├── ColoredBtn.js │ │ │ └── EraserSizeSlider.js │ │ │ ├── config.js │ │ │ ├── index.js │ │ │ ├── useColors.js │ │ │ └── useProgressBar.js │ └── vite.config.js ├── pixpro-react │ ├── README.md │ ├── index.html │ ├── package.json │ ├── src │ │ ├── App.css │ │ ├── App.tsx │ │ ├── PixProSkin │ │ │ ├── AddNewColor.less │ │ │ ├── AddNewColor.tsx │ │ │ ├── AiLoading.less │ │ │ ├── AiLoading.tsx │ │ │ ├── AngleAdjustment.less │ │ │ ├── AngleAdjustment.tsx │ │ │ ├── ColoredBtn.less │ │ │ ├── ColoredBtn.tsx │ │ │ ├── EraserSizeSlider.css │ │ │ ├── EraserSizeSlider.tsx │ │ │ ├── SvgIcon.css │ │ │ ├── SvgIcon.tsx │ │ │ ├── _constant.less │ │ │ ├── assets │ │ │ │ ├── icon │ │ │ │ │ ├── 11.svg │ │ │ │ │ ├── 169.svg │ │ │ │ │ ├── 43.svg │ │ │ │ │ ├── 916.svg │ │ │ │ │ ├── add.svg │ │ │ │ │ ├── close.svg │ │ │ │ │ ├── compress-btn.svg │ │ │ │ │ ├── crop-btn.svg │ │ │ │ │ ├── erase-btn.svg │ │ │ │ │ ├── expand-btn.svg │ │ │ │ │ ├── flip-l.svg │ │ │ │ │ ├── flip-r.svg │ │ │ │ │ ├── flip-x.svg │ │ │ │ │ ├── flip-y.svg │ │ │ │ │ ├── hd-btn.svg │ │ │ │ │ ├── loading.svg │ │ │ │ │ ├── logo.svg │ │ │ │ │ ├── original.svg │ │ │ │ │ ├── pointer.svg │ │ │ │ │ ├── remove-bg-btn.svg │ │ │ │ │ └── step.svg │ │ │ │ ├── image │ │ │ │ │ └── loading.png │ │ │ │ └── style │ │ │ │ │ ├── _constant.less │ │ │ │ │ └── index.less │ │ │ ├── hooks │ │ │ │ ├── config.ts │ │ │ │ ├── useColors.ts │ │ │ │ └── useProgressBar.tsx │ │ │ ├── index.tsx │ │ │ └── types.ts │ │ ├── PixProVue.tsx │ │ ├── env.d.ts │ │ ├── index.css │ │ ├── index.ts │ │ ├── main.tsx │ │ └── types.d.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ ├── vite.config.ts │ └── yarn.lock ├── pixpro-vue │ ├── README.md │ ├── package.json │ ├── src │ │ ├── PixProSkin │ │ │ ├── assets │ │ │ │ ├── icon │ │ │ │ │ ├── 11.svg │ │ │ │ │ ├── 169.svg │ │ │ │ │ ├── 43.svg │ │ │ │ │ ├── 916.svg │ │ │ │ │ ├── add.svg │ │ │ │ │ ├── ai-loading.lottie │ │ │ │ │ ├── close.svg │ │ │ │ │ ├── compress-btn.svg │ │ │ │ │ ├── crop-btn.svg │ │ │ │ │ ├── erase-btn.svg │ │ │ │ │ ├── expand-btn.svg │ │ │ │ │ ├── flip-l.svg │ │ │ │ │ ├── flip-r.svg │ │ │ │ │ ├── flip-x.svg │ │ │ │ │ ├── flip-y.svg │ │ │ │ │ ├── hd-btn.svg │ │ │ │ │ ├── loading.svg │ │ │ │ │ ├── logo.svg │ │ │ │ │ ├── original.svg │ │ │ │ │ ├── pointer.svg │ │ │ │ │ ├── remove-bg-btn.svg │ │ │ │ │ └── step.svg │ │ │ │ ├── images │ │ │ │ │ └── loading.png │ │ │ │ └── style │ │ │ │ │ ├── _constant.less │ │ │ │ │ └── index.less │ │ │ ├── components │ │ │ │ ├── AddNewColor.vue │ │ │ │ ├── AiLoading.vue │ │ │ │ ├── AngleAdjustment.vue │ │ │ │ ├── ColoredBtn.vue │ │ │ │ ├── EraserSizeSlider.vue │ │ │ │ └── SvgIcon.vue │ │ │ ├── hooks │ │ │ │ ├── config.ts │ │ │ │ ├── useColors.ts │ │ │ │ └── useProgressBar.ts │ │ │ └── index.vue │ │ ├── PixProVue.vue │ │ ├── index.ts │ │ ├── plugin.ts │ │ ├── shims-vue.d.ts │ │ ├── styles │ │ │ └── index.less │ │ └── types.d.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ ├── vite.config.ts │ └── yarn.lock └── pixpro-vue2 │ ├── README.md │ ├── index.html │ ├── package.json │ ├── src │ ├── App.vue │ ├── PixProSkin │ │ ├── assets │ │ │ ├── icon │ │ │ │ ├── 11.svg │ │ │ │ ├── 169.svg │ │ │ │ ├── 43.svg │ │ │ │ ├── 916.svg │ │ │ │ ├── add.svg │ │ │ │ ├── ai-loading.lottie │ │ │ │ ├── close.svg │ │ │ │ ├── compress-btn.svg │ │ │ │ ├── crop-btn.svg │ │ │ │ ├── erase-btn.svg │ │ │ │ ├── expand-btn.svg │ │ │ │ ├── flip-l.svg │ │ │ │ ├── flip-r.svg │ │ │ │ ├── flip-x.svg │ │ │ │ ├── flip-y.svg │ │ │ │ ├── hd-btn.svg │ │ │ │ ├── loading.svg │ │ │ │ ├── logo.svg │ │ │ │ ├── original.svg │ │ │ │ ├── pointer.svg │ │ │ │ ├── remove-bg-btn.svg │ │ │ │ └── step.svg │ │ │ ├── images │ │ │ │ └── loading.png │ │ │ └── style │ │ │ │ ├── _constant.less │ │ │ │ └── index.less │ │ ├── components │ │ │ ├── AddNewColor.vue │ │ │ ├── AiLoading.vue │ │ │ ├── AngleAdjustment.vue │ │ │ ├── ColoredBtn.vue │ │ │ ├── EraserSizeSlider.vue │ │ │ └── SvgIcon.vue │ │ ├── hooks │ │ │ ├── config.js │ │ │ ├── constants.js │ │ │ ├── useColors.js │ │ │ └── useProgressBar.js │ │ └── index.vue │ ├── PixProVue.vue │ ├── index.js │ └── main.js │ ├── vite.config.js │ └── yarn.lock ├── src ├── ai │ ├── ai-background.ts │ ├── ai-compress.ts │ ├── ai-enhanceResolution.ts │ ├── ai-erase.ts │ └── ai-expand.ts ├── assets │ ├── style.css │ └── style.css.d.ts ├── config │ ├── constants.ts │ └── default.ts ├── index.ts ├── templates │ └── App.ts ├── types │ ├── IType.ts │ └── libs.d.ts └── utils │ ├── CustomFetch.ts │ ├── cache │ ├── constants.ts │ └── index.ts │ ├── compressImage.ts │ ├── dragCalculator.ts │ ├── dragHandle.ts │ ├── eraser.ts │ ├── event.ts │ ├── exportImage.ts │ ├── imageData.ts │ ├── imageToBase64.ts │ ├── traceId.ts │ ├── utils.ts │ └── weakTip.ts ├── tsconfig.json ├── vite.config.ts └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | # AI.md 11 | AI.md 12 | 13 | node_modules 14 | dist 15 | dist-ssr 16 | *.local 17 | 18 | # Editor directories and files 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? 26 | *.tgz 27 | *.env -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 PixPro 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /assets/0-嵌入.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/assets/0-嵌入.gif -------------------------------------------------------------------------------- /assets/1-裁切.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/assets/1-裁切.gif -------------------------------------------------------------------------------- /assets/2-扩图.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/assets/2-扩图.gif -------------------------------------------------------------------------------- /assets/3-擦除.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/assets/3-擦除.gif -------------------------------------------------------------------------------- /assets/4-移除背景.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/assets/4-移除背景.gif -------------------------------------------------------------------------------- /assets/5-提升解析度.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/assets/5-提升解析度.gif -------------------------------------------------------------------------------- /example/js/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Pix Pro For JS Example 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /example/js/src/css/AddNewColor.css: -------------------------------------------------------------------------------- 1 | .add-color-item { 2 | width: 50px; 3 | height: 50px; 4 | border-radius: 6px; 5 | cursor: pointer; 6 | border: 2px solid transparent; 7 | padding: 3px; 8 | box-sizing: border-box; 9 | position: relative; 10 | } 11 | .add-color-item span { 12 | display: flex; 13 | align-items: center; 14 | justify-content: center; 15 | box-sizing: border-box; 16 | border: 1px solid #cdd5dd; 17 | width: 100%; 18 | height: 100%; 19 | border-radius: 6px; 20 | overflow: hidden; 21 | background: linear-gradient(to bottom, #f9f9f9, #ffffff); 22 | } 23 | .add-color-item .color-select { 24 | box-sizing: border-box; 25 | padding: 10px; 26 | border-radius: 8px; 27 | position: absolute; 28 | width: 180px; 29 | top: 0px; 30 | left: 50px; 31 | z-index: 9999; 32 | cursor: auto; 33 | box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2); 34 | background-color: #fff; 35 | } 36 | .add-color-item .color-select input { 37 | cursor: pointer; 38 | width: 100%; 39 | } 40 | .add-color-item .color-select p { 41 | font-size: 12px; 42 | color: #666; 43 | margin: 0 0 5px; 44 | text-align: center; 45 | } 46 | 47 | .add-color-item .color-select footer { 48 | display: flex; 49 | justify-content: space-between; 50 | gap: 5px; 51 | } 52 | .add-color-item .color-select footer .toolbar-btn { 53 | width: 100%; 54 | padding: 5px 10px !important; 55 | margin-top: 10px !important; 56 | } 57 | -------------------------------------------------------------------------------- /example/js/src/css/ColoredBtn.css: -------------------------------------------------------------------------------- 1 | /* ColoredBtn 样式 */ 2 | .colored-btn { 3 | margin: 20px auto; 4 | width: 128px; 5 | height: 36px; 6 | border-radius: 8px; 7 | border: none; 8 | color: #fff; 9 | background: linear-gradient(to right, #184aff 0%, #fc9bff 100%); 10 | display: flex; 11 | align-items: center; 12 | justify-content: center; 13 | gap: 4px; 14 | cursor: pointer; 15 | transition: all 0.3s ease; 16 | } 17 | 18 | .colored-btn svg { 19 | color: #fff; 20 | } 21 | 22 | .colored-btn:active { 23 | transform: scale(0.97); 24 | } 25 | 26 | .colored-btn:disabled { 27 | background: #ccc; 28 | cursor: not-allowed; 29 | } 30 | 31 | .colored-btn.loading { 32 | opacity: 0.7; 33 | } 34 | -------------------------------------------------------------------------------- /example/js/src/css/EraserSizeSlider.css: -------------------------------------------------------------------------------- 1 | small { 2 | display: block; 3 | margin: 20px 0 10px; 4 | } 5 | 6 | input { 7 | width: 100%; 8 | -webkit-appearance: none; /* Safari */ 9 | appearance: none; 10 | height: 6px; 11 | border-radius: 3px; 12 | outline: none; 13 | opacity: 1; 14 | transition: opacity 0.2s; 15 | } 16 | 17 | input::-webkit-slider-thumb { 18 | -webkit-appearance: none; /* Safari */ 19 | appearance: none; 20 | width: 16px; 21 | height: 16px; 22 | border-radius: 50%; 23 | background: #4878ef; 24 | cursor: pointer; 25 | } 26 | 27 | input::-moz-range-thumb { 28 | width: 16px; 29 | height: 16px; 30 | border-radius: 50%; 31 | background: #4878ef; 32 | cursor: pointer; 33 | } 34 | -------------------------------------------------------------------------------- /example/js/src/css/SvgIcon.css: -------------------------------------------------------------------------------- 1 | .svg-icon { 2 | display: flex; 3 | align-items: center; 4 | justify-content: center; 5 | } 6 | -------------------------------------------------------------------------------- /example/js/src/img/icon/11.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/js/src/img/icon/169.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/js/src/img/icon/43.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/js/src/img/icon/916.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/js/src/img/icon/add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/js/src/img/icon/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/js/src/img/icon/compress-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /example/js/src/img/icon/crop-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/js/src/img/icon/erase-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/js/src/img/icon/expand-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/js/src/img/icon/flip-l.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/js/src/img/icon/flip-r.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/js/src/img/icon/flip-x.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/js/src/img/icon/flip-y.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/js/src/img/icon/original.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/js/src/img/icon/pointer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/js/src/img/icon/remove-bg-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/js/src/img/icon/step.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/js/src/js/config.js: -------------------------------------------------------------------------------- 1 | export const controlTextData = { 2 | crop: { 3 | btn: "裁切", 4 | title: "裁切", 5 | desc: "", 6 | icon: "crop-btn", 7 | }, 8 | expand: { 9 | btn: "扩图", 10 | title: "扩图", 11 | desc: "向外扩展图片,AI将填充图片以外的部分", 12 | icon: "expand-btn", 13 | }, 14 | erase: { 15 | btn: "擦除", 16 | title: "擦除", 17 | desc: "涂抹想要从图片中擦除的区域", 18 | icon: "erase-btn", 19 | }, 20 | "remove-bg": { 21 | btn: "移除背景", 22 | title: "移除背景", 23 | desc: "一键抠出图片中的主体", 24 | icon: "remove-bg-btn", 25 | }, 26 | hd: { 27 | btn: "提升解析度", 28 | title: "提升解析度", 29 | desc: "立即提提升图片解析度", 30 | icon: "hd-btn", 31 | }, 32 | compress: { 33 | btn: "压缩容量", 34 | title: "压缩容量", 35 | desc: "在保证图片质量的基础上,有效降低图片的容量", 36 | icon: "compress-btn", 37 | }, 38 | }; 39 | 40 | export const cropControlData = { 41 | original: 0, 42 | "1:1": 1, 43 | "4:3": 4 / 3, 44 | "16:9": 16 / 9, 45 | "9:16": 9 / 16, 46 | }; 47 | 48 | /** 颜色列表 */ 49 | export const colorListData = ["transparent", "#ffffff", "#e3e9ef", "#dbe9fd", "#afc5c1", "#a2e1c9", "#4067c5", "#0b209f", "#4041c3", "#27297e", "#5a335f", "#d74f3c", "#ebaacb", "#fbe8e3", "#f3e48b", "#ccef7a", "#75c097", "#62b6b0", "#6de9b0", "#83c8df"]; 50 | -------------------------------------------------------------------------------- /example/js/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import path from 'path'; 3 | 4 | export default defineConfig({ 5 | server: { 6 | port: 3000, 7 | open: true, 8 | }, 9 | resolve: { 10 | alias: { 11 | '@': path.resolve(__dirname, '../../src'), 12 | }, 13 | }, 14 | optimizeDeps: { 15 | include: ['@/index'] 16 | }, 17 | publicDir: 'public', 18 | build: { 19 | assetsDir: 'assets', 20 | assetsInlineLimit: 4096, 21 | }, 22 | assetsInclude: ['**/*.svg'], 23 | }); -------------------------------------------------------------------------------- /example/react/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Pix Pro For React Example 7 | 8 | 9 |
10 | 11 | 12 | 19 | 20 | -------------------------------------------------------------------------------- /example/react/src/App.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | .box { 6 | width: 100%; 7 | height: 100%; 8 | padding: 60px 40px; 9 | box-sizing: border-box; 10 | overflow: hidden; 11 | } 12 | .export-img-box { 13 | position: fixed; 14 | top: 0; 15 | left: 0; 16 | right: 0; 17 | bottom: 0; 18 | background-color: rgba(0, 0, 0, 0.5); 19 | padding: 46px; 20 | box-sizing: border-box; 21 | z-index: 3; 22 | display: flex; 23 | justify-content: center; 24 | align-items: center; 25 | } 26 | .export-img-box img { 27 | max-width: 80%; 28 | max-height: 80%; 29 | } 30 | -------------------------------------------------------------------------------- /example/react/src/App.tsx: -------------------------------------------------------------------------------- 1 | import PixProVue from "./PixProVue.tsx"; 2 | 3 | const App = () => { 4 | return ( 5 |
6 | 7 |
8 | ); 9 | }; 10 | 11 | export default App; 12 | -------------------------------------------------------------------------------- /example/react/src/Canvas.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef, useState } from "react"; 2 | import bgImg from "./bg1.jpg"; 3 | 4 | const Canvas = () => { 5 | const canvasRef = useRef(null); 6 | const [canvasWidth] = useState(1500); 7 | const [canvasHeight] = useState(1000); 8 | const [canvasStyle] = useState({ 9 | width: 1500, 10 | height: 1000, 11 | }); 12 | 13 | const canvasRenderStyle = { 14 | width: `${canvasStyle.width / 2}px`, 15 | height: `${canvasStyle.height / 2}px`, 16 | }; 17 | 18 | useEffect(() => { 19 | const img = new Image(); 20 | img.src = bgImg; 21 | img.onload = () => { 22 | const ctx = canvasRef.current?.getContext("2d"); 23 | if (ctx && canvasRef.current) { 24 | ctx.drawImage(img, 0, 0, 3000, 2000, 0, 0, canvasWidth, canvasHeight); 25 | } 26 | }; 27 | }, [canvasWidth, canvasHeight]); 28 | 29 | return ( 30 |
31 | 32 |
33 | ); 34 | }; 35 | 36 | export default Canvas; 37 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/AddNewColor.tsx: -------------------------------------------------------------------------------- 1 | import React, { useRef } from "react"; 2 | import SvgIcon from "./SvgIcon"; 3 | import "./AddNewColor.less"; 4 | 5 | interface AddNewColorProps { 6 | value: boolean; 7 | onChange: (color: string) => void; 8 | onOpen: () => void; 9 | onRemove?: (color: string) => void; 10 | localColorList?: string[]; 11 | currentColor?: string; 12 | } 13 | 14 | const AddNewColor: React.FC = ({ value, onChange, onOpen }) => { 15 | const inputRef = useRef(null); 16 | 17 | const handleClick = () => { 18 | onOpen(); 19 | }; 20 | 21 | const handleConfirm = () => { 22 | const color = inputRef.current?.value; 23 | if (color) { 24 | onChange(color); 25 | } 26 | }; 27 | 28 | const handleCancel = () => { 29 | onChange(""); 30 | }; 31 | 32 | return ( 33 |
34 | 35 | 36 | 37 | {value && ( 38 |
39 |

点击色块选择颜色

40 | 41 |
42 | 45 | 48 |
49 |
50 | )} 51 |
52 | ); 53 | }; 54 | 55 | export default AddNewColor; 56 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/ColoredBtn.less: -------------------------------------------------------------------------------- 1 | @import "./assets/style/_constant.less"; 2 | 3 | .colored-btn-component { 4 | button { 5 | margin: 20px auto; 6 | width: 128px; 7 | height: 36px; 8 | border-radius: @radius; 9 | border: none; 10 | color: #fff; 11 | background: linear-gradient(to right, #184aff 0%, #fc9bff 100%); 12 | display: flex; 13 | align-items: center; 14 | justify-content: center; 15 | gap: 4px; 16 | cursor: pointer; 17 | .ani300; 18 | 19 | :deep(svg) { 20 | color: #fff; 21 | } 22 | 23 | &:active { 24 | transform: scale(0.97); 25 | } 26 | 27 | &:disabled { 28 | background: #ccc; 29 | cursor: not-allowed; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/ColoredBtn.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import SvgIcon from "./SvgIcon"; 3 | import "./assets/style/_constant.less"; 4 | import "./ColoredBtn.less"; 5 | 6 | interface ColoredBtnProps { 7 | text: string; 8 | icon?: string; 9 | disabled?: boolean; 10 | loading?: boolean; 11 | onClick: () => void; 12 | } 13 | 14 | const ColoredBtn: React.FC = ({ text, icon = "expand-btn", disabled = false, loading = false, onClick }) => { 15 | return ( 16 |
17 | 21 |
22 | ); 23 | }; 24 | 25 | export default ColoredBtn; 26 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/EraserSizeSlider.css: -------------------------------------------------------------------------------- 1 | small { 2 | display: block; 3 | margin: 20px 0 10px; 4 | } 5 | 6 | input { 7 | width: 100%; 8 | -webkit-appearance: none; /* Safari */ 9 | appearance: none; 10 | height: 6px; 11 | border-radius: 3px; 12 | outline: none; 13 | opacity: 1; 14 | transition: opacity 0.2s; 15 | } 16 | 17 | input::-webkit-slider-thumb { 18 | -webkit-appearance: none; /* Safari */ 19 | appearance: none; 20 | width: 16px; 21 | height: 16px; 22 | border-radius: 50%; 23 | background: #4878ef; 24 | cursor: pointer; 25 | } 26 | 27 | input::-moz-range-thumb { 28 | width: 16px; 29 | height: 16px; 30 | border-radius: 50%; 31 | background: #4878ef; 32 | cursor: pointer; 33 | } 34 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/SvgIcon.css: -------------------------------------------------------------------------------- 1 | .svg-icon { 2 | display: flex; 3 | align-items: center; 4 | justify-content: center; 5 | } 6 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/_constant.less: -------------------------------------------------------------------------------- 1 | @primary-color: #184aff; 2 | @radius: 8px; 3 | @selected-bgc: #e6e6e6; 4 | @border-color: #e8e8e8; 5 | 6 | .ani300 { 7 | transition: all 0.3s ease; 8 | } 9 | 10 | .btn-line { 11 | position: relative; 12 | &:before { 13 | content: ""; 14 | display: block; 15 | width: 1px; 16 | height: 60%; 17 | background-color: #e0e5ea; 18 | position: absolute; 19 | right: 0; 20 | top: 50%; 21 | transform: translateY(-50%); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/11.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/169.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/43.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/916.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/compress-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/crop-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/erase-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/expand-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/flip-l.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/flip-r.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/flip-x.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/flip-y.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/original.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/pointer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/remove-bg-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/icon/step.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/assets/style/_constant.less: -------------------------------------------------------------------------------- 1 | @primary-color: #184aff; 2 | @radius: 8px; 3 | @selected-bgc: #e6e6e6; 4 | @border-color: #e8e8e8; 5 | 6 | .ani300 { 7 | transition: all 0.3s ease; 8 | } 9 | 10 | .btn-line { 11 | position: relative; 12 | &:before { 13 | content: ""; 14 | display: block; 15 | width: 1px; 16 | height: 60%; 17 | background-color: #e0e5ea; 18 | position: absolute; 19 | right: 0; 20 | top: 50%; 21 | transform: translateY(-50%); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/hooks/config.ts: -------------------------------------------------------------------------------- 1 | export const controlTextData = { 2 | crop: { 3 | btn: "裁切", 4 | title: "裁切", 5 | desc: "", 6 | icon: "crop-btn", 7 | }, 8 | expand: { 9 | btn: "扩图", 10 | title: "扩图", 11 | desc: "向外扩展图片,AI将填充图片以外的部分", 12 | icon: "expand-btn", 13 | }, 14 | erase: { 15 | btn: "擦除", 16 | title: "擦除", 17 | desc: "涂抹想要从图片中擦除的区域", 18 | icon: "erase-btn", 19 | }, 20 | "remove-bg": { 21 | btn: "移除背景", 22 | title: "移除背景", 23 | desc: "一键抠出图片中的主体", 24 | icon: "remove-bg-btn", 25 | }, 26 | hd: { 27 | btn: "提升解析度", 28 | title: "提升解析度", 29 | desc: "立即提提升图片解析度", 30 | icon: "hd-btn", 31 | }, 32 | }; 33 | 34 | export const cropControlData = { 35 | original: 0, 36 | "1:1": 1, 37 | "4:3": 4 / 3, 38 | "16:9": 16 / 9, 39 | "9:16": 9 / 16, 40 | }; 41 | 42 | /** 颜色列表 */ 43 | export const colorListData = ["transparent", "#ffffff", "#e3e9ef", "#dbe9fd", "#afc5c1", "#a2e1c9", "#4067c5", "#0b209f", "#4041c3", "#27297e", "#5a335f", "#d74f3c", "#ebaacb", "#fbe8e3", "#f3e48b", "#ccef7a", "#75c097", "#62b6b0", "#6de9b0", "#83c8df"]; 44 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/icon/11.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/icon/169.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/icon/43.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/icon/916.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/icon/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/icon/compress-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/icon/crop-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/icon/erase-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/icon/expand-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/icon/flip-l.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/icon/flip-r.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/icon/flip-x.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/icon/flip-y.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/icon/original.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/icon/pointer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/icon/remove-bg-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/PixProSkin/icon/step.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/react/src/Test.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | .box { 7 | width: 80vw; 8 | height: 60vh; 9 | background-color: #f0f0f0; 10 | margin: 30px auto; 11 | position: relative; 12 | } 13 | 14 | .dots { 15 | width: 20px; 16 | height: 20px; 17 | background-color: red; 18 | position: absolute; 19 | top: 30px; 20 | left: 30px; 21 | } 22 | 23 | .dots.n { 24 | top: 0; 25 | } 26 | 27 | .dots.s { 28 | left: 0; 29 | } 30 | -------------------------------------------------------------------------------- /example/react/src/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/example/react/src/bg.jpg -------------------------------------------------------------------------------- /example/react/src/bg1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/example/react/src/bg1.jpg -------------------------------------------------------------------------------- /example/react/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | declare module '*.svg?raw' { 5 | const content: string; 6 | export default content; 7 | } 8 | 9 | declare module '*.jpg' { 10 | const src: string; 11 | export default src; 12 | } 13 | 14 | declare module '*.png' { 15 | const src: string; 16 | export default src; 17 | } 18 | 19 | declare module '*.less' { 20 | const classes: { readonly [key: string]: string }; 21 | export default classes; 22 | } 23 | 24 | declare module '*.css' { 25 | const classes: { readonly [key: string]: string }; 26 | export default classes; 27 | } -------------------------------------------------------------------------------- /example/react/src/index.css: -------------------------------------------------------------------------------- 1 | /* 全局样式 */ 2 | * { 3 | margin: 0; 4 | padding: 0; 5 | box-sizing: border-box; 6 | } 7 | 8 | body { 9 | margin: 0; 10 | padding: 0; 11 | } 12 | 13 | /* App 容器样式 */ 14 | .app-container { 15 | width: 100vw; 16 | height: 100vh; 17 | overflow: hidden; 18 | } 19 | 20 | .box { 21 | width: 100%; 22 | height: 100%; 23 | padding: 60px 40px; 24 | box-sizing: border-box; 25 | overflow: hidden; 26 | } 27 | 28 | .export-img-box { 29 | position: fixed; 30 | top: 0; 31 | left: 0; 32 | right: 0; 33 | bottom: 0; 34 | background-color: rgba(0, 0, 0, 0.5); 35 | padding: 46px; 36 | box-sizing: border-box; 37 | z-index: 3; 38 | display: flex; 39 | justify-content: center; 40 | align-items: center; 41 | } 42 | 43 | .export-img-box img { 44 | max-width: 80%; 45 | max-height: 80%; 46 | } 47 | 48 | .loading-mask { 49 | position: fixed; 50 | top: 0; 51 | left: 0; 52 | right: 0; 53 | bottom: 0; 54 | background-color: rgba(0, 0, 0, 0.5); 55 | display: flex; 56 | justify-content: center; 57 | align-items: center; 58 | z-index: 1000; 59 | } 60 | 61 | .loading-spinner { 62 | color: #fff; 63 | font-size: 16px; 64 | } 65 | -------------------------------------------------------------------------------- /example/react/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import App from "./App"; 4 | import "./index.css"; 5 | 6 | ReactDOM.createRoot(document.getElementById("root")!).render( 7 | 8 | 9 | 10 | ); 11 | -------------------------------------------------------------------------------- /example/react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | "moduleResolution": "bundler", 9 | "allowImportingTsExtensions": true, 10 | "resolveJsonModule": true, 11 | "isolatedModules": true, 12 | "noEmit": true, 13 | "jsx": "react-jsx", 14 | "strict": true, 15 | "noUnusedLocals": true, 16 | "noUnusedParameters": true, 17 | "noFallthroughCasesInSwitch": true, 18 | "types": [], 19 | "baseUrl": ".", 20 | "paths": { 21 | "@/*": ["../../src/*"] 22 | } 23 | }, 24 | "include": ["src"], 25 | "references": [{ "path": "./tsconfig.node.json" }] 26 | } 27 | -------------------------------------------------------------------------------- /example/react/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /example/react/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | import path from 'path'; 4 | 5 | export default defineConfig({ 6 | plugins: [react()], 7 | assetsInclude: ['**/*.svg'], 8 | css: { 9 | preprocessorOptions: { 10 | less: { 11 | javascriptEnabled: true, 12 | }, 13 | }, 14 | }, 15 | server: { 16 | port: 1220, 17 | open: true, 18 | host: true, 19 | proxy: { 20 | '^/api/.*': { 21 | target: 'https://pixpro.brandsh.cn', 22 | changeOrigin: true 23 | } 24 | } 25 | }, 26 | resolve: { 27 | alias: { 28 | '@': path.resolve(__dirname, '../../src'), 29 | }, 30 | } 31 | }); -------------------------------------------------------------------------------- /example/vue/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Pix Pro For Vue Example 7 | 8 | 9 |
10 | 11 | 12 | 21 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/11.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/169.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/43.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/916.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/ai-loading.lottie: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/example/vue/src/PixProSkin/assets/icon/ai-loading.lottie -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/compress-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/crop-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/erase-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/expand-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/flip-l.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/flip-r.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/flip-x.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/flip-y.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/original.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/pointer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/remove-bg-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/icon/step.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/images/loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/example/vue/src/PixProSkin/assets/images/loading.png -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/assets/style/_constant.less: -------------------------------------------------------------------------------- 1 | @primary-color: #184aff; 2 | @radius: 8px; 3 | @selected-bgc: #e6e6e6; 4 | @border-color: #e8e8e8; 5 | 6 | .ani300 { 7 | transition: all 0.3s ease; 8 | } 9 | 10 | .btn-line { 11 | position: relative; 12 | &:before { 13 | content: ''; 14 | display: block; 15 | width: 1px; 16 | height: 60%; 17 | background-color: #E0E5EA; 18 | position: absolute; 19 | right: 0; 20 | top: 50%; 21 | transform: translateY(-50%); 22 | } 23 | } -------------------------------------------------------------------------------- /example/vue/src/PixProSkin/components/ColoredBtn.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 33 | 34 | -------------------------------------------------------------------------------- /example/vue/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | interface ImportMetaEnv { 4 | readonly VITE_HOST: string 5 | readonly VITE_ROUTES: string 6 | readonly VITE_TOKEN: string 7 | } 8 | 9 | interface ImportMeta { 10 | readonly env: ImportMetaEnv 11 | } -------------------------------------------------------------------------------- /example/vue/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | // import App from './PixProSkin/index.vue' 4 | // import Test from './Test.vue' 5 | 6 | createApp(App).mount('#app') 7 | // createApp(Test).mount('#app') -------------------------------------------------------------------------------- /example/vue/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import vue from '@vitejs/plugin-vue'; 3 | import path from 'path'; 4 | 5 | export default defineConfig({ 6 | plugins: [ 7 | vue({ 8 | template: { 9 | compilerOptions: { 10 | isCustomElement: (tag) => tag === 'svg' 11 | } 12 | } 13 | }) 14 | ], 15 | server: { 16 | port: 1220, 17 | open: true, 18 | host: true, 19 | proxy: { 20 | '^/api/.*': { // 使用正则匹配所有以 /api 开头的请求 21 | target: 'https://api.pixpro.cc', 22 | changeOrigin: true 23 | } 24 | } 25 | }, 26 | resolve: { 27 | alias: { 28 | '@': path.resolve(__dirname, '../../src'), 29 | }, 30 | }, 31 | css: { 32 | modules: { 33 | scopeBehaviour: 'local', 34 | } 35 | } 36 | }); -------------------------------------------------------------------------------- /example/vue2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Pix Pro For Vue Example 8 | 9 | 10 | 11 |
12 | 13 | 14 | 21 | 22 | -------------------------------------------------------------------------------- /example/vue2/src/App.vue: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 17 | 18 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/11.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/169.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/43.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/916.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/ai-loading.lottie: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/example/vue2/src/PixProSkin/assets/icon/ai-loading.lottie -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/compress-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/crop-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/erase-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/expand-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/flip-l.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/flip-r.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/flip-x.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/flip-y.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/original.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/pointer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/icon/step.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/images/loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/example/vue2/src/PixProSkin/assets/images/loading.png -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/assets/style/_constant.less: -------------------------------------------------------------------------------- 1 | @primary-color: #184aff; 2 | @radius: 8px; 3 | @selected-bgc: #e6e6e6; 4 | @border-color: #e8e8e8; 5 | 6 | .ani300 { 7 | transition: all 0.3s ease; 8 | } 9 | 10 | .btn-line { 11 | position: relative; 12 | &:before { 13 | content: ''; 14 | display: block; 15 | width: 1px; 16 | height: 60%; 17 | background-color: #E0E5EA; 18 | position: absolute; 19 | right: 0; 20 | top: 50%; 21 | transform: translateY(-50%); 22 | } 23 | } -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/components/ColoredBtn.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 40 | 41 | 72 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/hooks/config.js: -------------------------------------------------------------------------------- 1 | export const controlTextData = { 2 | crop: { 3 | btn: '裁切', 4 | title: '裁切', 5 | desc: '', 6 | icon: 'crop-btn' 7 | }, 8 | expand: { 9 | btn: '扩图', 10 | title: '扩图', 11 | desc: '向外扩展图片,AI将填充图片以外的部分。', 12 | icon: 'expand-btn' 13 | }, 14 | erase: { 15 | btn: '擦除', 16 | title: '擦除', 17 | desc: '涂抹想要从图片中擦除的区域', 18 | icon: 'erase-btn' 19 | }, 20 | 'remove-bg': { 21 | btn: '移除背景', 22 | title: '移除背景', 23 | desc: '一键抠出图片中的主体。', 24 | icon: 'remove-bg-btn' 25 | }, 26 | hd: { 27 | btn: '提升解析度', 28 | title: '提升解析度', 29 | desc: '最大可提升至 3200 x 3200', 30 | icon: 'hd-btn' 31 | } 32 | } 33 | 34 | export const cropControlData = { 35 | original: 0, 36 | '1:1': 1, 37 | '4:3': 4 / 3, 38 | '16:9': 16 / 9, 39 | '9:16': 9 / 16 40 | } 41 | 42 | /** 颜色列表 */ 43 | export const colorListData = [ 44 | 'transparent', 45 | '#ffffff', 46 | '#e3e9ef', 47 | '#dbe9fd', 48 | '#afc5c1', 49 | '#a2e1c9', 50 | '#4067c5', 51 | '#0b209f', 52 | '#4041c3', 53 | '#27297e', 54 | '#5a335f', 55 | '#d74f3c', 56 | '#ebaacb', 57 | '#fbe8e3', 58 | '#f3e48b', 59 | '#ccef7a', 60 | '#75c097', 61 | '#62b6b0', 62 | '#6de9b0', 63 | '#83c8df' 64 | ] 65 | -------------------------------------------------------------------------------- /example/vue2/src/PixProSkin/hooks/useColors.js: -------------------------------------------------------------------------------- 1 | // hooks/useColors.js 2 | import { colorListData } from './config.js'; 3 | 4 | export default { 5 | data() { 6 | return { 7 | colorList: colorListData, 8 | colorBoxVisible: false, 9 | localColorList: [] 10 | }; 11 | }, 12 | computed: { 13 | allColorsList() { 14 | return [...this.colorList, ...this.localColorList]; 15 | } 16 | }, 17 | methods: { 18 | getColorLocalStorage() { 19 | const colorList = localStorage.getItem('PIXPRO_COLOR_LIST'); 20 | if (colorList) { 21 | this.localColorList = colorList.split(','); 22 | } 23 | }, 24 | setColorLocalStorage(colorList) { 25 | localStorage.setItem('PIXPRO_COLOR_LIST', colorList.join(',')); 26 | }, 27 | removeLocalColorStorage(color) { 28 | const index = this.localColorList.indexOf(color); 29 | if (index !== -1) { 30 | this.localColorList.splice(index, 1); 31 | this.setColorLocalStorage(this.localColorList); 32 | this.$nextTick(() => { 33 | this.handleColorChange(this.currentColor); 34 | }); 35 | } 36 | }, 37 | handleAddNewColor(color) { 38 | if (this.localColorList.includes(color)) { 39 | this.handleColorChange(color); 40 | this.colorBoxVisible = false; 41 | return; 42 | } 43 | this.localColorList.push(color); 44 | this.setColorLocalStorage(this.localColorList); 45 | this.handleColorChange(color); 46 | this.colorBoxVisible = false; 47 | } 48 | }, 49 | mounted() { 50 | this.getColorLocalStorage(); 51 | } 52 | }; -------------------------------------------------------------------------------- /example/vue2/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | 5 | new Vue({ 6 | render: h => h(App) 7 | }).$mount('#app') -------------------------------------------------------------------------------- /example/vue2/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import vue from '@vitejs/plugin-vue2'; 3 | import { resolve } from 'path'; 4 | 5 | export default defineConfig({ 6 | plugins: [ 7 | vue({ 8 | template: { 9 | compilerOptions: { 10 | isCustomElement: (tag) => tag === 'svg' 11 | } 12 | } 13 | }) 14 | ], 15 | server: { 16 | port: 1220, 17 | open: true, 18 | host: true, 19 | proxy: { 20 | '^/api/.*': { // 使用正则匹配所有以 /api 开头的请求 21 | target: 'https://api.pixpro.cc', 22 | changeOrigin: true 23 | } 24 | } 25 | }, 26 | resolve: { 27 | alias: { 28 | '@': resolve(__dirname, '../../src'), 29 | }, 30 | }, 31 | css: { 32 | modules: { 33 | scopeBehaviour: 'local', 34 | } 35 | } 36 | }); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pixpro", 3 | "version": "0.1.12", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "devDependencies": { 7 | "@types/node": "^22.10.2", 8 | "@types/react": "^18.2.0", 9 | "@types/react-dom": "^19.0.4", 10 | "@vitejs/plugin-react": "^3.0.0", 11 | "@vitejs/plugin-vue": "^5.0.2", 12 | "less": "^4.2.2", 13 | "typescript": "^5.7.2", 14 | "vite": "^6.0.4", 15 | "vite-plugin-dts": "^4.4.0" 16 | }, 17 | "scripts": { 18 | "vue": "vite example/vue --config example/vue/vite.config.ts", 19 | "react": "vite example/react --config example/react/vite.config.ts" 20 | }, 21 | "dependencies": { 22 | "compressorjs": "^1.2.1", 23 | "lodash-es": "^4.17.21", 24 | "react": "^18.0.0", 25 | "react-dom": "^18.0.0", 26 | "uuid": "^11.0.5", 27 | "vue": "^3.2.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/pixpro-core/README.md: -------------------------------------------------------------------------------- 1 | # PixPro AI图片处理库(AI Image Processing Library) 2 | 3 | PixPro 是一个图片处理工具,提供了图片处理的基础功能,如常用的裁剪、等比例缩放、翻转、镜像、旋转等功能。同时,PixPro 还嵌入了各类第三方的AI图像处理能力,例如AI 扩图、AI擦除、AI去背景、AI提升解析度(更多陆续更新..) 4 | 5 | 您可以在任意网页端快速嵌入该工具【任意图片上传框、表单、后台等等】,即可实现无缝AI图像处理体验。 6 | 7 | 详见 [Github 文档](https://github.com/lambortao/PixPro)。 8 | 9 | ## 安装 10 | 11 | ```bash 12 | npm install @pixpro/core 13 | ``` 14 | 15 | ## 基本使用 16 | 17 | ```typescript 18 | import PixPro from '@pixpro/core'; 19 | 20 | const pixpro = new PixPro(document.getElementById('container'), { 21 | token: 'your-api-token', 22 | host: 'https://api.your-service.com', 23 | routes: '/api', 24 | action: { 25 | extend: '/extend', 26 | erase: '/erase', 27 | removeBg: '/remove-background', 28 | hd: '/enhance-resolution' 29 | } 30 | }); 31 | ``` -------------------------------------------------------------------------------- /packages/pixpro-core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pixpro/core", 3 | "version": "0.1.14", 4 | "description": "图片处理底层库,提供裁剪、缩放、AI 扩图等功能", 5 | "type": "module", 6 | "main": "dist/index.js", 7 | "module": "dist/index.esm.js", 8 | "types": "dist/index.d.ts", 9 | "files": [ 10 | "dist" 11 | ], 12 | "scripts": { 13 | "build": "rollup -c", 14 | "prepublishOnly": "npm run build" 15 | }, 16 | "publishConfig": { 17 | "access": "public" 18 | }, 19 | "keywords": [ 20 | "image", 21 | "processing", 22 | "AI", 23 | "crop", 24 | "resize" 25 | ], 26 | "author": "Lambortao", 27 | "license": "MIT", 28 | "dependencies": { 29 | "compressorjs": "^1.2.1", 30 | "lodash-es": "^4.17.21", 31 | "uuid": "^11.0.5" 32 | }, 33 | "devDependencies": { 34 | "@rollup/plugin-alias": "^5.1.0", 35 | "@rollup/plugin-commonjs": "^25.0.0", 36 | "@rollup/plugin-node-resolve": "^15.0.0", 37 | "@rollup/plugin-terser": "^0.4.0", 38 | "@rollup/plugin-typescript": "^11.0.0", 39 | "rollup": "^4.0.0", 40 | "rollup-plugin-postcss": "^4.0.2", 41 | "typescript": "^5.7.2" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/pixpro-core/rollup.config.mjs: -------------------------------------------------------------------------------- 1 | import typescript from '@rollup/plugin-typescript'; 2 | import resolve from '@rollup/plugin-node-resolve'; 3 | import commonjs from '@rollup/plugin-commonjs'; 4 | import terser from '@rollup/plugin-terser'; 5 | import alias from '@rollup/plugin-alias'; 6 | import postcss from 'rollup-plugin-postcss'; 7 | import { fileURLToPath } from 'url'; 8 | import { dirname, resolve as resolvePath } from 'path'; 9 | 10 | const __filename = fileURLToPath(import.meta.url); 11 | const __dirname = dirname(__filename); 12 | 13 | export default { 14 | input: 'src/index.ts', 15 | output: [ 16 | { 17 | file: 'dist/index.js', 18 | format: 'cjs', 19 | sourcemap: true 20 | }, 21 | { 22 | file: 'dist/index.esm.js', 23 | format: 'esm', 24 | sourcemap: true 25 | }, 26 | { 27 | file: 'dist/index.min.js', 28 | format: 'umd', 29 | name: 'PixPro', 30 | plugins: [terser()], 31 | sourcemap: true 32 | } 33 | ], 34 | plugins: [ 35 | alias({ 36 | entries: [ 37 | { find: '@', replacement: resolvePath(__dirname, 'src') } 38 | ] 39 | }), 40 | postcss({ 41 | extensions: ['.css'], 42 | extract: false, 43 | modules: false, 44 | inject: true, 45 | minimize: true 46 | }), 47 | typescript({ 48 | tsconfig: './tsconfig.json' 49 | }), 50 | resolve(), 51 | commonjs() 52 | ], 53 | external: ['compressorjs', 'lodash-es', 'uuid'] 54 | }; -------------------------------------------------------------------------------- /packages/pixpro-core/src/ai/ai-background.ts: -------------------------------------------------------------------------------- 1 | export function aiBackground() { } 2 | -------------------------------------------------------------------------------- /packages/pixpro-core/src/ai/ai-compress.ts: -------------------------------------------------------------------------------- 1 | export function aiCompress() { } 2 | -------------------------------------------------------------------------------- /packages/pixpro-core/src/ai/ai-enhanceResolution.ts: -------------------------------------------------------------------------------- 1 | export function aiEnhanceResolution() { } 2 | -------------------------------------------------------------------------------- /packages/pixpro-core/src/ai/ai-erase.ts: -------------------------------------------------------------------------------- 1 | export function aiErase() { } 2 | -------------------------------------------------------------------------------- /packages/pixpro-core/src/ai/ai-expand.ts: -------------------------------------------------------------------------------- 1 | export function aiExpand() { } 2 | -------------------------------------------------------------------------------- /packages/pixpro-core/src/assets/style.css.d.ts: -------------------------------------------------------------------------------- 1 | declare const styles: string; 2 | export default styles; -------------------------------------------------------------------------------- /packages/pixpro-core/src/config/default.ts: -------------------------------------------------------------------------------- 1 | import type { IDrawCanvasInfo } from '../types/IType'; 2 | 3 | export const startStepInfo: IDrawCanvasInfo = { 4 | imgId: '', 5 | gripper: 'body', 6 | mode: 'crop', 7 | moveX: 0, 8 | moveY: 0, 9 | cropBoxWidth: 0, 10 | cropBoxHeight: 0, 11 | fenceMaxWidth: 0, 12 | fenceMaxHeight: 0, 13 | fenceMinWidth: 0, 14 | fenceMinHeight: 0, 15 | cropRatio: null, 16 | cropRationLabel: 'none', 17 | cdProportions: 1, 18 | currentDomWidth: 0, 19 | currentDomHeight: 0, 20 | xCropOffset: 0, 21 | yCropOffset: 0, 22 | xDomOffset: 0, 23 | yDomOffset: 0, 24 | rawImgWidth: 0, 25 | rawImgHeight: 0, 26 | rawDomWidth: 0, 27 | rawDomHeight: 0, 28 | domWidth: 0, 29 | domHeight: 0, 30 | dWidth: 0, 31 | dHeight: 0, 32 | sWidth: 0, 33 | sHeight: 0, 34 | dx: 0, 35 | dy: 0, 36 | sx: 0, 37 | sy: 0, 38 | flipX: 1, 39 | flipY: 1 40 | } -------------------------------------------------------------------------------- /packages/pixpro-core/src/global.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.css' { 2 | const content: string; 3 | export default content; 4 | } -------------------------------------------------------------------------------- /packages/pixpro-core/src/types/libs.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'lodash-es'; 2 | declare module '*.css?inline' { 3 | const content: string; 4 | export default content; 5 | } 6 | 7 | declare module 'pngjs'; -------------------------------------------------------------------------------- /packages/pixpro-core/src/utils/cache/constants.ts: -------------------------------------------------------------------------------- 1 | export const TRACEIDIMF = "traceIdInformation"; 2 | -------------------------------------------------------------------------------- /packages/pixpro-core/src/utils/cache/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 璐 Lu.xu@brandsh.cn 3 | * @Date: 2025-03-26 11:51:46 4 | * @LastEditors: 璐 Lu.xu@brandsh.cn 5 | * @LastEditTime: 2025-03-26 12:06:17 6 | * @FilePath: /pixpro/utils/cache/index.ts 7 | * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE 8 | */ 9 | 10 | enum CacheType { 11 | Local = "local", 12 | Session = "session", 13 | } 14 | 15 | class Cache { 16 | storage: Storage; 17 | constructor(type: CacheType) { 18 | this.storage = type === CacheType.Local ? localStorage : sessionStorage; 19 | } 20 | 21 | setCache(key: string, value: any) { 22 | if (value) { 23 | this.storage.setItem(key, JSON.stringify(value)); 24 | } 25 | } 26 | 27 | getCache(key: string) { 28 | const value = this.storage.getItem(key); 29 | try { 30 | return JSON.parse(value as string); 31 | } catch (error) { 32 | return value; 33 | } 34 | } 35 | 36 | removeCache(key: string) { 37 | this.storage.removeItem(key); 38 | } 39 | 40 | clear() { 41 | this.storage.clear(); 42 | } 43 | } 44 | 45 | const localCache = new Cache(CacheType.Local); 46 | const sessionCache = new Cache(CacheType.Session); 47 | 48 | export { localCache, sessionCache }; 49 | -------------------------------------------------------------------------------- /packages/pixpro-core/src/utils/imageData.ts: -------------------------------------------------------------------------------- 1 | /** 记录图片数据 */ 2 | class ImageData { 3 | 4 | public static getInstance() { 5 | return new ImageData(); 6 | } 7 | } 8 | 9 | export default ImageData.getInstance(); 10 | -------------------------------------------------------------------------------- /packages/pixpro-core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "ESNext", 5 | "moduleResolution": "node", 6 | "esModuleInterop": true, 7 | "strict": true, 8 | "declaration": true, 9 | "declarationDir": "dist", 10 | "outDir": "dist", 11 | "skipLibCheck": true, 12 | "sourceMap": true, 13 | "baseUrl": ".", 14 | "paths": { 15 | "@/*": ["src/*"] 16 | } 17 | }, 18 | "include": ["src/**/*"], 19 | "exclude": ["node_modules", "dist"] 20 | } -------------------------------------------------------------------------------- /packages/pixpro-js/src/css/AddNewColor.css: -------------------------------------------------------------------------------- 1 | .add-color-item { 2 | width: 50px; 3 | height: 50px; 4 | border-radius: 6px; 5 | cursor: pointer; 6 | border: 2px solid transparent; 7 | padding: 3px; 8 | box-sizing: border-box; 9 | position: relative; 10 | } 11 | .add-color-item span { 12 | display: flex; 13 | align-items: center; 14 | justify-content: center; 15 | box-sizing: border-box; 16 | border: 1px solid #cdd5dd; 17 | width: 100%; 18 | height: 100%; 19 | border-radius: 6px; 20 | overflow: hidden; 21 | background: linear-gradient(to bottom, #f9f9f9, #ffffff); 22 | } 23 | .add-color-item .color-select { 24 | box-sizing: border-box; 25 | padding: 10px; 26 | border-radius: 8px; 27 | position: absolute; 28 | width: 180px; 29 | top: 0px; 30 | left: 50px; 31 | z-index: 9999; 32 | cursor: auto; 33 | box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2); 34 | background-color: #fff; 35 | } 36 | .add-color-item .color-select input { 37 | cursor: pointer; 38 | width: 100%; 39 | } 40 | .add-color-item .color-select p { 41 | font-size: 12px; 42 | color: #666; 43 | margin: 0 0 5px; 44 | text-align: center; 45 | } 46 | 47 | .add-color-item .color-select footer { 48 | display: flex; 49 | justify-content: space-between; 50 | gap: 5px; 51 | } 52 | .add-color-item .color-select footer .toolbar-btn { 53 | width: 100%; 54 | padding: 5px 10px !important; 55 | margin-top: 10px !important; 56 | } 57 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/css/ColoredBtn.css: -------------------------------------------------------------------------------- 1 | /* ColoredBtn 样式 */ 2 | .colored-btn { 3 | margin: 20px auto; 4 | width: 128px; 5 | height: 36px; 6 | border-radius: 8px; 7 | border: none; 8 | color: #fff; 9 | background: linear-gradient(to right, #184aff 0%, #fc9bff 100%); 10 | display: flex; 11 | align-items: center; 12 | justify-content: center; 13 | gap: 4px; 14 | cursor: pointer; 15 | transition: all 0.3s ease; 16 | } 17 | 18 | .colored-btn svg { 19 | color: #fff; 20 | } 21 | 22 | .colored-btn:active { 23 | transform: scale(0.97); 24 | } 25 | 26 | .colored-btn:disabled { 27 | background: #ccc; 28 | cursor: not-allowed; 29 | } 30 | 31 | .colored-btn.loading { 32 | opacity: 0.7; 33 | } 34 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/css/EraserSizeSlider.css: -------------------------------------------------------------------------------- 1 | small { 2 | display: block; 3 | margin: 20px 0 10px; 4 | } 5 | 6 | input { 7 | width: 100%; 8 | -webkit-appearance: none; /* Safari */ 9 | appearance: none; 10 | height: 6px; 11 | border-radius: 3px; 12 | outline: none; 13 | opacity: 1; 14 | transition: opacity 0.2s; 15 | } 16 | 17 | input::-webkit-slider-thumb { 18 | -webkit-appearance: none; /* Safari */ 19 | appearance: none; 20 | width: 16px; 21 | height: 16px; 22 | border-radius: 50%; 23 | background: #4878ef; 24 | cursor: pointer; 25 | } 26 | 27 | input::-moz-range-thumb { 28 | width: 16px; 29 | height: 16px; 30 | border-radius: 50%; 31 | background: #4878ef; 32 | cursor: pointer; 33 | } 34 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/css/SvgIcon.css: -------------------------------------------------------------------------------- 1 | .svg-icon { 2 | display: flex; 3 | align-items: center; 4 | justify-content: center; 5 | } 6 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/11.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/169.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/43.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/916.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/compress-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/crop-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/erase-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/expand-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/flip-l.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/flip-r.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/flip-x.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/flip-y.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/original.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/pointer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/remove-bg-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/icon/step.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-js/src/img/loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/packages/pixpro-js/src/img/loading.png -------------------------------------------------------------------------------- /packages/pixpro-js/src/js/config.js: -------------------------------------------------------------------------------- 1 | export const controlTextData = { 2 | crop: { 3 | btn: "裁切", 4 | title: "裁切", 5 | desc: "", 6 | icon: "crop-btn", 7 | }, 8 | expand: { 9 | btn: "扩图", 10 | title: "扩图", 11 | desc: "向外扩展图片,AI将填充图片以外的部分", 12 | icon: "expand-btn", 13 | }, 14 | erase: { 15 | btn: "擦除", 16 | title: "擦除", 17 | desc: "涂抹想要从图片中擦除的区域", 18 | icon: "erase-btn", 19 | }, 20 | "remove-bg": { 21 | btn: "移除背景", 22 | title: "移除背景", 23 | desc: "一键抠出图片中的主体", 24 | icon: "remove-bg-btn", 25 | }, 26 | hd: { 27 | btn: "提升解析度", 28 | title: "提升解析度", 29 | desc: "立即提提升图片解析度", 30 | icon: "hd-btn", 31 | }, 32 | compress: { 33 | btn: "压缩容量", 34 | title: "压缩容量", 35 | desc: "在保证图片质量的基础上,有效降低图片的容量", 36 | icon: "compress-btn", 37 | }, 38 | }; 39 | 40 | export const cropControlData = { 41 | original: 0, 42 | "1:1": 1, 43 | "4:3": 4 / 3, 44 | "16:9": 16 / 9, 45 | "9:16": 9 / 16, 46 | }; 47 | 48 | /** 颜色列表 */ 49 | export const colorListData = ["transparent", "#ffffff", "#e3e9ef", "#dbe9fd", "#afc5c1", "#a2e1c9", "#4067c5", "#0b209f", "#4041c3", "#27297e", "#5a335f", "#d74f3c", "#ebaacb", "#fbe8e3", "#f3e48b", "#ccef7a", "#75c097", "#62b6b0", "#6de9b0", "#83c8df"]; 50 | -------------------------------------------------------------------------------- /packages/pixpro-js/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import path from "path"; 3 | 4 | export default defineConfig({ 5 | server: { 6 | port: 3000, 7 | open: true, 8 | }, 9 | resolve: { 10 | alias: { 11 | "@": path.resolve(__dirname, "../../src"), 12 | }, 13 | }, 14 | optimizeDeps: { 15 | include: ["@/index"], 16 | }, 17 | publicDir: "public", 18 | build: { 19 | outDir: "dist", 20 | assetsDir: "", 21 | assetsInlineLimit: 4096, 22 | rollupOptions: { 23 | input: { 24 | main: path.resolve(__dirname, "index.html"), 25 | }, 26 | output: { 27 | entryFileNames: "[name].[hash].js", 28 | chunkFileNames: "[name].[hash].js", 29 | assetFileNames: "[name].[hash].[ext]", 30 | }, 31 | }, 32 | }, 33 | assetsInclude: ["**/*.svg"], 34 | }); 35 | -------------------------------------------------------------------------------- /packages/pixpro-react/README.md: -------------------------------------------------------------------------------- 1 | # PixPro AI图片处理库(AI Image Processing Library) 2 | 3 | PixPro 是一个图片处理工具,提供了图片处理的基础功能,如常用的裁剪、等比例缩放、翻转、镜像、旋转等功能。同时,PixPro 还嵌入了各类第三方的AI图像处理能力,例如AI 扩图、AI擦除、AI去背景、AI提升解析度(更多陆续更新..) 4 | 5 | 您可以在任意网页端快速嵌入该工具【任意图片上传框、表单、后台等等】,即可实现无缝AI图像处理体验。 6 | 7 | 详见 [Github 文档](https://github.com/lambortao/PixPro)。 8 | 9 | ## 安装 10 | 11 | ```bash 12 | npm install @pixpro/react 13 | ``` 14 | 15 | ## 使用方法 16 | ```tsx 17 | import { PixProReact } from "@pixpro/react"; 18 | import "@pixpro/react/dist/style.css"; 19 | 20 | const [pixProAttrs, setPixProAttrs] = useState({ 21 | cropRatios: { 22 | original: 0, 23 | "1:1": 1, 24 | "3:4": 3 / 4, 25 | "4:3": 4 / 3, 26 | "9:16": 9 / 16, 27 | "16:9": 16 / 9, 28 | }, 29 | host: "xxx", 30 | routes: "/image/processing", 31 | token: "", 32 | fitstImage: null as File | null, 33 | showDownloadBtn: true, 34 | eraserSize: { 35 | min: 20, 36 | max: 100, 37 | default: 50, 38 | }, 39 | }); 40 | 41 | return ( 42 | 43 | ) 44 | 45 | 51 | ``` 52 | -------------------------------------------------------------------------------- /packages/pixpro-react/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Pix Pro For React Example 7 | 8 | 9 |
10 | 11 | 12 | 19 | 20 | -------------------------------------------------------------------------------- /packages/pixpro-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pixpro/react", 3 | "version": "0.1.1", 4 | "description": "PixPro 的 React UI 组件库", 5 | "type": "module", 6 | "main": "dist/index.umd.js", 7 | "module": "dist/index.es.js", 8 | "types": "dist/index.d.ts", 9 | "style": "dist/index.css", 10 | "files": [ 11 | "dist" 12 | ], 13 | "scripts": { 14 | "build": "vite build", 15 | "prepublishOnly": "npm run build" 16 | }, 17 | "publishConfig": { 18 | "access": "public" 19 | }, 20 | "keywords": [ 21 | "pixpro", 22 | "react", 23 | "image", 24 | "processing", 25 | "editor", 26 | "component" 27 | ], 28 | "author": "", 29 | "license": "MIT", 30 | "peerDependencies": { 31 | "react": "^18.0.0", 32 | "react-dom": "^18.0.0" 33 | }, 34 | "dependencies": { 35 | "@pixpro/core": "^0.1.14", 36 | "lodash-es": "^4.17.21" 37 | }, 38 | "devDependencies": { 39 | "@types/node": "^20.0.0", 40 | "@vitejs/plugin-react": "^3.0.0", 41 | "less": "^4.2.0", 42 | "terser": "^5.39.0", 43 | "typescript": "^5.2.0", 44 | "vite": "^5.0.0", 45 | "vite-plugin-dts": "^3.7.0" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/App.css: -------------------------------------------------------------------------------- 1 | .fade-enter-active, 2 | .fade-leave-active { 3 | transition: opacity 0.2s ease; 4 | } 5 | 6 | .fade-enter-from, 7 | .fade-leave-to { 8 | opacity: 0; 9 | } 10 | 11 | .upload-container { 12 | padding: 20px; 13 | } 14 | 15 | .upload-button { 16 | padding: 12px 24px; 17 | font-size: 16px; 18 | cursor: pointer; 19 | } 20 | 21 | .upload-button .el-icon { 22 | margin-right: 8px; 23 | } 24 | 25 | .export-img-box { 26 | max-width: 80vw; 27 | max-height: 80vw; 28 | margin: 20px auto; 29 | overflow: hidden; 30 | } 31 | 32 | .export-img-box img { 33 | max-width: 100%; 34 | max-height: 100%; 35 | } 36 | 37 | .buttons-container { 38 | display: flex; 39 | justify-content: center; 40 | align-items: center; 41 | margin-top: 20px; 42 | } 43 | 44 | .buttons-container .action-btn { 45 | margin: 0 10px; 46 | } 47 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/AddNewColor.tsx: -------------------------------------------------------------------------------- 1 | import React, { useRef } from "react"; 2 | import SvgIcon from "./SvgIcon"; 3 | import "./AddNewColor.less"; 4 | 5 | interface AddNewColorProps { 6 | value: boolean; 7 | onChange: (color: string) => void; 8 | onOpen: () => void; 9 | onRemove?: (color: string) => void; 10 | localColorList?: string[]; 11 | currentColor?: string; 12 | } 13 | 14 | const AddNewColor: React.FC = ({ value, onChange, onOpen }) => { 15 | const inputRef = useRef(null); 16 | 17 | const handleClick = () => { 18 | onOpen(); 19 | }; 20 | 21 | const handleConfirm = () => { 22 | const color = inputRef.current?.value; 23 | if (color) { 24 | onChange(color); 25 | } 26 | }; 27 | 28 | const handleCancel = () => { 29 | onChange(""); 30 | }; 31 | 32 | return ( 33 |
34 | 35 | 36 | 37 | {value && ( 38 |
39 |

点击色块选择颜色

40 | 41 |
42 | 45 | 48 |
49 |
50 | )} 51 |
52 | ); 53 | }; 54 | 55 | export default AddNewColor; 56 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/AiLoading.less: -------------------------------------------------------------------------------- 1 | .loader-container { 2 | position: relative; 3 | overflow: hidden; 4 | background-color: transparent; 5 | position: relative; 6 | } 7 | 8 | .animated-image { 9 | position: absolute; 10 | top: 50%; 11 | left: 50%; 12 | animation: complexAnimation 12s infinite linear; 13 | transform-origin: center center; 14 | min-width: 2000px; 15 | min-height: 2000px; 16 | will-change: transform; /* 优化动画性能 */ 17 | } 18 | 19 | .center-loading { 20 | position: absolute; 21 | top: 50%; 22 | left: 50%; 23 | transform: translate(-50%, -50%); 24 | } 25 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/ColoredBtn.less: -------------------------------------------------------------------------------- 1 | @import "./assets/style/_constant.less"; 2 | 3 | .colored-btn-component { 4 | button { 5 | margin: 20px auto; 6 | width: 128px; 7 | height: 36px; 8 | border-radius: @radius; 9 | border: none; 10 | color: #fff; 11 | background: linear-gradient(to right, #184aff 0%, #fc9bff 100%); 12 | display: flex; 13 | align-items: center; 14 | justify-content: center; 15 | gap: 4px; 16 | cursor: pointer; 17 | .ani300; 18 | 19 | :deep(svg) { 20 | color: #fff; 21 | } 22 | 23 | &:active { 24 | transform: scale(0.97); 25 | } 26 | 27 | &:disabled { 28 | background: #ccc; 29 | cursor: not-allowed; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/ColoredBtn.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import SvgIcon from "./SvgIcon"; 3 | import "./assets/style/_constant.less"; 4 | import "./ColoredBtn.less"; 5 | 6 | interface ColoredBtnProps { 7 | text: string; 8 | icon?: string; 9 | disabled?: boolean; 10 | loading?: boolean; 11 | onClick: () => void; 12 | } 13 | 14 | const ColoredBtn: React.FC = ({ text, icon = "expand-btn", disabled = false, loading = false, onClick }) => { 15 | return ( 16 |
17 | 21 |
22 | ); 23 | }; 24 | 25 | export default ColoredBtn; 26 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/EraserSizeSlider.css: -------------------------------------------------------------------------------- 1 | small { 2 | display: block; 3 | margin: 20px 0 10px; 4 | } 5 | 6 | input { 7 | width: 100%; 8 | -webkit-appearance: none; /* Safari */ 9 | appearance: none; 10 | height: 6px; 11 | border-radius: 3px; 12 | outline: none; 13 | opacity: 1; 14 | transition: opacity 0.2s; 15 | } 16 | 17 | input::-webkit-slider-thumb { 18 | -webkit-appearance: none; /* Safari */ 19 | appearance: none; 20 | width: 16px; 21 | height: 16px; 22 | border-radius: 50%; 23 | background: #4878ef; 24 | cursor: pointer; 25 | } 26 | 27 | input::-moz-range-thumb { 28 | width: 16px; 29 | height: 16px; 30 | border-radius: 50%; 31 | background: #4878ef; 32 | cursor: pointer; 33 | } 34 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/SvgIcon.css: -------------------------------------------------------------------------------- 1 | .svg-icon { 2 | display: flex; 3 | align-items: center; 4 | justify-content: center; 5 | } 6 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/_constant.less: -------------------------------------------------------------------------------- 1 | @primary-color: #184aff; 2 | @radius: 8px; 3 | @selected-bgc: #e6e6e6; 4 | @border-color: #e8e8e8; 5 | 6 | .ani300 { 7 | transition: all 0.3s ease; 8 | } 9 | 10 | .btn-line { 11 | position: relative; 12 | &:before { 13 | content: ""; 14 | display: block; 15 | width: 1px; 16 | height: 60%; 17 | background-color: #e0e5ea; 18 | position: absolute; 19 | right: 0; 20 | top: 50%; 21 | transform: translateY(-50%); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/icon/11.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/icon/169.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/icon/43.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/icon/916.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/icon/add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/icon/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/icon/compress-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/icon/crop-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/icon/erase-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/icon/expand-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/icon/flip-l.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/icon/flip-r.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/icon/flip-x.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/icon/flip-y.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/icon/original.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/icon/pointer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/icon/step.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/image/loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/packages/pixpro-react/src/PixProSkin/assets/image/loading.png -------------------------------------------------------------------------------- /packages/pixpro-react/src/PixProSkin/assets/style/_constant.less: -------------------------------------------------------------------------------- 1 | @primary-color: #184aff; 2 | @radius: 8px; 3 | @selected-bgc: #e6e6e6; 4 | @border-color: #e8e8e8; 5 | 6 | .ani300 { 7 | transition: all 0.3s ease; 8 | } 9 | 10 | .btn-line { 11 | position: relative; 12 | &:before { 13 | content: ""; 14 | display: block; 15 | width: 1px; 16 | height: 60%; 17 | background-color: #e0e5ea; 18 | position: absolute; 19 | right: 0; 20 | top: 50%; 21 | transform: translateY(-50%); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | declare module '*.svg?raw' { 5 | const content: string; 6 | export default content; 7 | } 8 | 9 | declare module '*.jpg' { 10 | const src: string; 11 | export default src; 12 | } 13 | 14 | declare module '*.png' { 15 | const src: string; 16 | export default src; 17 | } 18 | 19 | declare module '*.less' { 20 | const classes: { readonly [key: string]: string }; 21 | export default classes; 22 | } 23 | 24 | declare module '*.css' { 25 | const classes: { readonly [key: string]: string }; 26 | export default classes; 27 | } -------------------------------------------------------------------------------- /packages/pixpro-react/src/index.css: -------------------------------------------------------------------------------- 1 | /* 全局样式 */ 2 | * { 3 | margin: 0; 4 | padding: 0; 5 | box-sizing: border-box; 6 | } 7 | 8 | body { 9 | margin: 0; 10 | padding: 0; 11 | } 12 | 13 | /* App 容器样式 */ 14 | .app-container { 15 | /* width: 100vw; 16 | height: 100vh; */ 17 | overflow: hidden; 18 | } 19 | 20 | .box { 21 | width: 100%; 22 | height: 100%; 23 | padding: 60px 40px; 24 | box-sizing: border-box; 25 | overflow: hidden; 26 | } 27 | 28 | .export-img-box { 29 | position: fixed; 30 | top: 0; 31 | left: 0; 32 | right: 0; 33 | bottom: 0; 34 | background-color: rgba(0, 0, 0, 0.5); 35 | padding: 46px; 36 | box-sizing: border-box; 37 | z-index: 3; 38 | display: flex; 39 | justify-content: center; 40 | align-items: center; 41 | } 42 | 43 | .export-img-box img { 44 | max-width: 80%; 45 | max-height: 80%; 46 | } 47 | 48 | .loading-mask { 49 | position: fixed; 50 | top: 0; 51 | left: 0; 52 | right: 0; 53 | bottom: 0; 54 | background-color: rgba(0, 0, 0, 0.5); 55 | display: flex; 56 | justify-content: center; 57 | align-items: center; 58 | z-index: 1000; 59 | } 60 | 61 | .loading-spinner { 62 | color: #fff; 63 | font-size: 16px; 64 | } 65 | -------------------------------------------------------------------------------- /packages/pixpro-react/src/index.ts: -------------------------------------------------------------------------------- 1 | import PixProReact from './PixProVue'; 2 | import { type ICropRatio, type IDrawCanvasInfo, type IImageMode } from '@pixpro/core'; 3 | import './PixProSkin/assets/style/index.less'; 4 | 5 | // 导出组件 6 | export { PixProReact, ICropRatio, IDrawCanvasInfo, IImageMode }; -------------------------------------------------------------------------------- /packages/pixpro-react/src/main.tsx: -------------------------------------------------------------------------------- 1 | // import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import App from "./App"; 4 | import "./index.css"; 5 | 6 | ReactDOM.createRoot(document.getElementById("root")!).render(); 7 | -------------------------------------------------------------------------------- /packages/pixpro-react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | "moduleResolution": "bundler", 9 | "allowImportingTsExtensions": true, 10 | "resolveJsonModule": true, 11 | "isolatedModules": true, 12 | "noEmit": true, 13 | "jsx": "react-jsx", 14 | "strict": true, 15 | "noUnusedLocals": true, 16 | "noUnusedParameters": true, 17 | "noFallthroughCasesInSwitch": true, 18 | "types": [], 19 | "baseUrl": ".", 20 | "paths": { 21 | "@/*": ["../../src/*"] 22 | } 23 | }, 24 | "include": ["src"], 25 | "references": [{ "path": "./tsconfig.node.json" }] 26 | } 27 | -------------------------------------------------------------------------------- /packages/pixpro-react/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/pixpro-react/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | import path from 'path'; 4 | import dts from 'vite-plugin-dts'; 5 | 6 | export default defineConfig({ 7 | build: { 8 | lib: { 9 | entry: path.resolve(__dirname, 'src/index.ts'), // 你的入口 10 | name: 'PixProReact', // UMD 模式下的全局变量名,可随便填 11 | fileName: (format) => `index.${format}.js`, // 控制输出的文件名 12 | formats: ['es', 'cjs'], // 输出两种格式,供主流工具使用 13 | }, 14 | rollupOptions: { 15 | // 这些依赖在使用时由外部项目提供,不要打包进去 16 | external: ['react', 'react-dom'], 17 | }, 18 | outDir: 'dist', // 输出目录 19 | emptyOutDir: true, // 每次构建前清空 20 | }, 21 | plugins: [ 22 | react(), 23 | dts({ 24 | insertTypesEntry: true, 25 | }) 26 | ], 27 | assetsInclude: ['**/*.svg'], 28 | css: { 29 | preprocessorOptions: { 30 | less: { 31 | javascriptEnabled: true, 32 | }, 33 | }, 34 | }, 35 | server: { 36 | port: 1220, 37 | open: true, 38 | host: true, 39 | proxy: { 40 | '^/api/.*': { 41 | target: 'https://pixpro.brandsh.cn', 42 | changeOrigin: true 43 | } 44 | } 45 | }, 46 | resolve: { 47 | alias: { 48 | '@': path.resolve(__dirname, '../../src'), 49 | }, 50 | } 51 | }); -------------------------------------------------------------------------------- /packages/pixpro-vue/README.md: -------------------------------------------------------------------------------- 1 | # PixPro AI图片处理库(AI Image Processing Library) 2 | 3 | PixPro 是一个图片处理工具,提供了图片处理的基础功能,如常用的裁剪、等比例缩放、翻转、镜像、旋转等功能。同时,PixPro 还嵌入了各类第三方的AI图像处理能力,例如AI 扩图、AI擦除、AI去背景、AI提升解析度(更多陆续更新..) 4 | 5 | 您可以在任意网页端快速嵌入该工具【任意图片上传框、表单、后台等等】,即可实现无缝AI图像处理体验。 6 | 7 | 详见 [Github 文档](https://github.com/lambortao/PixPro)。 8 | 9 | ## 安装 10 | 11 | ```bash 12 | npm install @pixpro/vue 13 | ``` 14 | 15 | ## 使用方法 16 | ```vue 17 | 28 | 29 | 46 | 47 | 53 | ``` 54 | -------------------------------------------------------------------------------- /packages/pixpro-vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pixpro/vue", 3 | "version": "0.1.16", 4 | "description": "PixPro 的 Vue 3 UI 组件库", 5 | "type": "module", 6 | "main": "dist/index.umd.js", 7 | "module": "dist/index.es.js", 8 | "types": "dist/index.d.ts", 9 | "style": "dist/index.css", 10 | "exports": { 11 | ".": { 12 | "import": "./dist/index.es.js", 13 | "require": "./dist/index.umd.js", 14 | "types": "./dist/index.d.ts", 15 | "style": "./dist/index.css" 16 | }, 17 | "./dist/index.css": "./dist/index.css" 18 | }, 19 | "files": [ 20 | "dist" 21 | ], 22 | "scripts": { 23 | "build": "vite build", 24 | "prepublishOnly": "npm run build" 25 | }, 26 | "publishConfig": { 27 | "access": "public" 28 | }, 29 | "keywords": [ 30 | "pixpro", 31 | "vue", 32 | "image", 33 | "processing", 34 | "editor", 35 | "component" 36 | ], 37 | "author": "", 38 | "license": "MIT", 39 | "peerDependencies": { 40 | "vue": "^3.3.0" 41 | }, 42 | "dependencies": { 43 | "@pixpro/core": "^0.1.14", 44 | "lodash-es": "^4.17.21" 45 | }, 46 | "devDependencies": { 47 | "@types/node": "^20.0.0", 48 | "@vitejs/plugin-vue": "^5.0.0", 49 | "less": "^4.2.0", 50 | "terser": "^5.39.0", 51 | "typescript": "^5.2.0", 52 | "vite": "^5.0.0", 53 | "vite-plugin-dts": "^3.7.0", 54 | "vue": "^3.3.0" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/11.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/169.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/43.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/916.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/ai-loading.lottie: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/packages/pixpro-vue/src/PixProSkin/assets/icon/ai-loading.lottie -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/compress-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/crop-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/erase-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/expand-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/flip-l.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/flip-r.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/flip-x.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/flip-y.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/original.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/pointer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/icon/step.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/images/loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/packages/pixpro-vue/src/PixProSkin/assets/images/loading.png -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/assets/style/_constant.less: -------------------------------------------------------------------------------- 1 | @primary-color: #184aff; 2 | @radius: 8px; 3 | @selected-bgc: #e6e6e6; 4 | @border-color: #e8e8e8; 5 | 6 | .ani300 { 7 | transition: all 0.3s ease; 8 | } 9 | 10 | .btn-line { 11 | position: relative; 12 | &:before { 13 | content: ''; 14 | display: block; 15 | width: 1px; 16 | height: 60%; 17 | background-color: #E0E5EA; 18 | position: absolute; 19 | right: 0; 20 | top: 50%; 21 | transform: translateY(-50%); 22 | } 23 | } -------------------------------------------------------------------------------- /packages/pixpro-vue/src/PixProSkin/components/ColoredBtn.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 33 | 34 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/index.ts: -------------------------------------------------------------------------------- 1 | import PixProVue from './PixProVue.vue'; 2 | import { type ICropRatio, type IDrawCanvasInfo, type IImageMode } from '@pixpro/core'; 3 | import PixProVuePlugin from './plugin'; 4 | import './styles/index.less'; 5 | 6 | // 导出组件 7 | export { PixProVue, ICropRatio, IDrawCanvasInfo, IImageMode }; 8 | 9 | // 导出默认插件 10 | export default PixProVuePlugin; 11 | -------------------------------------------------------------------------------- /packages/pixpro-vue/src/plugin.ts: -------------------------------------------------------------------------------- 1 | import { App } from 'vue'; 2 | import { PixProVue } from './index'; 3 | 4 | // 导入样式 5 | import './styles/index.less'; 6 | 7 | // 创建Vue插件 8 | export default { 9 | install: (app: App) => { 10 | // 全局注册组件 11 | app.component('PixProVue', PixProVue); 12 | } 13 | }; -------------------------------------------------------------------------------- /packages/pixpro-vue/src/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import type { DefineComponent } from 'vue' 3 | const component: DefineComponent<{}, {}, any> 4 | export default component 5 | } -------------------------------------------------------------------------------- /packages/pixpro-vue/src/styles/index.less: -------------------------------------------------------------------------------- 1 | /* 导入所有组件样式 */ 2 | @import '../PixProSkin/assets/style/index.less'; 3 | @import '../PixProSkin/assets/style/_constant.less'; 4 | 5 | /* 提示用户在使用时单独引入 core 样式 */ 6 | /* 使用时需要自行引入 @pixpro/core/dist/style.css */ -------------------------------------------------------------------------------- /packages/pixpro-vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "preserve", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true, 22 | 23 | /* Paths */ 24 | "baseUrl": ".", 25 | "paths": { 26 | "@/*": ["src/*"] 27 | } 28 | }, 29 | "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], 30 | "exclude": ["node_modules", "dist"] 31 | } -------------------------------------------------------------------------------- /packages/pixpro-vue/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } -------------------------------------------------------------------------------- /packages/pixpro-vue2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Pix Pro For Vue Example 8 | 9 | 10 | 11 |
12 | 13 | 14 | 21 | 22 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pixpro/vue2", 3 | "version": "0.1.0", 4 | "description": "PixPro 的 Vue 2 UI 组件库", 5 | "type": "module", 6 | "main": "dist/index.umd.js", 7 | "module": "dist/index.es.js", 8 | "style": "dist/index.css", 9 | "exports": { 10 | ".": { 11 | "import": "./dist/index.es.js", 12 | "require": "./dist/index.umd.js", 13 | "style": "./dist/index.css" 14 | }, 15 | "./dist/index.css": "./dist/index.css" 16 | }, 17 | "files": [ 18 | "dist" 19 | ], 20 | "scripts": { 21 | "build": "vite build", 22 | "prepublishOnly": "npm run build" 23 | }, 24 | "publishConfig": { 25 | "access": "public" 26 | }, 27 | "keywords": [ 28 | "pixpro", 29 | "vue", 30 | "image", 31 | "processing", 32 | "editor", 33 | "component" 34 | ], 35 | "author": "", 36 | "license": "MIT", 37 | "peerDependencies": { 38 | "vue": "^2.6.14" 39 | }, 40 | "dependencies": { 41 | "@pixpro/core": "^0.1.14", 42 | "lodash-es": "^4.17.21" 43 | }, 44 | "devDependencies": { 45 | "@types/node": "^20.0.0", 46 | "@vitejs/plugin-vue2": "^2.3.0", 47 | "less": "^4.2.0", 48 | "terser": "^5.39.0", 49 | "typescript": "^5.2.0", 50 | "vite": "^5.0.0", 51 | "vite-plugin-dts": "^3.7.0", 52 | "vue": "^2.6.14" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/11.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/169.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/43.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/916.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/ai-loading.lottie: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/packages/pixpro-vue2/src/PixProSkin/assets/icon/ai-loading.lottie -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/compress-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/crop-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/erase-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/expand-btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/flip-l.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/flip-r.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/flip-x.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/flip-y.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/original.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/pointer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/icon/step.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/images/loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambortao/PixPro/2905961996f2874ac0ef76e9e7bbba7ac290faa9/packages/pixpro-vue2/src/PixProSkin/assets/images/loading.png -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/assets/style/_constant.less: -------------------------------------------------------------------------------- 1 | @primary-color: #184aff; 2 | @radius: 8px; 3 | @selected-bgc: #e6e6e6; 4 | @border-color: #e8e8e8; 5 | 6 | .ani300 { 7 | transition: all 0.3s ease; 8 | } 9 | 10 | .btn-line { 11 | position: relative; 12 | &:before { 13 | content: ''; 14 | display: block; 15 | width: 1px; 16 | height: 60%; 17 | background-color: #E0E5EA; 18 | position: absolute; 19 | right: 0; 20 | top: 50%; 21 | transform: translateY(-50%); 22 | } 23 | } -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/PixProSkin/components/ColoredBtn.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 34 | 35 | 66 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/index.js: -------------------------------------------------------------------------------- 1 | import PixProVue from './PixProVue.vue'; 2 | import './PixProSkin/assets/style/index.less'; 3 | 4 | // 导出组件 5 | export { PixProVue }; 6 | -------------------------------------------------------------------------------- /packages/pixpro-vue2/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | 5 | new Vue({ 6 | render: h => h(App) 7 | }).$mount('#app') -------------------------------------------------------------------------------- /packages/pixpro-vue2/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import vue from '@vitejs/plugin-vue2'; 3 | import { resolve } from 'path'; 4 | 5 | export default defineConfig({ 6 | plugins: [ 7 | vue({ 8 | template: { 9 | compilerOptions: { 10 | isCustomElement: (tag) => tag === 'svg', 11 | }, 12 | }, 13 | }), 14 | ], 15 | resolve: { 16 | alias: { 17 | '@': resolve(__dirname, '../../src'), 18 | }, 19 | }, 20 | css: { 21 | modules: { 22 | scopeBehaviour: 'local', 23 | }, 24 | preprocessorOptions: { 25 | less: { 26 | javascriptEnabled: true, 27 | }, 28 | }, 29 | }, 30 | build: { 31 | lib: { 32 | entry: resolve(__dirname, 'src/index.js'), // 👈 你的组件入口文件 33 | name: 'PixProVue2', // UMD 打包时的全局变量名,可随便写 34 | fileName: (format) => `index.${format}.js`, // 输出的文件名规则 35 | formats: ['es', 'umd'], // 输出 ESModule + UMD 36 | }, 37 | rollupOptions: { 38 | external: ['vue'], // 👈 vue 不打进去,作为 peer 依赖 39 | }, 40 | outDir: 'dist', 41 | emptyOutDir: true, 42 | }, 43 | }); -------------------------------------------------------------------------------- /src/ai/ai-background.ts: -------------------------------------------------------------------------------- 1 | export function aiBackground() { } 2 | -------------------------------------------------------------------------------- /src/ai/ai-compress.ts: -------------------------------------------------------------------------------- 1 | export function aiCompress() { } 2 | -------------------------------------------------------------------------------- /src/ai/ai-enhanceResolution.ts: -------------------------------------------------------------------------------- 1 | export function aiEnhanceResolution() { } 2 | -------------------------------------------------------------------------------- /src/ai/ai-erase.ts: -------------------------------------------------------------------------------- 1 | export function aiErase() { } 2 | -------------------------------------------------------------------------------- /src/ai/ai-expand.ts: -------------------------------------------------------------------------------- 1 | export function aiExpand() { } 2 | -------------------------------------------------------------------------------- /src/assets/style.css.d.ts: -------------------------------------------------------------------------------- 1 | declare const styles: string; 2 | export default styles; -------------------------------------------------------------------------------- /src/config/default.ts: -------------------------------------------------------------------------------- 1 | import type { IDrawCanvasInfo } from '../types/IType'; 2 | 3 | export const startStepInfo: IDrawCanvasInfo = { 4 | imgId: '', 5 | gripper: 'body', 6 | mode: 'crop', 7 | moveX: 0, 8 | moveY: 0, 9 | cropBoxWidth: 0, 10 | cropBoxHeight: 0, 11 | fenceMaxWidth: 0, 12 | fenceMaxHeight: 0, 13 | fenceMinWidth: 0, 14 | fenceMinHeight: 0, 15 | cropRatio: null, 16 | cropRationLabel: 'none', 17 | cdProportions: 1, 18 | currentDomWidth: 0, 19 | currentDomHeight: 0, 20 | xCropOffset: 0, 21 | yCropOffset: 0, 22 | xDomOffset: 0, 23 | yDomOffset: 0, 24 | rawImgWidth: 0, 25 | rawImgHeight: 0, 26 | rawDomWidth: 0, 27 | rawDomHeight: 0, 28 | domWidth: 0, 29 | domHeight: 0, 30 | dWidth: 0, 31 | dHeight: 0, 32 | sWidth: 0, 33 | sHeight: 0, 34 | dx: 0, 35 | dy: 0, 36 | sx: 0, 37 | sy: 0, 38 | flipX: 1, 39 | flipY: 1 40 | } -------------------------------------------------------------------------------- /src/types/libs.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'lodash-es'; 2 | declare module '*.css?inline' { 3 | const content: string; 4 | export default content; 5 | } 6 | 7 | declare module 'pngjs'; -------------------------------------------------------------------------------- /src/utils/cache/constants.ts: -------------------------------------------------------------------------------- 1 | export const TRACEIDIMF = "traceIdInformation"; 2 | -------------------------------------------------------------------------------- /src/utils/cache/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 璐 Lu.xu@brandsh.cn 3 | * @Date: 2025-03-26 11:51:46 4 | * @LastEditors: 璐 Lu.xu@brandsh.cn 5 | * @LastEditTime: 2025-03-26 12:06:17 6 | * @FilePath: /pixpro/utils/cache/index.ts 7 | * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE 8 | */ 9 | 10 | enum CacheType { 11 | Local = "local", 12 | Session = "session", 13 | } 14 | 15 | class Cache { 16 | storage: Storage; 17 | constructor(type: CacheType) { 18 | this.storage = type === CacheType.Local ? localStorage : sessionStorage; 19 | } 20 | 21 | setCache(key: string, value: any) { 22 | if (value) { 23 | this.storage.setItem(key, JSON.stringify(value)); 24 | } 25 | } 26 | 27 | getCache(key: string) { 28 | const value = this.storage.getItem(key); 29 | try { 30 | return JSON.parse(value as string); 31 | } catch (error) { 32 | return value; 33 | } 34 | } 35 | 36 | removeCache(key: string) { 37 | this.storage.removeItem(key); 38 | } 39 | 40 | clear() { 41 | this.storage.clear(); 42 | } 43 | } 44 | 45 | const localCache = new Cache(CacheType.Local); 46 | const sessionCache = new Cache(CacheType.Session); 47 | 48 | export { localCache, sessionCache }; 49 | -------------------------------------------------------------------------------- /src/utils/imageData.ts: -------------------------------------------------------------------------------- 1 | /** 记录图片数据 */ 2 | class ImageData { 3 | 4 | public static getInstance() { 5 | return new ImageData(); 6 | } 7 | } 8 | 9 | export default ImageData.getInstance(); 10 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ESNext", "DOM"], 7 | "moduleResolution": "Node", 8 | "strict": true, 9 | "resolveJsonModule": true, 10 | "isolatedModules": true, 11 | "esModuleInterop": true, 12 | "noEmit": true, 13 | "noUnusedLocals": true, 14 | "noUnusedParameters": true, 15 | "noImplicitReturns": true, 16 | "skipLibCheck": true, 17 | "verbatimModuleSyntax": true, 18 | "paths": { 19 | "@/*": ["./src/*"] 20 | } 21 | }, 22 | "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "src/**/*.svelte"] 23 | } 24 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import dts from 'vite-plugin-dts' 3 | import { resolve } from 'path' 4 | import path from 'path' 5 | 6 | export default defineConfig({ 7 | plugins: [dts()], 8 | build: { 9 | lib: { 10 | entry: resolve(__dirname, 'src/index.ts'), 11 | name: 'PhotoStudio', 12 | fileName: 'photo-studio' 13 | } 14 | }, 15 | resolve: { 16 | alias: { 17 | '@': path.resolve(__dirname, 'src'), 18 | }, 19 | } 20 | }) 21 | --------------------------------------------------------------------------------