diff --git a/.arts/settings.json b/.arts/settings.json deleted file mode 100644 index 701b3b07ef5f1416745f4cc533cdfbf73248554a..0000000000000000000000000000000000000000 --- a/.arts/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "diffEditor.renderSideBySide": false -} \ No newline at end of file diff --git a/LICENSE b/LICENSE index be2f36de23c948c408ae5341dd4cfeefe634ae07..1464658bd90a9702778683802d18075de23c1dd8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,32 +1,78 @@ 取色卡(Color Card) - 许可证信息 +目录 + +1. 项目信息 +2. 作者声明 +3. 重要提示 +4. 主项目许可证 + 4.1 GNU General Public License v3.0 +5. 第三方依赖许可证(运行时) + 5.1 PySide6 - LGPLv3 + 5.2 PySide6-Fluent-Widgets - GPLv3 + 5.3 Pillow - MIT-CMU + 5.4 requests - Apache 2.0 + 5.5 numpy - BSD-3-Clause + 5.6 PySideSix-Frameless-Window - LGPLv3 +6. 内置色彩方案 + 6.1 Open Color - MIT + 6.2 Nice Color Palettes - MIT + 6.3 Tailwind CSS Colors - MIT + 6.4 Material Design Colors - Apache 2.0 + 6.5 ColorBrewer - Apache 2.0 + 6.6 Radix UI Colors - MIT + 6.7 Nord - MIT + 6.8 Dracula - MIT + 6.9 Rosé Pine - MIT + 6.10 Solarized - MIT + 6.11 Catppuccin - MIT + 6.12 Gruvbox - MIT/X11 + 6.13 Tokyo Night - MIT +7. 网站使用资源 + 7.1 Tailwind CSS (CSS 框架) - MIT + 7.2 Inter 字体 - SIL OFL 1.1 + 7.3 Vue.js - MIT + 7.4 TypeScript - Apache 2.0 + 7.5 Vite - MIT + 7.6 内置色彩方案展示 +8. 开发工具链许可证 + 8.1 Nuitka - AGPLv3 + Runtime Library Exception +9. 使用说明 + +================================================================================ +1. 项目信息 ================================================================================ -项目信息 --------------------------------------------------------------------------------- 项目名称:取色卡(Color Card) 版权所有:© 2026 浮晓 HXiao Studio 开发者:青山公仔 联系方式:hxiao_studio@163.com ================================================================================ -作者声明 --------------------------------------------------------------------------------- -虽然GPL v3允许商业使用,但作为作者,我恳请使用者遵守以下原则: +2. 作者声明 +================================================================================ +虽然 GPLv3 允许商业使用,但作为作者,我恳请使用者遵守以下原则: - 非商业使用:请勿将此工具用于商业盈利目的 - 共享改进:欢迎提交改进,但请保持开源精神 -请注意,这只是作者的道德请求,法律上仍遵循GPL v3条款。 +请注意,这只是作者的道德请求,法律上仍遵循 GPLv3 条款。 ================================================================================ -⚠️ 重要提示 --------------------------------------------------------------------------------- +3. 重要提示 +================================================================================ 本项目主要包含以下许可证: -1. 主项目许可证:GNU General Public License v3.0 (GPLv3) -2. 第三方库许可证:包含LGPL-3.0、GPL-3.0、MIT等多种开源许可证,详细的第三方库许可证信息请查看后续章节或应用程序的"关于"窗口 +1. 主项目许可证:GNU General Public License v3.0 (GPLv3) — 见第4节 +2. 第三方运行时库许可证:包含 LGPLv3、MIT、Apache 2.0、BSD-3-Clause 等 — 见第5节 +3. 内置色彩方案许可证:主要为 MIT,部分为 Apache 2.0 — 见第6节 +4. 网站使用资源许可证:MIT、Apache 2.0、SIL OFL 1.1 等 — 见第7节 +5. 开发工具许可证:Nuitka (AGPLv3 + Runtime Library Exception) — 见第8节 + +详细的许可证信息请查阅对应章节或应用程序的“关于”窗口。 ================================================================================ -GNU GENERAL PUBLIC LICENSE +4. 主项目许可证 +================================================================================ +4.1 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. @@ -34,7 +80,7 @@ Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble --------------------------------------------------------------------------------- + The GNU General Public License is a free, copyleft license for software and other kinds of works. @@ -395,8 +441,7 @@ consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or -propagating a covered work, you indicate your acceptance of this License to do -so. +propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a @@ -553,71 +598,16 @@ liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS -How to Apply These Terms to Your New Programs --------------------------------------------------------------------------------- -If you develop a new program, and you want it to be of the greatest possible -use to the public, the best way to achieve this is to make it free software -which everyone can redistribute and change under these terms. - -To do so, attach the following notices to the program. It is safest to attach -them to the start of each source file to most effectively state the exclusion -of warranty; and each file should have at the "copyright" line and a pointer to -where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - -If the program does terminal interaction, make it output a short notice like this -when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands might -be different; for a GUI interface, you would use an "about box". - -You should also get your employer (if you work as a programmer) or school, if -any, to sign a "copyright disclaimer" for the program, if necessary. For more -information on this, and how to apply and follow the GNU GPL, see -. - -The GNU General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may consider -it more useful to permit linking proprietary applications with the library. If -this is what you want to do, use the GNU Lesser General Public License instead -of this License. But first, please read . - ================================================================================ -第三方库许可证 --------------------------------------------------------------------------------- -本项目使用了以下第三方库,每个库都有其自己的开源许可证: +5. 第三方依赖许可证(运行时) +================================================================================ --------------------------------------------------------------------------------- -1. PySide6 +5.1 PySide6 -------------------------------------------------------------------------------- 版权所有:The Qt Company Qt官网:https://www.qt.io/ 许可证:GNU Lesser General Public License v3.0 --------------------------------------------------------------------------------- GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -755,28 +745,24 @@ future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. -================================================================================ -2. PySide6-Fluent-Widgets +5.2 PySide6-Fluent-Widgets -------------------------------------------------------------------------------- 版权所有:zhiyiYo 项目地址:https://github.com/zhiyiYo/PyQt-Fluent-Widgets 许可证:GNU General Public License v3.0 说明: -PySide6-Fluent-Widgets 使用 GPLv3 许可证。由于本项目主许可证也为 GPLv3, -完整的 GPLv3 许可证文本请参考本文档前面的 "GNU GENERAL PUBLIC LICENSE -Version 3" 章节。 +PySide6-Fluent-Widgets 使用 GPLv3 许可证。完整的 GPLv3 许可证文本请参阅第4节 +“主项目许可证”中的 GNU General Public License Version 3。 -================================================================================ -3. Pillow +5.3 Pillow -------------------------------------------------------------------------------- 版权所有:Python Imaging Library Team 项目地址:https://github.com/python-pillow/Pillow 官网:python-pillow.github.io 许可证:MIT-CMU License --------------------------------------------------------------------------------- -MIT License +MIT License (MIT-CMU) The Python Imaging Library (PIL) is @@ -809,20 +795,16 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -================================================================================ -4. requests +5.4 requests -------------------------------------------------------------------------------- 版权所有:Kenneth Reitz 项目地址:https://github.com/psf/requests 许可证:Apache License 2.0 --------------------------------------------------------------------------------- NOTICE --------------------------------------------------------------------------------- Requests Copyright 2019 Kenneth Reitz --------------------------------------------------------------------------------- Apache License Version 2.0, January 2004 @@ -985,15 +967,13 @@ of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS -================================================================================ -5. numpy (BSD-3-Clause) +5.5 numpy -------------------------------------------------------------------------------- 版权所有:NumPy Developers 项目地址:https://github.com/numpy/numpy 官网:https://numpy.org/ 许可证:BSD 3-Clause License --------------------------------------------------------------------------------- BSD 3-Clause License Copyright (c) 2005-2025, NumPy Developers. @@ -1027,21 +1007,21 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -================================================================================ -6. PySideSix-Frameless-Window +5.6 PySideSix-Frameless-Window -------------------------------------------------------------------------------- 版权所有:zhiyiYo 项目地址:https://github.com/zhiyiYo/PyQt-Frameless-Window 许可证:GNU Lesser General Public License v3.0 说明: -PySideSix-Frameless-Window 使用 LGPLv3 许可证。由于本项目主许可证为 GPLv3, -而 LGPLv3 是 GPLv3 的补充版本,完整的 LGPLv3 许可证文本请参考本文档 -"PySide6" 章节中的 "GNU LESSER GENERAL PUBLIC LICENSE Version 3" 部分。 - +PySideSix-Frameless-Window 使用 LGPLv3 许可证。完整的 LGPLv3 许可证文本请参阅 +第5.1节 “PySide6”中的 GNU Lesser General Public License Version 3。 ================================================================================ -7. Open Color +6. 内置色彩方案 +================================================================================ + +6.1 Open Color -------------------------------------------------------------------------------- 版权所有:heeyeun (Yeun) 项目地址:https://github.com/yeun/open-color @@ -1049,7 +1029,6 @@ PySideSix-Frameless-Window 使用 LGPLv3 许可证。由于本项目主许可证 许可证:MIT License 用途:内置色彩配色方案 --------------------------------------------------------------------------------- MIT License Copyright (c) 2016 heeyeun @@ -1072,15 +1051,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -================================================================================ -8. Nice Color Palettes +6.2 Nice Color Palettes -------------------------------------------------------------------------------- 版权所有:Jam3 项目地址:https://github.com/Experience-Monks/nice-color-palettes 许可证:MIT License 用途:内置色彩配色方案 --------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2016 Jam3 @@ -1102,8 +1079,7 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -================================================================================ -9. Tailwind CSS Colors +6.3 Tailwind CSS Colors -------------------------------------------------------------------------------- 版权所有:Tailwind Labs, Inc. 项目地址:https://github.com/tailwindlabs/tailwindcss @@ -1111,7 +1087,6 @@ OR OTHER DEALINGS IN THE SOFTWARE. 许可证:MIT License 用途:内置色彩配色方案 --------------------------------------------------------------------------------- MIT License Copyright (c) Tailwind Labs, Inc. @@ -1134,8 +1109,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -================================================================================ -10. Material Design Colors (Apache License 2.0) +6.4 Material Design Colors -------------------------------------------------------------------------------- 版权所有:Google LLC 项目地址:https://m3.material.io/styles/color/system/overview @@ -1143,11 +1117,10 @@ SOFTWARE. 用途:内置色彩配色方案 说明: -Material Design Colors 使用 Apache License 2.0 许可证。完整的许可证文本请参考 -requests 章节中的 "Apache License Version 2.0" 部分。 +Material Design Colors 使用 Apache License 2.0 许可证。完整的许可证文本请参阅 +第5.4节 “requests”中的 Apache License Version 2.0。 -================================================================================ -11. ColorBrewer (Apache License 2.0) +6.5 ColorBrewer -------------------------------------------------------------------------------- 版权所有:Cynthia Brewer 官网:https://colorbrewer2.org/ @@ -1155,11 +1128,10 @@ requests 章节中的 "Apache License Version 2.0" 部分。 用途:内置色彩配色方案 说明: -ColorBrewer 使用 Apache License 2.0 许可证。完整的许可证文本请参考 -requests 章节中的 "Apache License Version 2.0" 部分。 +ColorBrewer 使用 Apache License 2.0 许可证。完整的许可证文本请参阅第5.4节 +“requests”中的 Apache License Version 2.0。 -================================================================================ -12. Radix UI Colors +6.6 Radix UI Colors -------------------------------------------------------------------------------- 版权所有:WorkOS 项目地址:https://github.com/radix-ui/colors @@ -1167,7 +1139,6 @@ requests 章节中的 "Apache License Version 2.0" 部分。 许可证:MIT License 用途:内置色彩配色方案 --------------------------------------------------------------------------------- MIT License Copyright (c) 2021-2022 Modulz @@ -1191,8 +1162,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -================================================================================ -13. Nord +6.7 Nord -------------------------------------------------------------------------------- 版权所有:Sven Greb 项目地址:https://github.com/arcticicestudio/nord @@ -1200,7 +1170,6 @@ SOFTWARE. 许可证:MIT License 用途:内置色彩配色方案 --------------------------------------------------------------------------------- MIT License (MIT) Copyright (c) 2016-present Sven Greb (https://www.svengreb.de) @@ -1223,15 +1192,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -================================================================================ -14. Dracula ---------------------------------------------------------------------------------- +6.8 Dracula +-------------------------------------------------------------------------------- 版权所有:Dracula Theme contributors 官网:https://draculatheme.com/ 许可证:MIT License 用途:内置色彩配色方案 ---------------------------------------------------------------------------------- MIT License Copyright (c) Dracula Theme contributors @@ -1254,16 +1221,14 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -================================================================================ -15. Rosé Pine ---------------------------------------------------------------------------------- +6.9 Rosé Pine +-------------------------------------------------------------------------------- 版权所有:Rosé Pine 团队 项目地址:https://github.com/rose-pine/rose-pine-theme 官网:https://www.rosepine.com/ 许可证:MIT License 用途:内置色彩配色方案 --------------------------------------------------------------------------------- MIT License Copyright (c) 2023 Rosé Pine @@ -1286,8 +1251,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -================================================================================ -16. Solarized +6.10 Solarized -------------------------------------------------------------------------------- 版权所有:Ethan Schoonover 项目地址:https://github.com/altercation/solarized @@ -1295,7 +1259,6 @@ SOFTWARE. 许可证:MIT License 用途:内置色彩配色方案 --------------------------------------------------------------------------------- Copyright (c) 2011 Ethan Schoonover Permission is hereby granted, free of charge, to any person obtaining a copy @@ -1316,8 +1279,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -================================================================================ -17. Catppuccin +6.11 Catppuccin -------------------------------------------------------------------------------- 版权所有:Catppuccin 团队 项目地址:https://github.com/catppuccin/catppuccin @@ -1325,8 +1287,6 @@ THE SOFTWARE. 许可证:MIT License 用途:内置色彩配色方案 --------------------------------------------------------------------------------- - MIT License Copyright (c) 2021 Catppuccin @@ -1349,16 +1309,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -================================================================================ -18. Gruvbox +6.12 Gruvbox -------------------------------------------------------------------------------- 版权所有:Pavel Pertsev 项目地址:https://github.com/morhetz/gruvbox 许可证:MIT/X11 License 用途:内置色彩配色方案 --------------------------------------------------------------------------------- - Copyright (c) 2012 Pavel Pertsev Permission is hereby granted, free of charge, to any person obtaining a copy @@ -1379,16 +1336,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -================================================================================ -19. Tokyo Night +6.13 Tokyo Night -------------------------------------------------------------------------------- 版权所有:enkia 项目地址:https://github.com/enkia/tokyo-night-vscode-theme 许可证:MIT License 用途:内置色彩配色方案 --------------------------------------------------------------------------------- - The MIT License (MIT) Copyright (c) 2018-present Enkia @@ -1413,40 +1367,56 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================================================ -20. 网站使用资源 --------------------------------------------------------------------------------- +7. 网站使用资源 +================================================================================ 项目官网 (https://qingshangongzai.github.io/Color_Card/) 使用了以下资源: -1. Tailwind CSS (MIT License) ---------------------------------------------------------------------------------- +7.1 Tailwind CSS (CSS 框架) +-------------------------------------------------------------------------------- 版权所有:Tailwind Labs, Inc. 项目地址:https://github.com/tailwindlabs/tailwindcss 官网:https://tailwindcss.com 来源:https://cdn.tailwindcss.com 许可证:MIT License -用途:CSS 样式框架 +用途:CSS 样式框架(仅用于网站展示,不包含在最终分发的桌面应用程序中) - 说明:Tailwind CSS 使用 MIT License 许可证。完整的许可证文本请参考本文档第8节 - "Tailwind CSS Colors" 中的 MIT License 部分。 +MIT License -================================================================================ +Copyright (c) Tailwind Labs, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -2. Inter 字体 - 来源:Google Fonts (https://fonts.google.com/specimen/Inter) - 版权所有:© Rasmus Andersson - 许可证:SIL Open Font License 1.1 - 用途:网站正文字体 +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -================================================================================ -3. Vue.js (MIT License) ---------------------------------------------------------------------------------- +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +7.2 Inter 字体 +-------------------------------------------------------------------------------- +来源:Google Fonts (https://fonts.google.com/specimen/Inter) +版权所有:© Rasmus Andersson +许可证:SIL Open Font License 1.1 +用途:网站正文字体(未随本软件分发,仅通过网站引用) + +7.3 Vue.js +-------------------------------------------------------------------------------- 版权所有:Yuxi (Evan) You and Vue contributors 项目地址:https://github.com/vuejs/core 官网:https://vuejs.org/ 许可证:MIT License 用途:网站前端框架(仅用于开发,不包含在最终产品中) ---------------------------------------------------------------------------------- MIT License Copyright (c) 2018-present, Yuxi (Evan) You and Vue contributors @@ -1468,9 +1438,8 @@ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -================================================================================ -4. TypeScript (Apache License 2.0) ---------------------------------------------------------------------------------- +7.4 TypeScript +-------------------------------------------------------------------------------- 版权所有:Microsoft Corporation 项目地址:https://github.com/microsoft/TypeScript 官网:https://www.typescriptlang.org/ @@ -1478,19 +1447,17 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 用途:网站开发类型系统(仅用于开发,不包含在最终产品中) 说明: -TypeScript 使用 Apache License 2.0 许可证。完整的许可证文本请参考本文档第4节 -"requests" 中的 "Apache License Version 2.0" 部分。 +TypeScript 使用 Apache License 2.0 许可证。完整的许可证文本请参阅第5.4节 +“requests”中的 Apache License Version 2.0。 -================================================================================ -5. Vite (MIT License) ---------------------------------------------------------------------------------- +7.5 Vite +-------------------------------------------------------------------------------- 版权所有:Yuxi (Evan) You and Vite contributors 项目地址:https://github.com/vitejs/vite 官网:https://vitejs.dev/ 许可证:MIT License 用途:网站开发构建工具(仅用于开发,不包含在最终产品中) ---------------------------------------------------------------------------------- MIT License Copyright (c) 2019-present, VoidZero Inc. and Vite contributors @@ -1513,64 +1480,31 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -================================================================================ -6. 开源配色方案展示 ---------------------------------------------------------------------------------- -官网展示了13套开源配色方案(详见上文第6-18节) -所有配色方案均遵循各自的开源许可证 - -================================================================================ -开发工具链许可证 +7.6 内置色彩方案展示 -------------------------------------------------------------------------------- -本项目在开发过程中使用了以下工具: +官网展示的13套开源配色方案(Open Color、Nice Color Palettes、Tailwind CSS Colors、 +Material Design Colors、ColorBrewer、Radix UI Colors、Nord、Dracula、Rosé Pine、 +Solarized、Catppuccin、Gruvbox、Tokyo Night)均遵循各自的开源许可证,具体信息请 +参见第6节“内置色彩方案”。 ================================================================================ -1. Nuitka +8. 开发工具链许可证 +================================================================================ + +8.1 Nuitka -------------------------------------------------------------------------------- 版权所有:Kay Hayen 项目地址:https://github.com/Nuitka/Nuitka 官网:https://nuitka.net/ -许可证:GNU Affero General Public License v3.0 -用途:编译打包 +许可证:GNU Affero General Public License v3.0 (AGPLv3),附带 Runtime Library Exception +用途:编译打包(仅作为开发工具使用,其 Runtime Library Exception 明确允许生成 +产物不受 AGPLv3 传染性限制) 说明: -Nuitka 是一款 Python 编译器,将 Python 代码编译为独立的可执行文件。 -本项目使用 Nuitka 编译 Windows 和 Mac 版本。 - -Nuitka 采用双重许可: -1. GNU Affero General Public License v3.0 - 编译器本身 -2. LICENSE-RUNTIME - 运行时组件,允许商业使用 - -本项目仅使用 Nuitka 作为编译工具,生成的可执行文件适用 LICENSE-RUNTIME 条款。 - -Nuitka 编译器本身使用 AGPL-3.0 许可证。完整的 GPL-3.0 许可证文本请参考本文档前面的 -"GNU GENERAL PUBLIC LICENSE Version 3" 章节,以下是 AGPL-3.0 相较 GPL-3.0 补充的部分: - --------------------------------------------------------------------------------- - -13. Remote Network Interaction; Use with the GNU General Public License. - -Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - -Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. +Nuitka 编译器本身使用 AGPLv3 许可证。但根据其提供的 Runtime Library Exception, +通过 Nuitka 编译生成的目标代码(本项目的可执行文件)可以选择不同于 AGPLv3 的 +条款进行许可,不受 AGPLv3 传染性约束。以下为该豁免条款的全文: --------------------------------------------------------------------------------- -LICENSE-RUNTIME -------------------------------------------------------------------------------- Nuitka Runtime Library Exception @@ -1630,10 +1564,9 @@ This exception is intended to allow the creation of closed-source Python applications that use Nuitka, but it does prevent the creation of closed-source Nuitka itself except by the source code owner. - ================================================================================ -使用说明 --------------------------------------------------------------------------------- +9. 使用说明 +================================================================================ 许可证约束: - 本项目整体受 GNU General Public License v3.0 约束 - 使用本软件即表示您同意遵守所有相关许可证条款 @@ -1648,4 +1581,4 @@ Nuitka itself except by the source code owner. ================================================================================ 许可证文档结束 -================================================================================ +================================================================================ \ No newline at end of file diff --git a/README.md b/README.md index 83d88a2a3941e6e49a1f0874c677ad0513048030..c89484949b3865d50ac644d9d4e8ff873374d285 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@

- Python - PySide6 - License + Python + PySide6 + License

*** @@ -43,29 +43,29 @@ 自 2026-02-05 发布首个版本以来,项目保持快速稳定的迭代节奏: -|指标 |数据 | -|:---|:---| -|发布版本 |16 个版本(v1.0.0 → v1.10.2) | -|开发周期 |115 天 | -|总更新项 |**191 项** | -|平均每版本 |11.9 项 | +| 指标 | 数据 | +| :---- | :----------------------- | +| 发布版本 | 17 个版本(v1.0.0 → v1.11.0) | +| 开发周期 | 122 天 | +| 总更新项 | **204 项** | +| 平均每版本 | 12.0 项 | **详细分类统计**: -|分类 |数量 |说明 | -|:---|:---:|:---| -|✨ 新增功能 |**48** |包含首次发布的 9 项核心功能 | -|🔧 问题修复 |**44** |持续修复 Bug,提升稳定性 | -|🎨 界面优化 |**47** |用户体验打磨 | -|⚡ 性能提升 |**12** |缓存机制、启动优化等 | -|📝 内容调整 |**13** |文本、名称等调整 | -|⚙️ 体验优化 |**7** |交互体验改进 | -|🏗️ 代码优化 |**6** |代码结构优化 | -|🔮 逻辑优化 |**2** |算法逻辑改进 | -|🖥️ 平台支持 |**1** |Mac 版本适配 | -|📜 许可证完善 |**1** |开源合规性 | -|🚀 功能优化 |**1** |功能增强 | -|📛 命名调整 |**1** |面板名称统一 | +| 分类 | 数量 | 说明 | +| :------- | :----: | :-------------- | +| ✨ 新增功能 | **50** | 包含首次发布的 9 项核心功能 | +| 🔧 问题修复 | **46** | 持续修复 Bug,提升稳定性 | +| 🎨 界面优化 | **48** | 用户体验打磨 | +| ⚡ 性能提升 | **19** | 缓存机制、启动优化等 | +| 📝 内容调整 | **13** | 文本、名称等调整 | +| ⚙️ 体验优化 | **7** | 交互体验改进 | +| 🏗️ 代码优化 | **7** | 代码结构优化 | +| 🔮 逻辑优化 | **2** | 算法逻辑改进 | +| 🖥️ 平台支持 | **1** | Mac 版本适配 | +| 📜 许可证完善 | **1** | 开源合规性 | +| 🚀 功能优化 | **1** | 功能增强 | +| 📛 命名调整 | **1** | 面板名称统一 | ### ✨ 核心功能特色 @@ -73,30 +73,22 @@ -🎨
-色彩分析
-多色彩空间支持 +🎨 色彩分析 多色彩空间支持 -📊
-明度分析
-9级分区可视化 +📊 明度分析 9级分区可视化 -🌈
-配色生成
-5种专业方案 +🌈 配色生成 5种专业方案 -👁️
-配色预览
-8种场景预览 +👁️ 配色预览 8种场景预览 @@ -104,17 +96,17 @@ > 🎯 **一站式色彩解决方案**:从图片分析到配色应用,提供完整的色彩工作流 -|功能 |截图预览 | -|---|---| -|**色彩信息分析**
通过可拖动取色点实时提取图片颜色,支持多色彩空间显示(HSB、LAB、HSL、CMYK、RGB) |![色彩分析](docs/screenshots/color-extract.png) | -|**明度分析**
将图片按明度分为9个区域(基于Adobe标准),提供直方图可视化,可快速分析图片影调 |![明度分析](docs/screenshots/luminance-extract.png) | -|**渐变色提取**
支持双色渐变和单色明度梯度两种模式,双色渐变通过起始色和结束色生成渐变色序列,单色明度梯度固定色相饱和度按明度分级生成色阶(类似 Tailwind 50-900),支持 RGB/HSB/HSL/LAB 四种颜色空间插值 |![渐变色提取](docs/screenshots/Gradient%20Extract.png) | -|**配色生成**
提供5种专业配色方案(同色系、邻近色、互补色、分离补色、双补色),支持可交互色环选择 |![配色生成](docs/screenshots/color-generation.png) | -|**配色收藏**
支持收藏、管理配色方案,支持批量导入导出为JSON文件,支持单组色卡导出为 Adobe ASE 格式 |![配色管理](docs/screenshots/palette-management.png) | -|**内置色彩库**
集成 Open Color、Tailwind CSS、Material Design 等13大开源配色方案,总计661组色卡 |![内置色彩库](docs/screenshots/preset-colors.png) | -|**配色预览**
支持手机UI、网页、插画、排版、品牌、海报、图案、杂志等8种场景预览,并支持导入自定义SVG |![配色预览](docs/screenshots/color-preview.png) | -|**多语言支持**
支持简体中文、繁体中文、英语、日语、法语、俄语等6种语言 |![多语言支持](docs/screenshots/locales.png) | -| **现代化界面**
基于 Fluent Design 设计语言,支持深色/浅色主题切换 | ![深色/浅色模式](./docs/screenshots/Dark%20mode%26light%20mode.png) | +| 功能 | 截图预览 | +| ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | +| **色彩信息分析**通过可拖动取色点实时提取图片颜色,支持多色彩空间显示(HSB、LAB、HSL、CMYK、RGB) | ![色彩分析](docs/screenshots/color-extract.png) | +| **明度分析**将图片按明度分为9个区域(基于Adobe标准),提供直方图可视化,可快速分析图片影调 | ![明度分析](docs/screenshots/luminance-extract.png) | +| **渐变色提取**支持双色渐变和单色明度梯度两种模式,双色渐变通过起始色和结束色生成渐变色序列,单色明度梯度固定色相饱和度按明度分级生成色阶(类似 Tailwind 50-900),支持 RGB/HSB/HSL/LAB 四种颜色空间插值 | ![渐变色提取](docs/screenshots/Gradient%20Extract.png) | +| **配色生成**提供5种专业配色方案(同色系、邻近色、互补色、分离补色、双补色),支持可交互色环选择 | ![配色生成](docs/screenshots/color-generation.png) | +| **配色收藏**支持收藏、管理配色方案,支持批量导入导出为JSON文件,支持单组色卡导出为 Adobe ASE 格式 | ![配色管理](docs/screenshots/palette-management.png) | +| **内置色彩库**集成 Open Color、Tailwind CSS、Material Design 等13大开源配色方案,总计661组色卡 | ![内置色彩库](docs/screenshots/preset-colors.png) | +| **配色预览**支持手机UI、网页、插画、排版、品牌、海报、图案、杂志等9种场景预览,并支持导入自定义SVG | ![配色预览](docs/screenshots/color-preview.png) | +| **多语言支持**支持简体中文、繁体中文、英语、日语、法语、俄语等6种语言 | ![多语言支持](docs/screenshots/locales.png) | +| **现代化界面**基于 Fluent Design 设计语言,支持深色/浅色主题切换 | ![深色/浅色模式](./docs/screenshots/Dark%20mode%26light%20mode.png) | ### 🎯 适用场景 @@ -125,7 +117,7 @@ **📷 摄影师工作流** - ✨ **摄影后期**:分析照片的色调分布,辅助调色决策 -- 🎨 **色彩参考**:从优秀作品中提取配色,获取创作灵感 +- 🎨 **色彩参考**:从优秀作品中提取配色,获取创作灵感 - 📊 **明度分析**:评估照片的明度分布,优化曝光和对比度 @@ -168,33 +160,26 @@ #### ⚙️ 依赖安装与运行 1. **克隆仓库**: - ```bash # 从 Gitee 克隆(国内推荐) git clone https://gitee.com/qingshangongzai/Color_Card.git - + # 或从 GitHub 克隆 git clone https://github.com/qingshangongzai/Color_Card.git - + cd color_card ``` - 2. **创建虚拟环境(推荐)**: - ```bash python -m venv .venv # 激活虚拟环境 .\.venv\Scripts\activate # Windows ``` - 3. **安装项目依赖**: - ```bash pip install -r requirements.txt ``` - 4. **启动应用程序**: - ```bash python main.py ``` @@ -221,15 +206,15 @@ ### 🧩 功能模块 -|模块 |功能 | -|:---|:---| -|色彩分析 |可拖动取色点、多色彩空间显示、一键复制颜色值 | -|明度分析 |9级明度分区(Zone 0-8)、直方图可视化、区域高亮 | -|渐变色提取 |双色渐变/单色明度梯度两种模式、RGB/HSB/HSL/LAB插值、中间色数量调节 | -|配色生成 |5种配色方案、可交互色环、明度调整 | -|配色管理 |收藏配色、自定义名称、批量导入导出为JSON文件、支持单组配色ASE格式导出(支持Adobe软件) | -|配色预览 |8种内置场景、自定义SVG、智能配色映射 | -|内置色彩库 |13大开源配色方案、661组色卡 | +| 模块 | 功能 | +| :---- | :------------------------------------------------ | +| 色彩分析 | 可拖动取色点、多色彩空间显示、一键复制颜色值 | +| 明度分析 | 9级明度分区(Zone 0-8)、直方图可视化、区域高亮 | +| 渐变色提取 | 双色渐变/单色明度梯度两种模式、RGB/HSB/HSL/LAB插值、中间色数量调节 | +| 配色生成 | 5种配色方案、可交互色环、明度调整 | +| 配色管理 | 收藏配色、自定义名称、批量导入导出为JSON文件、支持单组配色ASE格式导出(支持Adobe软件) | +| 配色预览 | 8种内置场景、自定义SVG、智能配色映射 | +| 内置色彩库 | 13大开源配色方案、661组色卡 | *** @@ -286,26 +271,26 @@ 本项目使用了以下第三方库(部分): -|库 |许可证 | -|:---|:---:| -|PySide6 |LGPL-3.0 | -|PySide6-Fluent-Widgets |GPL-3.0 | -|Pillow |MIT License | -|requests |Apache-2.0 | -|numpy |BSD-3-Clause | -|Open Color |MIT License | -|Tailwind CSS Colors |MIT License | -|Material Design Colors |Apache-2.0 | -|ColorBrewer |Apache-2.0 | -|Radix Colors |MIT License | -|Nord |MIT License | -|Dracula |MIT License | -|Solarized |MIT License | -|Gruvbox |MIT License | -|Catppuccin |MIT License | -|Rose Pine |MIT License | -|Tokyo Night |MIT License | -|Nice Color Palettes |MIT License | +| 库 | 许可证 | +| :--------------------- | :----------: | +| PySide6 | LGPL-3.0 | +| PySide6-Fluent-Widgets | GPL-3.0 | +| Pillow | MIT License | +| requests | Apache-2.0 | +| numpy | BSD-3-Clause | +| Open Color | MIT License | +| Tailwind CSS Colors | MIT License | +| Material Design Colors | Apache-2.0 | +| ColorBrewer | Apache-2.0 | +| Radix Colors | MIT License | +| Nord | MIT License | +| Dracula | MIT License | +| Solarized | MIT License | +| Gruvbox | MIT License | +| Catppuccin | MIT License | +| Rose Pine | MIT License | +| Tokyo Night | MIT License | +| Nice Color Palettes | MIT License | *** @@ -313,7 +298,7 @@ - **主仓库(Gitee)**: - **镜像仓库(GitHub)**: -- **联系邮箱**:[hxiao_studio@163.com](mailto:hxiao_studio@163.com)、[qingshangongzai@163.com](mailto:qingshangongzai@163.com) +- **联系邮箱**: *** @@ -345,29 +330,29 @@ Unlike common color tools or websites that only provide a single function, Color Since the release of the first version on 2026-02-05, the project has maintained a fast and stable iteration pace: -|Metric |Data | -|:---|:---| -|Released Versions |16 versions (v1.0.0 → v1.10.2) | -|Development Period |115 days | -|Total Updates |**191 items** | -|Average per Version |11.9 items | +| Metric | Data | +| :------------------ | :----------------------------- | +| Released Versions | 16 versions (v1.0.0 → v1.10.2) | +| Development Period | 115 days | +| Total Updates | **191 items** | +| Average per Version | 11.9 items | **Detailed Category Statistics**: -|Category |Count |Description | -|:---|:---:|:---| -|✨ New Features |**48** |Including 9 core features from v1.0.0 launch | -|🔧 Bug Fixes |**44** |Continuous bug fixes for stability | -|🎨 UI Improvements |**47** |User experience refinements | -|⚡ Performance |**12** |Cache mechanism, startup optimization | -|📝 Content Adjustments |**13** |Text, naming adjustments | -|⚙️ Experience |**7** |Interaction improvements | -|🏗️ Code Optimization |**6** |Code structure optimization | -|🔮 Logic Optimization |**2** |Algorithm improvements | -|🖥️ Platform Support |**1** |Mac version adaptation | -|📜 License Compliance |**1** |Open source compliance | -|🚀 Feature Enhancement |**1** |Feature enhancements | -|📛 Naming Adjustment |**1** |Panel name unification | +| Category | Count | Description | +| :--------------------- | :----: | :------------------------------------------- | +| ✨ New Features | **48** | Including 9 core features from v1.0.0 launch | +| 🔧 Bug Fixes | **44** | Continuous bug fixes for stability | +| 🎨 UI Improvements | **47** | User experience refinements | +| ⚡ Performance | **12** | Cache mechanism, startup optimization | +| 📝 Content Adjustments | **13** | Text, naming adjustments | +| ⚙️ Experience | **7** | Interaction improvements | +| 🏗️ Code Optimization | **6** | Code structure optimization | +| 🔮 Logic Optimization | **2** | Algorithm improvements | +| 🖥️ Platform Support | **1** | Mac version adaptation | +| 📜 License Compliance | **1** | Open source compliance | +| 🚀 Feature Enhancement | **1** | Feature enhancements | +| 📛 Naming Adjustment | **1** | Panel name unification | ### ✨ Key Features @@ -375,30 +360,22 @@ Since the release of the first version on 2026-02-05, the project has maintained -🎨
-Color Extraction
-Multiple color spaces +🎨 Color Extraction Multiple color spaces -📊
-Luminance Analysis
-9-zone visualization +📊 Luminance Analysis 9-zone visualization -🌈
-Color Schemes
-5 professional modes +🌈 Color Schemes 5 professional modes -👁️
-Color Preview
-8 scene previews +👁️ Color Preview 8 scene previews @@ -406,17 +383,17 @@ Since the release of the first version on 2026-02-05, the project has maintained > 🎯 **One-stop Color Solution**: Complete color workflow from image analysis to color application -|Feature |Screenshot | -|---|---| -|**Visual Color Extraction**
Real-time color extraction via draggable color pickers, supporting multiple color spaces (HSB, LAB, HSL, CMYK, RGB) |![Color Extraction](docs/screenshots/color-extract.png) | -|**Luminance Analysis**
9-zone luminance segmentation (Zone 0-8 based on Adobe standard) with histogram visualization |![Luminance Analysis](docs/screenshots/luminance-extract.png) | -|**Gradient Extraction**
Two modes: two-color gradient generates sequences from start/end colors, lightness shades generates scales by brightness with fixed hue/saturation (like Tailwind 50-900), supporting RGB/HSB/HSL/LAB color space interpolation |![Gradient Extraction](docs/screenshots/Gradient%20Extract.png) | -|**Color Scheme Generation**
5 professional color schemes (Monochromatic, Analogous, Complementary, Split-Complementary, Double Complementary) with interactive color wheel |![Color Generation](docs/screenshots/color-generation.png) | -|**Palette Collection**
Save and manage color schemes, support batch import/export in JSON format, support single palette export to Adobe ASE format |![Palette Management](docs/screenshots/palette-management.png) | -|**Built-in Color Library**
13 major open-source color schemes including Open Color, Tailwind CSS, Material Design, totaling 661 color palettes |![Preset Colors](docs/screenshots/preset-colors.png) | -|**Color Preview**
8 built-in scene previews (Mobile UI, Web, Illustration, Typography, Brand, Poster, Pattern, Magazine) with custom SVG support |![Color Preview](docs/screenshots/color-preview.png) | -|**Multi-language Support**
6 languages including Simplified Chinese, Traditional Chinese, English, Japanese, French, and Russian |![Multi-language](docs/screenshots/locales.png) | -|**Modern Interface**
Based on Fluent Design, supports dark/light theme switching |![Dark/Light Mode](./docs/screenshots/Dark%20mode%26light%20mode.png) | +| Feature | Screenshot | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------- | +| **Visual Color Extraction**Real-time color extraction via draggable color pickers, supporting multiple color spaces (HSB, LAB, HSL, CMYK, RGB) | ![Color Extraction](docs/screenshots/color-extract.png) | +| **Luminance Analysis**9-zone luminance segmentation (Zone 0-8 based on Adobe standard) with histogram visualization | ![Luminance Analysis](docs/screenshots/luminance-extract.png) | +| **Gradient Extraction**Two modes: two-color gradient generates sequences from start/end colors, lightness shades generates scales by brightness with fixed hue/saturation (like Tailwind 50-900), supporting RGB/HSB/HSL/LAB color space interpolation | ![Gradient Extraction](docs/screenshots/Gradient%20Extract.png) | +| **Color Scheme Generation**5 professional color schemes (Monochromatic, Analogous, Complementary, Split-Complementary, Double Complementary) with interactive color wheel | ![Color Generation](docs/screenshots/color-generation.png) | +| **Palette Collection**Save and manage color schemes, support batch import/export in JSON format, support single palette export to Adobe ASE format | ![Palette Management](docs/screenshots/palette-management.png) | +| **Built-in Color Library**13 major open-source color schemes including Open Color, Tailwind CSS, Material Design, totaling 661 color palettes | ![Preset Colors](docs/screenshots/preset-colors.png) | +| **Color Preview**9 built-in scene previews (Mobile UI, Web, Illustration, Typography, Brand, Poster, Pattern, Magazine) with custom SVG support | ![Color Preview](docs/screenshots/color-preview.png) | +| **Multi-language Support**6 languages including Simplified Chinese, Traditional Chinese, English, Japanese, French, and Russian | ![Multi-language](docs/screenshots/locales.png) | +| **Modern Interface**Based on Fluent Design, supports dark/light theme switching | ![Dark/Light Mode](./docs/screenshots/Dark%20mode%26light%20mode.png) | ### 🎯 Use Cases @@ -470,33 +447,26 @@ Since the release of the first version on 2026-02-05, the project has maintained #### ⚙️ Installation Steps 1. **Clone the repository**: - ```bash # Clone from Gitee (recommended for China) git clone https://gitee.com/qingshangongzai/color_card.git - + # Or clone from GitHub git clone https://github.com/qingshangongzai/Color_Card.git - + cd color_card ``` - 2. **Create virtual environment (recommended)**: - ```bash python -m venv .venv # Activate virtual environment .\.venv\Scripts\activate # Windows ``` - 3. **Install dependencies**: - ```bash pip install -r requirements.txt ``` - 4. **Launch the application**: - ```bash python main.py ``` @@ -523,15 +493,15 @@ Since the release of the first version on 2026-02-05, the project has maintained ### 🧩 Feature Modules -|Module |Features | -|:---|:---| -|Color Extraction |Draggable pickers, multiple color spaces, one-click copy | -|Gradient Extraction |Two-color gradient / lightness shades modes, RGB/HSB/HSL/LAB interpolation, adjustable middle colors | -|Luminance Analysis |9-zone segmentation (Zone 0-8), histogram visualization, zone highlighting | -|Color Generation |5 color schemes, interactive color wheel, luminance adjustment | -|Palette Management |Save palettes, custom names, batch import/export in JSON format, support single palette ASE format export (Adobe software compatible) | -|Color Preview |8 built-in scenes, custom SVG, intelligent color mapping | -|Built-in Library |13 open-source color schemes, 661 color palettes | +| Module | Features | +| :------------------ | :------------------------------------------------------------------------------------------------------------------------------------ | +| Color Extraction | Draggable pickers, multiple color spaces, one-click copy | +| Gradient Extraction | Two-color gradient / lightness shades modes, RGB/HSB/HSL/LAB interpolation, adjustable middle colors | +| Luminance Analysis | 9-zone segmentation (Zone 0-8), histogram visualization, zone highlighting | +| Color Generation | 5 color schemes, interactive color wheel, luminance adjustment | +| Palette Management | Save palettes, custom names, batch import/export in JSON format, support single palette ASE format export (Adobe software compatible) | +| Color Preview | 8 built-in scenes, custom SVG, intelligent color mapping | +| Built-in Library | 13 open-source color schemes, 661 color palettes | *** @@ -588,26 +558,26 @@ Color Card is released under the **GNU General Public License v3.0 (GPL 3.0)** l This project uses the following third-party libraries (portion): -|Library |License | -|:---|:---:| -|PySide6 |LGPL-3.0 | -|PySide6-Fluent-Widgets |GPL-3.0 | -|Pillow |MIT License | -|requests |Apache-2.0 | -|numpy |BSD-3-Clause | -|Open Color |MIT License | -|Tailwind CSS Colors |MIT License | -|Material Design Colors |Apache-2.0 | -|ColorBrewer |Apache-2.0 | -|Radix Colors |MIT License | -|Nord |MIT License | -|Dracula |MIT License | -|Solarized |MIT License | -|Gruvbox |MIT License | -|Catppuccin |MIT License | -|Rose Pine |MIT License | -|Tokyo Night |MIT License | -|Nice Color Palettes |MIT License | +| Library | License | +| :--------------------- | :----------: | +| PySide6 | LGPL-3.0 | +| PySide6-Fluent-Widgets | GPL-3.0 | +| Pillow | MIT License | +| requests | Apache-2.0 | +| numpy | BSD-3-Clause | +| Open Color | MIT License | +| Tailwind CSS Colors | MIT License | +| Material Design Colors | Apache-2.0 | +| ColorBrewer | Apache-2.0 | +| Radix Colors | MIT License | +| Nord | MIT License | +| Dracula | MIT License | +| Solarized | MIT License | +| Gruvbox | MIT License | +| Catppuccin | MIT License | +| Rose Pine | MIT License | +| Tokyo Night | MIT License | +| Nice Color Palettes | MIT License | *** @@ -615,7 +585,7 @@ This project uses the following third-party libraries (portion): - **Primary Repository (Gitee)**: - **Mirror Repository (GitHub)**: -- **Email**: [hxiao_studio@163.com](mailto:hxiao_studio@163.com)、[qingshangongzai@163.com](mailto:qingshangongzai@163.com) +- **Email**: *** @@ -629,4 +599,4 @@ This project uses the following third-party libraries (portion): 版权所有/Copyright © 2026 浮晓 HXiao Studio - \ No newline at end of file + diff --git a/app_log/changelog.json b/app_log/changelog.json index 3f2a998c80a7292b1ef7964dfb2d8f685a4567f1..a3c94c814d7ccd704ba17c860f3a6fca36537519 100644 --- a/app_log/changelog.json +++ b/app_log/changelog.json @@ -1,13 +1,62 @@ { "versions": [ { - "version": "v1.10.2", - "date": "2026-05-31", + "version": "v1.11.0", + "date": "2026-06-07", "notes": [ - "由于工作上的原因,未来版本会放缓维护", - "有需要什么改进的地方,欢迎大家反馈问题", - "版本存在一些bug,不太适合用于生产环境,后续会慢慢更新。" + "由于工作上的原因,本次更新后本项目暂时停更", + "有需要什么改进的地方,依旧欢迎大家反馈", + "本版本依旧存在一些bug,依旧不建议在生产环境中使用。" ], + "changes": [ + { + "category": "新增功能", + "items": [ + { + "title": "渐变生成", + "desc": "新增三色渐变模式" + }, + { + "title": "色盲模拟", + "desc": "色盲模拟算法升级为 Machado 2009 矩阵,新增异常三色视支持" + } + ] + }, + { + "category": "问题修复", + "items": [ + "修正配色生成面板翻译键层级错误", + "修复渐变模式切换后滑块位置显示异常,切换时自动重置中间色数量为默认值" + ] + }, + { + "category": "界面优化", + "items": [ + "色盲模拟对话框:扩大对话框尺寸,新增色块条预览功能,新增严重程度调节功能" + ] + }, + { + "category": "性能提升", + "items": [ + "提升颜色转换函数性能,避免重复创建函数对象", + "像素提取函数性能优化,消除 Python 对象创建开销", + "移除图片转 numpy 数组及 QImage 构造时冗余的数组拷贝", + "优化配色导入性能,添加批量处理函数", + "K-Means 聚类算法与主色调位置查找广播内存优化", + "直方图服务 numpy 导入提升至模块顶层" + ] + }, + { + "category": "代码优化", + "items": [ + "删除 color.py 和 gradient.py 中的重复函数定义" + ] + } + ] + }, + { + "version": "v1.10.2", + "date": "2026-05-31", "changes": [ { "category": "问题修复", diff --git a/core/__init__.py b/core/__init__.py index 3bdebb48ed784ad60ce2758ed93eec0b1eddbdcd..e392d80f56188fe2ff3afcb35324f9456dce4ae6 100644 --- a/core/__init__.py +++ b/core/__init__.py @@ -34,6 +34,7 @@ from .color import ( hsl_to_rgb, cmyk_to_rgb, get_color_info, + get_color_info_batch, convert_rgb_colorspace, get_luminance, get_zone, @@ -78,6 +79,8 @@ from .gradient import ( generate_random_gradient, generate_lightness_shades, generate_random_lightness_shade, + generate_three_color_gradient, + generate_random_three_color_gradient, ) from .async_loader import BaseBatchLoader @@ -154,6 +157,8 @@ __all__ = [ 'generate_random_gradient', 'generate_lightness_shades', 'generate_random_lightness_shade', + 'generate_three_color_gradient', + 'generate_random_three_color_gradient', 'rgb_to_hsb', 'rgb_to_lab', 'rgb_to_hex', @@ -165,6 +170,7 @@ __all__ = [ 'hsl_to_rgb', 'cmyk_to_rgb', 'get_color_info', + 'get_color_info_batch', 'get_luminance', 'get_zone', 'get_zone_bounds', diff --git a/core/color.py b/core/color.py index 0269e74294b357bb1bdd9621fe7f2351f55d9984..f345941feef4d0d7fef918903444cb5d9a02b53e 100644 --- a/core/color.py +++ b/core/color.py @@ -97,6 +97,49 @@ def _get_colorspace_matrices(colorspace_name: str) -> dict: return _COLORSPACE_MATRICES.get(colorspace_name, _COLORSPACE_MATRICES['sRGB']) +# ==================== Gamma 转换辅助函数 ==================== + +def _srgb_to_linear(c: float) -> float: + """sRGB 非线性值转线性值""" + if c <= 0.04045: + return c / 12.92 + return ((c + 0.055) / 1.055) ** 2.4 + + +def _linear_to_srgb(c: float) -> float: + """线性值转 sRGB 非线性值""" + if c <= 0.0031308: + return c * 12.92 + return 1.055 * (c ** (1.0 / 2.4)) - 0.055 + + +def _lab_f(t: float) -> float: + """LAB 色彩空间 f 函数""" + if t > 0.008856: + return t ** (1/3) + return 7.787 * t + 16/116 + + +def _lab_f_inv(t: float) -> float: + """LAB 色彩空间 f 函数的逆函数""" + delta = 6 / 29 + if t > delta: + return t ** 3 + return 3 * (delta ** 2) * (t - 4 / 29) + + +def _linear_to_gamma_srgb(c: float) -> float: + """线性值转 sRGB Gamma""" + if c <= 0.0031308: + return c * 12.92 + return 1.055 * (c ** (1 / 2.4)) - 0.055 + + +def _linear_to_gamma_generic(c: float, gamma: float) -> float: + """线性值转通用 Gamma""" + return c ** (1.0 / gamma) + + def calculate_luminance_from_array(rgb_array: np.ndarray, gamma: float = 2.2) -> np.ndarray: """从RGB数组计算明度(向量化计算) @@ -167,7 +210,7 @@ def _qimage_to_numpy(image: QImage) -> np.ndarray: row = np.array(ptr[offset:offset + width * 3], dtype=np.uint8) arr[y] = row.reshape((width, 3)) - return arr.copy() # 复制一份避免内存问题 + return arr # ==================== 配色常量定义 ==================== @@ -268,12 +311,9 @@ def rgb_to_lab(r: int, g: int, b: int, colorspace_name: str = 'sRGB') -> tuple[f x, y, z = x / wp[0], y / wp[1], z / wp[2] - def f(t: float) -> float: - return t ** (1/3) if t > 0.008856 else 7.787 * t + 16/116 - - L = 116 * f(y) - 16 - A = 500 * (f(x) - f(y)) - B = 200 * (f(y) - f(z)) + L = 116 * _lab_f(y) - 16 + A = 500 * (_lab_f(x) - _lab_f(y)) + B = 200 * (_lab_f(y) - _lab_f(z)) return L, A, B @@ -363,6 +403,106 @@ def rgb_to_cmyk(r: int, g: int, b: int) -> tuple[float, float, float, float]: return c * 100, m * 100, y * 100, k * 100 +# ==================== 内部辅助函数 (用于批量处理) ==================== + +def _rgb_to_hsb_normalized(r_norm: float, g_norm: float, b_norm: float) -> tuple[float, float, float]: + """将归一化的RGB转换为HSB (内部函数) + + Args: + r_norm: 红色通道归一化值 (0.0-1.0) + g_norm: 绿色通道归一化值 (0.0-1.0) + b_norm: 蓝色通道归一化值 (0.0-1.0) + + Returns: + tuple: (色相 0-360, 饱和度 0-100, 亮度 0-100) + """ + h, s, v = colorsys.rgb_to_hsv(r_norm, g_norm, b_norm) + return h * 360, s * 100, v * 100 + + +def _rgb_to_lab_normalized( + r_norm: float, g_norm: float, b_norm: float, + colorspace_name: str = 'sRGB' +) -> tuple[float, float, float]: + """将归一化的RGB转换为LAB (内部函数) + + Args: + r_norm: 红色通道归一化值 (0.0-1.0) + g_norm: 绿色通道归一化值 (0.0-1.0) + b_norm: 蓝色通道归一化值 (0.0-1.0) + colorspace_name: 色彩空间名称,默认 sRGB + + Returns: + tuple: (L 0-100, A -128-127, B -128-127) + """ + cs = _get_colorspace_matrices(colorspace_name) + m = cs['rgb_to_xyz'] + wp = cs['white_point'] + gamma = cs['gamma'] + use_srgb_curve = cs.get('use_srgb_curve', False) + + # Gamma 校正 + if use_srgb_curve: + r_norm = ((r_norm + 0.055) / 1.055) ** 2.4 if r_norm > 0.04045 else r_norm / 12.92 + g_norm = ((g_norm + 0.055) / 1.055) ** 2.4 if g_norm > 0.04045 else g_norm / 12.92 + b_norm = ((b_norm + 0.055) / 1.055) ** 2.4 if b_norm > 0.04045 else b_norm / 12.92 + else: + r_norm = r_norm ** gamma + g_norm = g_norm ** gamma + b_norm = b_norm ** gamma + + # 转换到XYZ + x = r_norm * m[0][0] + g_norm * m[0][1] + b_norm * m[0][2] + y = r_norm * m[1][0] + g_norm * m[1][1] + b_norm * m[1][2] + z = r_norm * m[2][0] + g_norm * m[2][1] + b_norm * m[2][2] + + x, y, z = x / wp[0], y / wp[1], z / wp[2] + + # 转换到LAB + L = 116 * _lab_f(y) - 16 + A = 500 * (_lab_f(x) - _lab_f(y)) + B = 200 * (_lab_f(y) - _lab_f(z)) + + return L, A, B + + +def _rgb_to_hsl_normalized(r_norm: float, g_norm: float, b_norm: float) -> tuple[float, float, float]: + """将归一化的RGB转换为HSL (内部函数) + + Args: + r_norm: 红色通道归一化值 (0.0-1.0) + g_norm: 绿色通道归一化值 (0.0-1.0) + b_norm: 蓝色通道归一化值 (0.0-1.0) + + Returns: + tuple: (色相 0-360, 饱和度 0-100, 亮度 0-100) + """ + H, L, S = colorsys.rgb_to_hls(r_norm, g_norm, b_norm) + return H * 360, S * 100, L * 100 + + +def _rgb_to_cmyk_normalized(r_norm: float, g_norm: float, b_norm: float) -> tuple[float, float, float, float]: + """将归一化的RGB转换为CMYK (内部函数) + + Args: + r_norm: 红色通道归一化值 (0.0-1.0) + g_norm: 绿色通道归一化值 (0.0-1.0) + b_norm: 蓝色通道归一化值 (0.0-1.0) + + Returns: + tuple: (C 0-100, M 0-100, Y 0-100, K 0-100) + """ + k = 1 - max(r_norm, g_norm, b_norm) + if k == 1: + return 0, 0, 0, 100 + + c = (1 - r_norm - k) / (1 - k) + m = (1 - g_norm - k) / (1 - k) + y = (1 - b_norm - k) / (1 - k) + + return c * 100, m * 100, y * 100, k * 100 + + def convert_rgb_colorspace( r: int, g: int, b: int, source_colorspace: str, @@ -420,6 +560,42 @@ def get_color_info(r: int, g: int, b: int, colorspace_name: str = 'sRGB') -> dic } +def get_color_info_batch(rgb_list: list[tuple[int, int, int]], colorspace_name: str = 'sRGB') -> list[dict[str, Any]]: + """批量获取颜色信息 (性能优化版本) + + 预先归一化所有颜色,避免重复计算,适用于批量处理场景 + + Args: + rgb_list: RGB颜色列表,每个元素为 (R, G, B) 元组 + colorspace_name: 色彩空间名称,默认 sRGB + + Returns: + list: 颜色信息字典列表,每个字典包含 RGB、HSB、LAB、HSL、CMYK、HEX 信息 + """ + results = [] + for r, g, b in rgb_list: + # 统一归一化一次 + r_norm, g_norm, b_norm = r / 255.0, g / 255.0, b / 255.0 + + # 使用内部函数处理 + H, S, B = _rgb_to_hsb_normalized(r_norm, g_norm, b_norm) + L, A, B_lab = _rgb_to_lab_normalized(r_norm, g_norm, b_norm, colorspace_name) + H2, S2, L2 = _rgb_to_hsl_normalized(r_norm, g_norm, b_norm) + C, M, Y, K = _rgb_to_cmyk_normalized(r_norm, g_norm, b_norm) + + results.append({ + 'rgb': (r, g, b), + 'hsb': (round(H), round(S), round(B)), + 'lab': (round(L), round(A), round(B_lab)), + 'hsl': (round(H2), round(S2), round(L2)), + 'cmyk': (round(C), round(M), round(Y), round(K)), + 'rgb_display': (r, g, b), + 'hex': rgb_to_hex(r, g, b) + }) + + return results + + def get_luminance(r: int, g: int, b: int, gamma: float = 2.2) -> int: """计算像素的明度值 (0-255) @@ -440,15 +616,9 @@ def get_luminance(r: int, g: int, b: int, gamma: float = 2.2) -> int: b_norm = b / 255.0 if gamma == 2.2: - def srgb_to_linear(c: float) -> float: - if c <= 0.04045: - return c / 12.92 - else: - return ((c + 0.055) / 1.055) ** 2.4 - - r_linear = srgb_to_linear(r_norm) - g_linear = srgb_to_linear(g_norm) - b_linear = srgb_to_linear(b_norm) + r_linear = _srgb_to_linear(r_norm) + g_linear = _srgb_to_linear(g_norm) + b_linear = _srgb_to_linear(b_norm) else: r_linear = r_norm ** gamma g_linear = g_norm ** gamma @@ -457,13 +627,7 @@ def get_luminance(r: int, g: int, b: int, gamma: float = 2.2) -> int: luminance_linear = 0.2126 * r_linear + 0.7152 * g_linear + 0.0722 * b_linear if gamma == 2.2: - def linear_to_srgb(c: float) -> float: - if c <= 0.0031308: - return c * 12.92 - else: - return 1.055 * (c ** (1.0 / 2.4)) - 0.055 - - luminance_output = linear_to_srgb(luminance_linear) + luminance_output = _linear_to_srgb(luminance_linear) else: luminance_output = luminance_linear ** (1.0 / gamma) @@ -511,29 +675,6 @@ def get_zone_bounds(zone_str: str) -> tuple[int, int]: return (min_lum, max_lum) -def _qimage_to_numpy(image) -> np.ndarray: - """QImage转NumPy数组(使用bits()直接内存访问)""" - width = image.width() - height = image.height() - - if image.format() != image.Format.Format_RGB888: - image = image.convertToFormat(image.Format.Format_RGB888) - - ptr = image.bits() - bytes_per_line = image.bytesPerLine() - - if bytes_per_line == width * 3: - arr = np.array(ptr, dtype=np.uint8).reshape((height, width, 3)) - else: - arr = np.zeros((height, width, 3), dtype=np.uint8) - for y in range(height): - offset = y * bytes_per_line - row = np.array(ptr[offset:offset + width * 3], dtype=np.uint8) - arr[y] = row.reshape((width, 3)) - - return arr - - def calculate_histogram(image, sample_step: int = 4, gamma: float = 2.2) -> list[int]: """计算图片的明度直方图(使用NumPy向量化优化) @@ -685,20 +826,13 @@ def lab_to_rgb(L: float, A: float, B: float, colorspace_name: str = 'sRGB') -> t gamma = cs['gamma'] use_srgb_curve = cs.get('use_srgb_curve', False) - def f_inv(t: float) -> float: - delta = 6 / 29 - if t > delta: - return t ** 3 - else: - return 3 * (delta ** 2) * (t - 4 / 29) - y = (L + 16) / 116 x = y + A / 500 z = y - B / 200 - x = wp[0] * f_inv(x) - y = wp[1] * f_inv(y) - z = wp[2] * f_inv(z) + x = wp[0] * _lab_f_inv(x) + y = wp[1] * _lab_f_inv(y) + z = wp[2] * _lab_f_inv(z) r_linear = x * m[0][0] + y * m[0][1] + z * m[0][2] g_linear = x * m[1][0] + y * m[1][1] + z * m[1][2] @@ -709,18 +843,13 @@ def lab_to_rgb(L: float, A: float, B: float, colorspace_name: str = 'sRGB') -> t b_linear = max(0, b_linear) if use_srgb_curve: - def linear_to_gamma(c: float) -> float: - if c <= 0.0031308: - return c * 12.92 - else: - return 1.055 * (c ** (1 / 2.4)) - 0.055 + r = _linear_to_gamma_srgb(r_linear) + g = _linear_to_gamma_srgb(g_linear) + b_out = _linear_to_gamma_srgb(b_linear) else: - def linear_to_gamma(c: float) -> float: - return c ** (1.0 / gamma) - - r = linear_to_gamma(r_linear) - g = linear_to_gamma(g_linear) - b_out = linear_to_gamma(b_linear) + r = _linear_to_gamma_generic(r_linear, gamma) + g = _linear_to_gamma_generic(g_linear, gamma) + b_out = _linear_to_gamma_generic(b_linear, gamma) r = min(1, r) g = min(1, g) @@ -1140,27 +1269,22 @@ def get_scheme_preview_colors( class _ColorCube: """MMCQ 颜色立方体,用于表示颜色空间中的一个区域""" - def __init__(self, pixels: list[tuple[int, int, int]]): + def __init__(self, pixels: np.ndarray): """ Args: - pixels: RGB 像素列表 [(r, g, b), ...] + pixels: RGB 像素数组 (N×3),dtype=np.int32 """ - self.pixels = pixels + self._np_pixels = pixels self._cache_volume = None self._cache_avg_color = None self._cache_ranges = None - self._np_pixels = None - - # 预先转换为 numpy 数组 - if pixels: - self._np_pixels = np.array(pixels, dtype=np.int32) def _get_ranges(self) -> tuple[int, int, int, int, int, int]: """获取各颜色通道的范围(使用缓存)""" if self._cache_ranges is not None: return self._cache_ranges - if not self.pixels: + if len(self._np_pixels) == 0: self._cache_ranges = (0, 0, 0, 0, 0, 0) return self._cache_ranges @@ -1177,7 +1301,7 @@ class _ColorCube: if self._cache_volume is not None: return self._cache_volume - if not self.pixels: + if len(self._np_pixels) == 0: self._cache_volume = 0 return 0 @@ -1187,14 +1311,14 @@ class _ColorCube: def get_count(self) -> int: """获取像素数量""" - return len(self.pixels) + return len(self._np_pixels) def get_average_color(self) -> tuple[int, int, int]: """计算立方体内像素的平均颜色""" if self._cache_avg_color is not None: return self._cache_avg_color - if not self.pixels: + if len(self._np_pixels) == 0: self._cache_avg_color = (0, 0, 0) return self._cache_avg_color @@ -1206,7 +1330,7 @@ class _ColorCube: def get_longest_axis(self) -> str: """获取最长的颜色轴 ('r', 'g', 或 'b')""" - if not self.pixels: + if len(self._np_pixels) == 0: return 'r' r_min, r_max, g_min, g_max, b_min, b_max = self._get_ranges() @@ -1225,37 +1349,35 @@ class _ColorCube: def split(self) -> tuple['_ColorCube', '_ColorCube']: """沿最长轴的中位数切分立方体""" - if not self.pixels: - return _ColorCube([]), _ColorCube([]) + if len(self._np_pixels) == 0: + empty = np.array([], dtype=np.int32).reshape(0, 3) + return _ColorCube(empty), _ColorCube(empty) axis = self.get_longest_axis() axis_index = {'r': 0, 'g': 1, 'b': 2}[axis] - # 使用 numpy 快速排序 + # 使用 numpy 排序和切片 sorted_indices = np.argsort(self._np_pixels[:, axis_index]) mid = len(sorted_indices) // 2 - pixels1 = [self.pixels[i] for i in sorted_indices[:mid]] - pixels2 = [self.pixels[i] for i in sorted_indices[mid:]] + # 直接使用 numpy 数组切片 + pixels1 = self._np_pixels[sorted_indices[:mid]] + pixels2 = self._np_pixels[sorted_indices[mid:]] - # 切分为两个立方体 - cube1 = _ColorCube(pixels1) - cube2 = _ColorCube(pixels2) + return _ColorCube(pixels1), _ColorCube(pixels2) - return cube1, cube2 - -def _mmcq_quantize(pixels: list[tuple[int, int, int]], count: int) -> list[_ColorCube]: +def _mmcq_quantize(pixels: np.ndarray, count: int) -> list[_ColorCube]: """MMCQ 算法核心实现 Args: - pixels: RGB 像素列表 + pixels: RGB 像素数组 (N×3) count: 目标颜色数量 Returns: list: 颜色立方体列表 """ - if not pixels or count <= 0: + if len(pixels) == 0 or count <= 0: return [] # 初始立方体包含所有像素 @@ -1289,77 +1411,79 @@ def _mmcq_quantize(pixels: list[tuple[int, int, int]], count: int) -> list[_Colo return cubes -def _extract_pixels_fast(image, sample_step: int = 4) -> list[tuple[int, int, int]]: +def _extract_pixels_fast(image, sample_step: int = 4) -> np.ndarray: """快速提取图片像素数据 - 使用 numpy 优化像素提取性能。 - Args: image: QImage 或 PIL Image 对象 sample_step: 采样步长 Returns: - list: RGB 像素列表 + np.ndarray: RGB 像素数组 (N×3),dtype=np.uint8 """ - pixels = [] - # 处理 QImage if hasattr(image, 'width') and hasattr(image, 'height'): width = image.width() height = image.height() if hasattr(image, 'bits'): - # 使用 numpy 批量读取像素(QImage 格式) arr = _qimage_to_numpy(image) # 采样像素 - arr_sampled = arr[::sample_step, ::sample_step] - pixels = [(int(r), int(g), int(b)) for r, g, b in arr_sampled.reshape(-1, 3)] + sampled = arr[::sample_step, ::sample_step].reshape(-1, 3) - # 额外采样边缘像素 + # 合并边缘像素 if width > 0 and height > 0: right_edge = arr[::sample_step, -1] bottom_edge = arr[-1, ::sample_step] - pixels.extend([(int(r), int(g), int(b)) for r, g, b in right_edge]) - pixels.extend([(int(r), int(g), int(b)) for r, g, b in bottom_edge]) + edges = np.vstack([right_edge, bottom_edge]) + return np.vstack([sampled, edges]) - return pixels + return sampled # 处理 PIL Image elif hasattr(image, 'size') and hasattr(image, 'getpixel'): width, height = image.size if hasattr(image, 'convert'): - # 使用 numpy 批量读取像素(PIL Image 格式) arr = np.array(image.convert('RGB')) # 采样像素 - arr_sampled = arr[::sample_step, ::sample_step] - pixels = [(int(r), int(g), int(b)) for r, g, b in arr_sampled.reshape(-1, 3)] + sampled = arr[::sample_step, ::sample_step].reshape(-1, 3) - # 额外采样边缘像素 + # 合并边缘像素 if width > 0 and height > 0: right_edge = arr[::sample_step, -1] bottom_edge = arr[-1, ::sample_step] - pixels.extend([(int(r), int(g), int(b)) for r, g, b in right_edge]) - pixels.extend([(int(r), int(g), int(b)) for r, g, b in bottom_edge]) + edges = np.vstack([right_edge, bottom_edge]) + return np.vstack([sampled, edges]) - return pixels + return sampled - return pixels + return np.array([], dtype=np.uint8).reshape(0, 3) def _kmeans_plus_plus_init(pixels: np.ndarray, k: int) -> np.ndarray: """K-Means++ 初始化聚类中心""" rng = np.random.default_rng() - centroids = [pixels[rng.integers(len(pixels))]] + n = len(pixels) + + # 随机选择第一个中心 + centroids = [pixels[rng.integers(n)]] + # 计算所有像素到第一个中心的距离 + diff = pixels - centroids[0] + min_dist_sq = np.sum(diff * diff, axis=1) + for _ in range(1, k): - dist_sq = np.min( - np.sum((pixels[:, np.newaxis] - np.array(centroids)[np.newaxis]) ** 2, axis=2), - axis=1 - ) - probs = dist_sq / dist_sq.sum() - centroids.append(pixels[rng.choice(len(pixels), p=probs)]) + probs = min_dist_sq / min_dist_sq.sum() + new_centroid = pixels[rng.choice(n, p=probs)] + centroids.append(new_centroid) + + # 只计算新中心的距离,增量更新最小值 + diff = pixels - new_centroid + new_dist_sq = np.sum(diff * diff, axis=1) + np.minimum(min_dist_sq, new_dist_sq, out=min_dist_sq) + return np.array(centroids, dtype=np.float32) @@ -1374,31 +1498,41 @@ def extract_dominant_colors_kmeans( count = max(3, min(8, count)) if original_pixels is not None: - arr_sampled = original_pixels[::sample_step, ::sample_step] - pixels_list = [(int(r), int(g), int(b)) for r, g, b in arr_sampled.reshape(-1, 3)] + arr_sampled = original_pixels[::sample_step, ::sample_step].reshape(-1, 3) + # 合并边缘像素 + if original_pixels.size > 0: + right_edge = original_pixels[::sample_step, -1] + bottom_edge = original_pixels[-1, ::sample_step] + edges = np.vstack([right_edge, bottom_edge]) + pixels_np = np.vstack([arr_sampled, edges]).astype(np.float32) + else: + pixels_np = arr_sampled.astype(np.float32) else: - pixels_list = _extract_pixels_fast(image, sample_step) + pixels_arr = _extract_pixels_fast(image, sample_step) + pixels_np = pixels_arr.astype(np.float32) - if not pixels_list: + if len(pixels_np) == 0: return [] - pixels_np = np.array(pixels_list, dtype=np.float32) centroids = _kmeans_plus_plus_init(pixels_np, count) + # 预计算像素范数平方,避免每轮重复计算 + pixel_norms = np.sum(pixels_np * pixels_np, axis=1) for _ in range(max_iterations): - distances = np.sum( - (pixels_np[:, np.newaxis] - centroids[np.newaxis]) ** 2, axis=2 - ) + # 展开式: ||p-c||^2 = ||p||^2 - 2*p.c + ||c||^2,矩阵乘法避免 (N,k,3) 中间数组 + centroid_norms = np.sum(centroids * centroids, axis=1) + distances = pixel_norms[:, np.newaxis] - 2 * (pixels_np @ centroids.T) + centroid_norms labels = np.argmin(distances, axis=1) + new_centroids = np.array([ - pixels_np[labels == k].mean(axis=0) if (labels == k).any() else centroids[k] - for k in range(count) + pixels_np[labels == i].mean(axis=0) if (labels == i).any() else centroids[i] + for i in range(count) ], dtype=np.float32) if np.allclose(centroids, new_centroids): break centroids = new_centroids - cluster_sizes = [(labels == k).sum() for k in range(count)] + cluster_sizes = [(labels == i).sum() for i in range(count)] sorted_indices = np.argsort(cluster_sizes)[::-1] return [tuple(int(round(c)) for c in centroids[i]) for i in sorted_indices] @@ -1431,20 +1565,24 @@ def extract_dominant_colors( count = max(3, min(8, count)) if original_pixels is not None: - arr_sampled = original_pixels[::sample_step, ::sample_step] - pixels = [(int(r), int(g), int(b)) for r, g, b in arr_sampled.reshape(-1, 3)] + arr_sampled = original_pixels[::sample_step, ::sample_step].reshape(-1, 3) + # 合并边缘像素 if original_pixels.size > 0: right_edge = original_pixels[::sample_step, -1] bottom_edge = original_pixels[-1, ::sample_step] - pixels.extend([(int(r), int(g), int(b)) for r, g, b in right_edge]) - pixels.extend([(int(r), int(g), int(b)) for r, g, b in bottom_edge]) + edges = np.vstack([right_edge, bottom_edge]) + pixels = np.vstack([arr_sampled, edges]) + else: + pixels = arr_sampled else: pixels = _extract_pixels_fast(image, sample_step) - if not pixels: + if len(pixels) == 0: return [] - cubes = _mmcq_quantize(pixels, count) + # 转换为 int32 用于 MMCQ + pixels_int32 = pixels.astype(np.int32) + cubes = _mmcq_quantize(pixels_int32, count) cubes.sort(key=lambda c: c.get_count(), reverse=True) dominant_colors = [cube.get_average_color() for cube in cubes] @@ -1454,7 +1592,7 @@ def extract_dominant_colors( def _extract_pixels_with_positions_fast( image, sample_step: int = 4 -) -> tuple[int, int, list[tuple[int, int, int, int, int]]]: +) -> tuple[int, int, np.ndarray]: """快速提取图片像素数据及其位置 Args: @@ -1462,9 +1600,9 @@ def _extract_pixels_with_positions_fast( sample_step: 采样步长 Returns: - tuple: (width, height, pixel_data) 其中 pixel_data 是 [(x, y, r, g, b), ...] + tuple: (width, height, pixel_data) 其中 pixel_data 是 (N×5) 数组 + 列顺序: x, y, r, g, b """ - pixel_data = [] width, height = 0, 0 # 处理 QImage @@ -1473,44 +1611,50 @@ def _extract_pixels_with_positions_fast( height = image.height() if hasattr(image, 'bits'): - # 使用 numpy 批量读取像素 arr = _qimage_to_numpy(image) - # 采样像素位置 - y_coords, x_coords = np.meshgrid( - np.arange(0, height, sample_step), - np.arange(0, width, sample_step), - indexing='ij' - ) + # 使用 numpy 生成坐标网格 + ys = np.arange(0, height, sample_step) + xs = np.arange(0, width, sample_step) + y_grid, x_grid = np.meshgrid(ys, xs, indexing='ij') + + # 扁平化坐标 + x_flat = x_grid.ravel() + y_flat = y_grid.ravel() + + # 获取对应像素 + pixels_flat = arr[::sample_step, ::sample_step].reshape(-1, 3) - for y, x in zip(y_coords.flat, x_coords.flat): - r, g, b = arr[y, x] - pixel_data.append((int(x), int(y), int(r), int(g), int(b))) + # 合并为 (x, y, r, g, b) 数组 + pixel_data = np.column_stack([x_flat, y_flat, pixels_flat]) - return width, height, pixel_data + return width, height, pixel_data.astype(np.int32) # 处理 PIL Image elif hasattr(image, 'size') and hasattr(image, 'getpixel'): width, height = image.size if hasattr(image, 'convert'): - # 使用 numpy 批量读取像素 arr = np.array(image.convert('RGB')) - # 采样像素位置 - y_coords, x_coords = np.meshgrid( - np.arange(0, height, sample_step), - np.arange(0, width, sample_step), - indexing='ij' - ) + # 使用 numpy 生成坐标网格 + ys = np.arange(0, height, sample_step) + xs = np.arange(0, width, sample_step) + y_grid, x_grid = np.meshgrid(ys, xs, indexing='ij') - for y, x in zip(y_coords.flat, x_coords.flat): - r, g, b = arr[y, x] - pixel_data.append((int(x), int(y), int(r), int(g), int(b))) + # 扁平化坐标 + x_flat = x_grid.ravel() + y_flat = y_grid.ravel() - return width, height, pixel_data + # 获取对应像素 + pixels_flat = arr[::sample_step, ::sample_step].reshape(-1, 3) - return width, height, pixel_data + # 合并为 (x, y, r, g, b) 数组 + pixel_data = np.column_stack([x_flat, y_flat, pixels_flat]) + + return width, height, pixel_data.astype(np.int32) + + return width, height, np.array([], dtype=np.int32).reshape(0, 5) def find_dominant_color_positions( @@ -1537,30 +1681,34 @@ def find_dominant_color_positions( height, width = original_pixels.shape[:2] arr = original_pixels[::sample_step, ::sample_step] ys, xs = np.mgrid[0:height:sample_step, 0:width:sample_step] - pixel_data = [ - (int(x), int(y), int(r), int(g), int(b)) - for y, x, r, g, b in zip(ys.flat, xs.flat, arr[:, :, 0].flat, arr[:, :, 1].flat, arr[:, :, 2].flat) - ] + + # 使用 numpy 列向量合并 + x_flat = xs.ravel() + y_flat = ys.ravel() + pixels_flat = arr.reshape(-1, 3) + pixel_data = np.column_stack([x_flat, y_flat, pixels_flat]).astype(np.float32) else: width, height, pixel_data = _extract_pixels_with_positions_fast(image, sample_step) + pixel_data = pixel_data.astype(np.float32) - if not pixel_data or width == 0 or height == 0: + if len(pixel_data) == 0 or width == 0 or height == 0: return [(0.5, 0.5)] * len(dominant_colors) - pixel_array = np.array(pixel_data, dtype=np.float32) dominant_array = np.array(dominant_colors, dtype=np.float32) - pixel_colors = pixel_array[:, 2:5] + pixel_colors = pixel_data[:, 2:5] - diff = pixel_colors[:, np.newaxis, :] - dominant_array[np.newaxis, :, :] - distances = np.sum(diff ** 2, axis=2) + # 展开式: ||p-c||^2 = ||p||^2 - 2*p.c + ||c||^2,矩阵乘法避免 (N,k,3) 中间数组 + color_norms = np.sum(pixel_colors * pixel_colors, axis=1) + dominant_norms = np.sum(dominant_array * dominant_array, axis=1) + distances = color_norms[:, np.newaxis] - 2 * (pixel_colors @ dominant_array.T) + dominant_norms closest_indices = np.argmin(distances, axis=1) positions = [] for i in range(len(dominant_colors)): mask = closest_indices == i - cluster = pixel_array[mask] + cluster = pixel_data[mask] if len(cluster) > 0: avg_x = cluster[:, 0].mean() diff --git a/core/colorblind.py b/core/colorblind.py index eb16b4dfd779d01fac2698b47e670e24267d5f46..738cba9e29b50e9517260123ad72f8466b69b806 100644 --- a/core/colorblind.py +++ b/core/colorblind.py @@ -1,12 +1,9 @@ """色盲模拟模块 提供各种色盲类型的颜色转换功能。 -使用 LMS 色彩空间转换矩阵实现准确的色盲模拟。 +使用 Machado 2009 LMS 色彩空间矩阵实现准确的色盲模拟。 """ - - - from __future__ import annotations # 色盲类型定义 @@ -30,181 +27,195 @@ COLORBLIND_TYPES = { 'achromatopsia': { 'name': '全色盲', 'description': '完全无法感知颜色,只能看到灰度,极为罕见。' - } + }, + 'protanomaly': { + 'name': '红色弱', + 'description': '红色视锥细胞功能减弱,对红色敏感度降低。' + }, + 'deuteranomaly': { + 'name': '绿色弱', + 'description': '绿色视锥细胞功能减弱,对绿色敏感度降低,最常见的色觉异常。' + }, + 'tritanomaly': { + 'name': '蓝色弱', + 'description': '蓝色视锥细胞功能减弱,对蓝色敏感度降低,极罕见。' + }, } +# ========== Machado 2009 矩阵常量 ========== +# 来源: "A Physiologically-based Model for Simulation of Color Vision Deficiency" +# doi: 10.1109/TVCG.2009.113 + +# RGB → LMS 转换矩阵(Machado 2009, Table I) +MACHADO_LMS_FROM_RGB = [ + [0.3904725, 0.6882901, -0.0786870], + [-0.2296649, 1.1833588, 0.0463308], + [0.0000000, 0.0000000, 1.0000000], +] + +# LMS → RGB 转换矩阵(Machado 2009 逆矩阵) +MACHADO_RGB_FROM_LMS = [ + [2.4399508, -1.4196877, 0.2194128], + [0.4734952, 0.8066012, 0.0734703], + [0.0000000, 0.0000000, 1.0000000], +] + +# 完全缺失型色盲矩阵(severity=1.0, Machado 2009 Table I) +MACHADO_MATRICES = { + 'protan': [ + [0.152286, 1.052583, -0.204868], + [0.114503, 0.786281, 0.099216], + [-0.003882, -0.048116, 1.051998], + ], + 'deutan': [ + [0.367322, 0.860646, -0.227968], + [0.280085, 0.672501, 0.047413], + [-0.011820, 0.042940, 0.968881], + ], + 'tritan': [ + [1.255528, -0.076749, -0.178779], + [-0.078411, 0.930809, 0.147602], + [0.004733, 0.691367, 0.303900], + ], +} -def rgb_to_lms(r: int, g: int, b: int) -> tuple[float, float, float]: - """将 RGB 转换为 LMS 色彩空间 - - LMS 代表长波(L)、中波(M)、短波(S)视锥细胞的响应值。 - 使用 Bradford 变换矩阵。 - - Args: - r: 红色分量 (0-255) - g: 绿色分量 (0-255) - b: 蓝色分量 (0-255) - - Returns: - (L, M, S) 元组 - """ - # 归一化到 0-1 - r_norm = r / 255.0 - g_norm = g / 255.0 - b_norm = b / 255.0 - - # sRGB 到线性 RGB 的伽马校正 - def gamma_correction(c): - if c <= 0.04045: - return c / 12.92 - else: - return ((c + 0.055) / 1.055) ** 2.4 - - r_linear = gamma_correction(r_norm) - g_linear = gamma_correction(g_norm) - b_linear = gamma_correction(b_norm) - - # RGB 到 LMS 转换矩阵 (Bradford) - L = 0.8951 * r_linear + 0.2664 * g_linear - 0.1614 * b_linear - M = -0.7502 * r_linear + 1.7135 * g_linear + 0.0367 * b_linear - S = 0.0389 * r_linear - 0.0685 * g_linear + 1.0296 * b_linear - - return (L, M, S) - - -def lms_to_rgb(L: float, M: float, S: float) -> tuple[int, int, int]: - """将 LMS 转换回 RGB 色彩空间 - Args: - L: 长波视锥响应 - M: 中波视锥响应 - S: 短波视锥响应 +def _apply_matrix(v: tuple[float, float, float], m: list[list[float]]) -> tuple[float, float, float]: + """3x3 矩阵乘以 3 维向量 v""" + return ( + m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2], + m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2], + m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2], + ) - Returns: - (R, G, B) 元组,范围 0-255 - """ - # LMS 到 RGB 转换矩阵 (Bradford 逆矩阵) - r_linear = 0.986993 * L - 0.147054 * M + 0.159963 * S - g_linear = 0.432305 * L + 0.51836 * M + 0.049291 * S - b_linear = -0.008529 * L + 0.040043 * M + 0.968487 * S - # 线性 RGB 到 sRGB 的伽马校正 - def gamma_correction_inv(c): - if c <= 0.0031308: - return c * 12.92 - else: - return 1.055 * (c ** (1.0 / 2.4)) - 0.055 +def _gamma_linearize(c: float) -> float: + """sRGB 非线性通道 → 线性通道""" + if c <= 0.04045: + return c / 12.92 + return ((c + 0.055) / 1.055) ** 2.4 - r_norm = gamma_correction_inv(r_linear) - g_norm = gamma_correction_inv(g_linear) - b_norm = gamma_correction_inv(b_linear) - # 裁剪到 0-1 范围并转换为 0-255 - R = int(max(0, min(1, r_norm)) * 255) - G = int(max(0, min(1, g_norm)) * 255) - B = int(max(0, min(1, b_norm)) * 255) +def _gamma_delinearize(c: float) -> float: + """线性通道 → sRGB 非线性通道""" + if c <= 0.0031308: + return c * 12.92 + return 1.055 * (c ** (1.0 / 2.4)) - 0.055 - return (R, G, B) +def _interpolate_matrix(full_matrix: list[list[float]], severity: float) -> list[list[float]]: + """在单位矩阵和完全缺失矩阵之间做线性插值 -def simulate_protanopia(L: float, M: float, S: float) -> tuple[float, float, float]: - """模拟红色盲 (Protanopia) + Args: + full_matrix: severity=1.0 时的完全缺失矩阵 + severity: 严重程度 (0.0-1.0) - 红色视锥细胞缺失,L 通道信息丢失。 - 使用红色盲模拟矩阵。 + Returns: + 插值后的 3x3 矩阵 """ - # 红色盲转换:L 通道由 M 和 S 估算 - L_blind = 0.0 * L + 2.02344 * M - 2.52581 * S - M_blind = M - S_blind = S - return (L_blind, M_blind, S_blind) + result = [[0.0] * 3 for _ in range(3)] + for i in range(3): + for j in range(3): + identity = 1.0 if i == j else 0.0 + result[i][j] = identity * (1.0 - severity) + full_matrix[i][j] * severity + return result -def simulate_deuteranopia(L: float, M: float, S: float) -> tuple[float, float, float]: - """模拟绿色盲 (Deuteranopia) +def _get_blind_matrix(cvd_type: str, severity: float) -> list[list[float]] | None: + """根据色盲类型和严重程度获取最终变换矩阵 - 绿色视锥细胞缺失,M 通道信息丢失。 - 使用绿色盲模拟矩阵。 - """ - # 绿色盲转换:M 通道由 L 和 S 估算 - L_blind = L - M_blind = 0.49421 * L + 0.0 * M + 1.24827 * S - S_blind = S - return (L_blind, M_blind, S_blind) - - -def simulate_tritanopia(L: float, M: float, S: float) -> tuple[float, float, float]: - """模拟蓝色盲 (Tritanopia) + Args: + cvd_type: 色盲类型标识 + severity: 严重程度 (0.0-1.0),仅对 anomal 类型生效 - 蓝色视锥细胞缺失,S 通道信息丢失。 - 使用蓝色盲模拟矩阵。 + Returns: + 3x3 变换矩阵,normal/achromatopsia 返回 None """ - # 蓝色盲转换:S 通道由 L 和 M 估算 - L_blind = L - M_blind = M - S_blind = -0.395913 * L + 0.801109 * M + 0.0 * S - return (L_blind, M_blind, S_blind) - + if cvd_type in ('protanopia', 'protanomaly'): + matrix_key = 'protan' + elif cvd_type in ('deuteranopia', 'deuteranomaly'): + matrix_key = 'deutan' + elif cvd_type in ('tritanopia', 'tritanomaly'): + matrix_key = 'tritan' + else: + return None -def simulate_achromatopsia(L: float, M: float, S: float) -> tuple[float, float, float]: - """模拟全色盲 (Achromatopsia) - - 完全无法感知颜色,转换为灰度。 - 使用 LMS 到灰度的转换。 - """ - # 转换为灰度值 (使用亮度权重) - gray = 0.299 * L + 0.587 * M + 0.114 * S - return (gray, gray, gray) + actual_severity = 1.0 if cvd_type.endswith('opia') else severity + return _interpolate_matrix(MACHADO_MATRICES[matrix_key], actual_severity) def simulate_colorblind( rgb: tuple[int, int, int], - colorblind_type: str = 'normal' + cvd_type: str = 'normal', + severity: float = 0.5 ) -> tuple[int, int, int]: """模拟指定类型的色盲效果 - + Args: rgb: 原始 RGB 颜色元组 (r, g, b),范围 0-255 - colorblind_type: 色盲类型,可选值: + cvd_type: 色盲类型,可选值: - 'normal': 正常视觉 - 'protanopia': 红色盲 - 'deuteranopia': 绿色盲 - 'tritanopia': 蓝色盲 - 'achromatopsia': 全色盲 - + - 'protanomaly': 红色弱(severity 生效) + - 'deuteranomaly': 绿色弱(severity 生效) + - 'tritanomaly': 蓝色弱(severity 生效) + severity: 严重程度 0.0-1.0,仅对 anomal 类型生效, + 0.0=正常视觉,1.0=完全缺失 + Returns: 模拟后的 RGB 颜色元组 (r, g, b),范围 0-255 """ - if colorblind_type == 'normal': + if cvd_type == 'normal': return rgb - + R, G, B = rgb - # 转换为 LMS 空间 - L, M, S = rgb_to_lms(R, G, B) - - # 应用色盲模拟 - if colorblind_type == 'protanopia': - L, M, S = simulate_protanopia(L, M, S) - elif colorblind_type == 'deuteranopia': - L, M, S = simulate_deuteranopia(L, M, S) - elif colorblind_type == 'tritanopia': - L, M, S = simulate_tritanopia(L, M, S) - elif colorblind_type == 'achromatopsia': - L, M, S = simulate_achromatopsia(L, M, S) - else: + if cvd_type == 'achromatopsia': + gray = int(0.299 * R + 0.587 * G + 0.114 * B) + return (gray, gray, gray) + + # severity 接近 0 时直接返回原值,避免矩阵往返精度损失 + if severity < 0.001: + return rgb + + matrix = _get_blind_matrix(cvd_type, severity) + if matrix is None: return rgb - # 转换回 RGB - return lms_to_rgb(L, M, S) + r_norm = R / 255.0 + g_norm = G / 255.0 + b_norm = B / 255.0 + + r_lin = _gamma_linearize(r_norm) + g_lin = _gamma_linearize(g_norm) + b_lin = _gamma_linearize(b_norm) + + lms = _apply_matrix((r_lin, g_lin, b_lin), MACHADO_LMS_FROM_RGB) + + lms_blind = _apply_matrix(lms, matrix) + + rgb_lin = _apply_matrix(lms_blind, MACHADO_RGB_FROM_LMS) + + r_out = _gamma_delinearize(rgb_lin[0]) + g_out = _gamma_delinearize(rgb_lin[1]) + b_out = _gamma_delinearize(rgb_lin[2]) + + return ( + int(max(0, min(255, r_out * 255))), + int(max(0, min(255, g_out * 255))), + int(max(0, min(255, b_out * 255))), + ) def get_colorblind_info(colorblind_type: str) -> dict[str, str]: """获取色盲类型的信息 - + Args: colorblind_type: 色盲类型 - + Returns: 包含名称和描述的字典 """ @@ -216,8 +227,8 @@ def get_colorblind_info(colorblind_type: str) -> dict[str, str]: def get_all_colorblind_types() -> dict[str, dict[str, str]]: """获取所有支持的色盲类型 - + Returns: 色盲类型字典,键为类型标识,值为信息字典 """ - return COLORBLIND_TYPES.copy() + return COLORBLIND_TYPES.copy() \ No newline at end of file diff --git a/core/gradient.py b/core/gradient.py index e77247514c786e4cab60e9f83e1ed0a883307904..39cbcbcadbe46182cc66465c520ccf2ecb3ec53a 100644 --- a/core/gradient.py +++ b/core/gradient.py @@ -4,7 +4,7 @@ from __future__ import annotations # 项目模块导入 -from .color import hex_to_rgb, rgb_to_hsb, rgb_to_lab, hsb_to_rgb, rgb_to_hsl, hsl_to_rgb +from .color import hex_to_rgb, rgb_to_hsb, rgb_to_lab, hsb_to_rgb, rgb_to_hsl, hsl_to_rgb, lab_to_rgb def _normalize_hue_for_interpolation(h1: float, h2: float) -> tuple[float, float]: @@ -146,65 +146,12 @@ def _interpolate_lab(start_rgb: tuple[int, int, int], end_rgb: tuple[int, int, i A = A1 + (A2 - A1) * t B = B1 + (B2 - B1) * t # 转换回RGB - colors.append(_lab_to_rgb(L, A, B)) + colors.append(lab_to_rgb(L, A, B)) colors.append(end_rgb) return colors -def _lab_to_rgb(L: float, A: float, B: float) -> tuple[int, int, int]: - """将LAB颜色空间转换为RGB - - 这是rgb_to_lab的逆运算 - - Args: - L: 亮度分量 (0-100) - A: 红绿对立分量 (-128-127) - B: 黄蓝对立分量 (-128-127) - - Returns: - tuple[int, int, int]: RGB颜色值 (R, G, B),每个值范围0-255 - """ - # 步骤1: 从LAB转换到XYZ - def f_inv(t: float) -> float: - """f函数的逆函数""" - if t > 0.20689655172413793: # (6/29)^3 的立方根 - return t ** 3 - else: - return 3 * 0.12841854934601665 * 0.12841854934601665 * (t - 16 / 116) - - # 参考白点 (D65) - x_ref, y_ref, z_ref = 0.95047, 1.00000, 1.08883 - - # 计算f(Y), f(X), f(Z) - fy = (L + 16) / 116 - fx = fy + A / 500 - fz = fy - B / 200 - - # 计算XYZ - x = x_ref * f_inv(fx) - y = y_ref * f_inv(fy) - z = z_ref * f_inv(fz) - - # 步骤2: 从XYZ转换到线性RGB - r_linear = x * 3.2404542 + y * -1.5371385 + z * -0.4985314 - g_linear = x * -0.9692660 + y * 1.8760108 + z * 0.0415560 - b_linear = x * 0.0556434 + y * -0.2040259 + z * 1.0572252 - - # 步骤3: 应用gamma校正(从线性空间转换到sRGB) - def linear_to_srgb(c: float) -> float: - if c <= 0.0031308: - return c * 12.92 - else: - return 1.055 * (c ** (1 / 2.4)) - 0.055 - - r = max(0, min(255, round(linear_to_srgb(r_linear) * 255))) - g = max(0, min(255, round(linear_to_srgb(g_linear) * 255))) - b_out = max(0, min(255, round(linear_to_srgb(b_linear) * 255))) - - return r, g, b_out - - def generate_gradient( start_hex: str, end_hex: str, @@ -307,7 +254,7 @@ def generate_lightness_shades( L, A, B = rgb_to_lab(*base_rgb) for i in range(count): lightness = max_lightness - i * step - colors.append(_lab_to_rgb(lightness, A, B)) + colors.append(lab_to_rgb(lightness, A, B)) elif color_space == 'hsl': # HSL空间:固定H/S,L从95%到10%均匀分布 H, S, _ = rgb_to_hsl(*base_rgb) @@ -346,3 +293,134 @@ def generate_random_lightness_shade( colors = generate_lightness_shades(base_hex, count, color_space) return base_hex, colors + + +def _interpolate_segment( + start_rgb: tuple[int, int, int], + end_rgb: tuple[int, int, int], + steps: int, + color_space: str +) -> list[tuple[int, int, int]]: + """单段颜色插值 + + Args: + start_rgb: 起始RGB颜色 + end_rgb: 结束RGB颜色 + steps: 中间色数量 + color_space: 颜色空间 + + Returns: + list[tuple[int, int, int]]: RGB颜色列表(包含起始色和结束色) + """ + if steps == 0: + return [start_rgb, end_rgb] + + if color_space == 'rgb': + return _interpolate_rgb(start_rgb, end_rgb, steps) + elif color_space == 'hsb': + return _interpolate_hsb(start_rgb, end_rgb, steps) + elif color_space == 'hsl': + return _interpolate_hsl(start_rgb, end_rgb, steps) + else: + return _interpolate_lab(start_rgb, end_rgb, steps) + + +def generate_three_color_gradient( + start_hex: str, + mid_hex: str, + end_hex: str, + mid_position: float, + steps: int, + color_space: str = 'lab' +) -> list[tuple[int, int, int]]: + """生成三色渐变色序列 + + 中间控制色作为中间色之一,根据位置分配两段插值的中间色数量 + 总颜色数 = 1(起始) + steps(中间色,包含中间控制色) + 1(结束) + + 中间控制色在色卡序列中的索引 = round(mid_position * (steps + 1)) + 例如:steps=3, mid_position=0.4, 总颜色数=5 + 中间控制色索引 = round(0.4 * 4) = 2 (第3个位置) + + Args: + start_hex: 起始颜色HEX值 + mid_hex: 中间控制色HEX值 + end_hex: 结束颜色HEX值 + mid_position: 中间控制色位置 (0.1~0.9) + steps: 中间色总数量 (1-10),包含中间控制色 + color_space: 颜色空间 ('rgb', 'hsb', 'hsl', 'lab'),默认'lab' + + Returns: + list[tuple[int, int, int]]: RGB颜色列表 + + Raises: + ValueError: 当输入的HEX值格式无效时 + """ + start_rgb = hex_to_rgb(start_hex) + mid_rgb = hex_to_rgb(mid_hex) + end_rgb = hex_to_rgb(end_hex) + + steps = max(1, min(10, steps)) + mid_position = max(0.1, min(0.9, mid_position)) + + # 计算中间控制色在色卡序列中的目标索引 + # 总段数 = steps + 1 (从起始到结束) + total_segments = steps + 1 + target_index = round(mid_position * total_segments) + # 限制范围:不能在起始(0)或结束(steps+1)位置 + target_index = max(1, min(steps, target_index)) + + # A→B 段的中间色数量(在起始色和中间控制色之间) + steps_first = target_index - 1 + # B→C 段的中间色数量(在中间控制色和结束色之间) + steps_second = steps - target_index + + # A→B 段:起始色 + 中间色 + 中间控制色 + if steps_first == 0: + colors_first = [start_rgb, mid_rgb] + else: + colors_first = _interpolate_segment(start_rgb, mid_rgb, steps_first, color_space) + + # B→C 段:中间控制色 + 中间色 + 结束色 + if steps_second == 0: + colors_second = [mid_rgb, end_rgb] + else: + colors_second = _interpolate_segment(mid_rgb, end_rgb, steps_second, color_space) + + # 合并,去掉重复的中间控制色 + result = colors_first[:-1] + colors_second + + return result + + +def generate_random_three_color_gradient( + steps: int = 2, + color_space: str = 'lab' +) -> tuple[str, str, str, float, list[tuple[int, int, int]]]: + """生成随机三色渐变 + + Args: + steps: 中间色数量 (1-10),默认2 + color_space: 颜色空间 ('rgb', 'hsb', 'hsl', 'lab'),默认'lab' + + Returns: + tuple: (起始色HEX, 中间色HEX, 结束色HEX, 中间色位置, RGB颜色列表) + """ + import random + from .color import rgb_to_hex + + start_rgb = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) + mid_rgb = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) + end_rgb = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) + + start_hex = rgb_to_hex(*start_rgb) + mid_hex = rgb_to_hex(*mid_rgb) + end_hex = rgb_to_hex(*end_rgb) + + mid_position = random.uniform(0.2, 0.8) + + colors = generate_three_color_gradient( + start_hex, mid_hex, end_hex, mid_position, steps, color_space + ) + + return start_hex, mid_hex, end_hex, mid_position, colors diff --git a/core/histogram_service.py b/core/histogram_service.py index 817fccd4becfc395f5b9861a1fe178538ce71ab1..303a0fa551dd01cee66eaddbe7a0dfcf8fe00193 100644 --- a/core/histogram_service.py +++ b/core/histogram_service.py @@ -4,6 +4,7 @@ from __future__ import annotations from typing import Any # 第三方库导入 +import numpy as np from PySide6.QtCore import QObject, QThread, Signal, QTimer, Qt from PySide6.QtGui import QImage @@ -336,8 +337,6 @@ class HistogramService(QObject): Returns: dict[str, Any]: 统计信息字典,包含 mean, median, std, min_val, max_val """ - import numpy as np - total_pixels = sum(histogram) if total_pixels == 0: return { diff --git a/core/luminance_service.py b/core/luminance_service.py index f4cda0070906d5c910f3eb71854d233d2694238a..22b3dfc3c87d99a6a48a84626cce5438245c9984 100644 --- a/core/luminance_service.py +++ b/core/luminance_service.py @@ -412,7 +412,7 @@ class LuminanceService(QObject): # 转为QImage mask_image = QImage( - rgba.tobytes(), + rgba.data, disp_w, disp_h, disp_w * 4, QImage.Format.Format_RGBA8888 @@ -495,7 +495,7 @@ class LuminanceService(QObject): # 转为QImage mask_image = QImage( - rgba.tobytes(), + rgba.data, disp_w, disp_h, disp_w * 4, QImage.Format.Format_RGBA8888 diff --git a/core/palette_service.py b/core/palette_service.py index 317ee3e12a7cf828e76c7c7f428505e58ff1bb91..32e5488dec9e84ad8ef3fde46b6d9bb4c9f09650 100644 --- a/core/palette_service.py +++ b/core/palette_service.py @@ -21,7 +21,7 @@ from PySide6.QtCore import QObject, QThread, Signal, Qt from PySide6.QtGui import QImage, QPainter, QColor, QFont, QFontMetrics, QPixmap # 项目模块导入 -from .color import hex_to_rgb, get_color_info +from .color import hex_to_rgb, get_color_info, get_color_info_batch from .grouping import generate_groups from .logger import get_logger, log_performance @@ -125,15 +125,22 @@ class PaletteImporter(QThread): continue colors = [] + rgb_list = [] + + # 收集有效的颜色数据 for hex_color in colors_data: if isinstance(hex_color, str) and hex_color.startswith('#'): try: r, g, b = hex_to_rgb(hex_color) - color_info = get_color_info(r, g, b) - colors.append(color_info) - except Exception: + rgb_list.append((r, g, b)) + except (ValueError, AttributeError): colors.append({"hex": hex_color, "rgb": (0, 0, 0)}) + # 批量处理颜色信息 + if rgb_list: + color_infos = get_color_info_batch(rgb_list) + colors.extend(color_infos) + if colors: favorite_data = { "id": str(uuid.uuid4()), diff --git a/dialogs/colorblind_dialog.py b/dialogs/colorblind_dialog.py index 3814b2eec87e7f57c5ac30b6f8d915c7221e821e..5608ffd0dd45ab1b94ec20ff99e7bd433ca2c701 100644 --- a/dialogs/colorblind_dialog.py +++ b/dialogs/colorblind_dialog.py @@ -1,137 +1,53 @@ """色盲模拟预览对话框 -提供配色方案的色盲模拟预览功能,支持多种色盲类型切换。 +提供配色方案的色盲模拟预览功能,支持多种色盲类型切换和严重程度调节。 """ from __future__ import annotations -# 标准库导入 - - -# 第三方库导入 from PySide6.QtCore import Qt from PySide6.QtWidgets import ( QHBoxLayout, QLabel, QVBoxLayout, QWidget ) -from PySide6.QtGui import QColor +from PySide6.QtGui import QColor, QPainter from qfluentwidgets import ( - ComboBox, qconfig, ScrollArea, ScrollBarHandleDisplayMode + ComboBox, Slider, qconfig ) -# 项目模块导入 from utils import tr, load_icon_universal from dialogs import BaseFramelessDialog from core.colorblind import ( simulate_colorblind, get_colorblind_info, get_all_colorblind_types ) from utils.theme_colors import ( - get_text_color, get_border_color, - get_secondary_text_color, get_title_color + get_text_color, get_secondary_text_color, + get_title_color ) -class ColorBlock(QWidget): - """颜色块组件""" +class PalettePreviewStrip(QWidget): + """配色色块条,横排显示一组色块""" - def __init__(self, width: int = 60, height: int = 40, parent=None): + def __init__(self, parent=None): super().__init__(parent) - self.setFixedSize(width, height) - self._color = QColor(200, 200, 200) + self._colors: list[tuple[int, int, int]] = [] + self.setFixedHeight(40) - def set_color(self, rgb: tuple[int, int, int]): - """设置颜色""" - self._color = QColor(rgb[0], rgb[1], rgb[2]) + def set_colors(self, colors: list[tuple[int, int, int]]): + self._colors = colors self.update() def paintEvent(self, event): - """绘制颜色块""" - from PySide6.QtGui import QPainter, QBrush, QPen - painter = QPainter(self) painter.setRenderHint(QPainter.RenderHint.Antialiasing) - - # 绘制背景 - painter.setPen(Qt.PenStyle.NoPen) - painter.setBrush(QBrush(self._color)) - painter.drawRoundedRect(0, 0, self.width(), self.height(), 6, 6) - - -class ColorComparisonRow(QWidget): - """颜色对比行组件 - 显示原颜色和模拟颜色""" - - def __init__(self, parent=None): - super().__init__(parent) - self.setup_ui() - self._update_styles() - - def setup_ui(self): - """设置界面""" - layout = QHBoxLayout(self) - layout.setContentsMargins(10, 8, 10, 8) - layout.setSpacing(10) - - # 左侧固定宽度区域(颜色块 + 箭头) - color_area = QWidget() - color_area_layout = QHBoxLayout(color_area) - color_area_layout.setContentsMargins(0, 0, 0, 0) - color_area_layout.setSpacing(5) - color_area.setFixedWidth(155) - - # 原颜色块 - self.original_block = ColorBlock(50, 32) - color_area_layout.addWidget(self.original_block) - - # 箭头标签 - self.arrow_label = QLabel("→") - self.arrow_label.setStyleSheet("font-size: 16px;") - self.arrow_label.setFixedWidth(16) - self.arrow_label.setAlignment(Qt.AlignmentFlag.AlignCenter) - color_area_layout.addWidget(self.arrow_label) - - # 模拟颜色块 - self.simulated_block = ColorBlock(50, 32) - color_area_layout.addWidget(self.simulated_block) - - layout.addWidget(color_area) - - # 颜色值信息 - info_layout = QVBoxLayout() - info_layout.setSpacing(4) - - self.original_hex = QLabel(tr('dialogs.colorblind.original') + ": #------") - self.original_hex.setStyleSheet("font-size: 12px;") - info_layout.addWidget(self.original_hex) - - self.simulated_hex = QLabel(tr('dialogs.colorblind.simulated') + ": #------") - self.simulated_hex.setStyleSheet("font-size: 12px;") - info_layout.addWidget(self.simulated_hex) - - layout.addLayout(info_layout) - layout.addStretch() - - def _update_styles(self): - """更新样式以适配主题""" - secondary_color = get_secondary_text_color() - self.arrow_label.setStyleSheet(f"font-size: 18px; color: {secondary_color.name()};") - self.original_hex.setStyleSheet(f"font-size: 12px; color: {secondary_color.name()};") - self.simulated_hex.setStyleSheet(f"font-size: 12px; color: {secondary_color.name()};") - - def set_colors(self, original_rgb: tuple[int, int, int], simulated_rgb: tuple[int, int, int]): - """设置颜色对比 - - Args: - original_rgb: 原始 RGB 颜色 - simulated_rgb: 模拟后的 RGB 颜色 - """ - self.original_block.set_color(original_rgb) - self.simulated_block.set_color(simulated_rgb) - - # 更新 HEX 显示 - original_hex = f"#{original_rgb[0]:02X}{original_rgb[1]:02X}{original_rgb[2]:02X}" - simulated_hex = f"#{simulated_rgb[0]:02X}{simulated_rgb[1]:02X}{simulated_rgb[2]:02X}" - - self.original_hex.setText(f"{tr('dialogs.colorblind.original')}: {original_hex}") - self.simulated_hex.setText(f"{tr('dialogs.colorblind.simulated')}: {simulated_hex}") + if not self._colors: + return + n = len(self._colors) + w = self.width() // n + for i, rgb in enumerate(self._colors): + painter.setPen(Qt.PenStyle.NoPen) + painter.setBrush(QColor(rgb[0], rgb[1], rgb[2])) + painter.drawRoundedRect(i * w + 2, 2, w - 4, self.height() - 4, 4, 4) class ColorblindPreviewDialog(BaseFramelessDialog): @@ -140,180 +56,146 @@ class ColorblindPreviewDialog(BaseFramelessDialog): 显示配色方案在不同色盲类型下的视觉效果。 """ - def __init__(self, scheme_name: str, colors: list[Dict], parent=None): - """初始化色盲预览对话框 - - Args: - scheme_name: 配色方案名称 - colors: 颜色列表,每个颜色是一个字典,包含 'rgb' 键 - parent: 父窗口 - """ + def __init__(self, scheme_name: str, colors: list[dict], parent=None): super().__init__(parent) self._scheme_name = scheme_name self._colors = colors self._current_type = 'normal' + self._severity = 0.5 self.setWindowTitle(tr('dialogs.colorblind.window_title', name=scheme_name)) - self.setFixedSize(320, 420) + self.setFixedSize(600, 380) - # 设置窗口图标 self.setWindowIcon(load_icon_universal()) - # 设置界面 self.setup_ui() - - # 设置标题栏和样式 self._setup_title_bar() self._update_styles() - # 更新预览 self.update_preview() - # 监听主题变化 self._theme_connection = qconfig.themeChangedFinished.connect( self._update_styles ) - # 样式准备好后允许显示 self._enable_show() def setup_ui(self): """设置界面布局""" main_layout = QVBoxLayout(self) main_layout.setContentsMargins(20, 40, 20, 20) - main_layout.setSpacing(15) - - # 获取主题颜色 - title_color = get_title_color() + main_layout.setSpacing(12) + text_color = get_text_color() secondary_color = get_secondary_text_color() - border_color = get_border_color() - - # 标题 + title_color = get_title_color() + title_label = QLabel(tr('dialogs.colorblind.title')) - title_label.setStyleSheet(f"font-size: 18px; font-weight: bold; color: {title_color.name()};") + title_label.setStyleSheet( + f"font-size: 18px; font-weight: bold; color: {title_color.name()};" + ) main_layout.addWidget(title_label) - + name_label = QLabel(tr('dialogs.colorblind.scheme_name', name=self._scheme_name)) name_label.setStyleSheet(f"font-size: 13px; color: {secondary_color.name()};") main_layout.addWidget(name_label) - - # 色盲类型选择 - type_layout = QHBoxLayout() - type_layout.setSpacing(10) - + + strip_label = QLabel(tr('dialogs.colorblind.original')) + strip_label.setStyleSheet(f"font-size: 12px; color: {secondary_color.name()};") + main_layout.addWidget(strip_label) + + self.original_strip = PalettePreviewStrip() + main_layout.addWidget(self.original_strip) + + simulated_label = QLabel(tr('dialogs.colorblind.simulated')) + simulated_label.setStyleSheet(f"font-size: 12px; color: {secondary_color.name()};") + main_layout.addWidget(simulated_label) + + self.simulated_strip = PalettePreviewStrip() + main_layout.addWidget(self.simulated_strip) + + control_layout = QHBoxLayout() + control_layout.setSpacing(10) + type_label = QLabel(tr('dialogs.colorblind.colorblind_type')) type_label.setStyleSheet(f"font-size: 13px; color: {text_color.name()};") - type_layout.addWidget(type_label) - + control_layout.addWidget(type_label) + self.type_combo = ComboBox() - self.type_combo.setMinimumWidth(150) - - # 添加色盲类型选项 + self.type_combo.setMinimumWidth(130) self._type_keys = [] colorblind_types = get_all_colorblind_types() for key, info in colorblind_types.items(): self.type_combo.addItem(info['name']) self._type_keys.append(key) - + self.type_combo.currentIndexChanged.connect(self._on_type_changed) - type_layout.addWidget(self.type_combo) - type_layout.addStretch() - - main_layout.addLayout(type_layout) - - # 列标题 - header_layout = QHBoxLayout() - header_layout.setSpacing(10) - - # 左侧固定宽度区域标题 - color_area_title = QWidget() - color_area_title_layout = QHBoxLayout(color_area_title) - color_area_title_layout.setContentsMargins(5, 0, 0, 0) - color_area_title_layout.setSpacing(5) - color_area_title.setFixedWidth(155) - - original_title = QLabel(tr('dialogs.colorblind.original_color')) - original_title.setStyleSheet(f"font-size: 14px; font-weight: bold; color: {text_color.name()};") - original_title.setAlignment(Qt.AlignmentFlag.AlignCenter) - original_title.setFixedWidth(60) - color_area_title_layout.addWidget(original_title) - - arrow_spacer = QLabel("") - arrow_spacer.setFixedWidth(15) - color_area_title_layout.addWidget(arrow_spacer) - - simulated_title = QLabel(tr('dialogs.colorblind.simulated_color')) - simulated_title.setStyleSheet(f"font-size: 14px; font-weight: bold; color: {text_color.name()};") - simulated_title.setAlignment(Qt.AlignmentFlag.AlignCenter) - simulated_title.setFixedWidth(70) - color_area_title_layout.addWidget(simulated_title) - - header_layout.addWidget(color_area_title) - header_layout.addStretch() - main_layout.addLayout(header_layout) - - # 颜色对比列表(带滚动条) - scroll_area = ScrollArea() - scroll_area.scrollDelagate.vScrollBar.setHandleDisplayMode(ScrollBarHandleDisplayMode.ON_HOVER) - scroll_area.setWidgetResizable(True) - scroll_area.setStyleSheet(""" - ScrollArea { - background-color: transparent; - border: none; - } - ScrollArea > QWidget > QWidget { - background-color: transparent; - } - """) - scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff) - - self.comparison_container = QWidget() - self.comparison_layout = QVBoxLayout(self.comparison_container) - self.comparison_layout.setContentsMargins(0, 0, 0, 0) - self.comparison_layout.setSpacing(5) - self.comparison_layout.setAlignment(Qt.AlignmentFlag.AlignTop) - - # 创建颜色对比行 - self.comparison_rows = [] - for color_data in self._colors: - row = ColorComparisonRow() - self.comparison_rows.append(row) - self.comparison_layout.addWidget(row) - - self.comparison_layout.addStretch() - scroll_area.setWidget(self.comparison_container) - main_layout.addWidget(scroll_area, stretch=1) - - # 说明文字 + control_layout.addWidget(self.type_combo) + + self.severity_container = QWidget() + severity_layout = QHBoxLayout(self.severity_container) + severity_layout.setContentsMargins(0, 0, 0, 0) + severity_layout.setSpacing(6) + + self.severity_label = QLabel(tr('dialogs.colorblind.severity', value=50)) + self.severity_label.setStyleSheet(f"font-size: 13px; color: {text_color.name()};") + severity_layout.addWidget(self.severity_label) + + self.severity_slider = Slider(Qt.Orientation.Horizontal) + self.severity_slider.setRange(0, 100) + self.severity_slider.setValue(50) + self.severity_slider.setMinimumWidth(120) + self.severity_slider.valueChanged.connect(self._on_severity_changed) + severity_layout.addWidget(self.severity_slider, stretch=1) + + control_layout.addWidget(self.severity_container) + control_layout.addStretch() + main_layout.addLayout(control_layout) + self.description_label = QLabel("") - self.description_label.setStyleSheet(f"font-size: 12px; color: {secondary_color.name()}; padding: 5px;") + self.description_label.setStyleSheet( + f"font-size: 12px; color: {secondary_color.name()}; padding: 5px;" + ) self.description_label.setWordWrap(True) main_layout.addWidget(self.description_label) - + + self._update_severity_visibility() + def _on_type_changed(self, index: int): """色盲类型改变""" if 0 <= index < len(self._type_keys): self._current_type = self._type_keys[index] + self._update_severity_visibility() self.update_preview() - + + def _on_severity_changed(self, value: int): + """严重程度滑块回调""" + self._severity = value / 100.0 + self.severity_label.setText(tr('dialogs.colorblind.severity', value=value)) + self.update_preview() + + def _update_severity_visibility(self): + """根据当前色盲类型控制滑块可见性""" + is_anomal = self._current_type in ('protanomaly', 'deuteranomaly', 'tritanomaly') + self.severity_container.setVisible(is_anomal) + def update_preview(self): - """更新预览显示""" - # 更新每个颜色行的显示 - for i, row in enumerate(self.comparison_rows): - if i < len(self._colors): - color_data = self._colors[i] - original_rgb = tuple(color_data.get('rgb', [128, 128, 128])) - - # 计算模拟颜色 - simulated_rgb = simulate_colorblind(original_rgb, self._current_type) - - row.set_colors(original_rgb, simulated_rgb) - - # 更新说明文字 - info = get_colorblind_info(self._current_type) - self.description_label.setText(tr('dialogs.colorblind.description', desc=info['description'])) + """更新所有预览组件的显示""" + original_rgbs = [ + tuple(color_data.get('rgb', [128, 128, 128])) + for color_data in self._colors + ] + + severity = self._severity + simulated_rgbs = [ + simulate_colorblind(rgb, self._current_type, severity) + for rgb in original_rgbs + ] - def closeEvent(self, event): - """关闭事件""" - super().closeEvent(event) # 基类处理信号断开 + self.original_strip.set_colors(original_rgbs) + self.simulated_strip.set_colors(simulated_rgbs) + + info = get_colorblind_info(self._current_type) + self.description_label.setText( + tr('dialogs.colorblind.description', desc=info['description']) + ) diff --git a/docs/changelog.json b/docs/changelog.json index 124e6615cf4e8b98996c5275217c9772f1cad57b..c319b8d3d1f1ffa7a88cb43aa0567eeeede4a67d 100644 --- a/docs/changelog.json +++ b/docs/changelog.json @@ -1,5 +1,54 @@ { "versions": [ + { + "version": "v1.11.0", + "date": "2026-06-07", + "changes": [ + { + "category": "新增功能", + "items": [ + { + "title": "渐变生成", + "desc": "新增三色渐变模式" + }, + { + "title": "色盲模拟", + "desc": "色盲模拟算法升级为 Machado 2009 矩阵,新增异常三色视支持" + } + ] + }, + { + "category": "问题修复", + "items": [ + "修正配色生成面板翻译键层级错误", + "修复渐变模式切换后滑块位置显示异常,切换时自动重置中间色数量为默认值" + ] + }, + { + "category": "界面优化", + "items": [ + "色盲模拟对话框:扩大对话框尺寸,新增色块条预览功能,新增严重程度调节功能" + ] + }, + { + "category": "性能提升", + "items": [ + "提升颜色转换函数性能,避免重复创建函数对象", + "像素提取函数性能优化,消除 Python 对象创建开销", + "移除图片转 numpy 数组及 QImage 构造时冗余的数组拷贝", + "优化配色导入性能,添加批量处理函数", + "K-Means 聚类算法与主色调位置查找广播内存优化", + "直方图服务 numpy 导入提升至模块顶层" + ] + }, + { + "category": "代码优化", + "items": [ + "删除 color.py 和 gradient.py 中的重复函数定义" + ] + } + ] + }, { "version": "v1.10.2", "date": "2026-05-31", diff --git a/file/LICENSE.html b/file/LICENSE.html index 738be5ad3bb3163f260bc51afd2e79cca535b871..c033384ad4794d101d313885dcbba6dca67cced0 100644 --- a/file/LICENSE.html +++ b/file/LICENSE.html @@ -3,1186 +3,2003 @@ - 取色卡(Color Card) - 许可证 + 取色卡(Color Card) - 许可证信息 -
+
+ + +

取色卡(Color Card) - 许可证信息

- -
-

项目信息

-

项目名称:取色卡(Color Card)

-

版权所有:© 2026 浮晓 HXiao Studio

-

开发者:青山公仔

-

联系方式:hxiao_studio@163.com

-
- + +
+ + +
+

1. 项目信息

+

项目名称:取色卡(Color Card)

+

版权所有:© 2026 浮晓 HXiao Studio

+

开发者:青山公仔

+

联系方式:hxiao_studio@163.com

+
+ + +
+

2. 作者声明

+

虽然GPL v3允许商业使用,但作为作者,我恳请使用者遵守以下原则:

+
    +
  • 🔒 非商业使用:请勿将此工具用于商业盈利目的
  • +
  • 🤝 共享改进:欢迎提交改进,但请保持开源精神
  • +
+

请注意,这只是作者的道德请求,法律上仍遵循GPL v3条款。

+
+ + +
+

3. ⚠️ 重要提示

+

本项目包含以下许可证:

+
    +
  1. 主项目许可证:GNU General Public License v3.0 (GPLv3) — 见第4节
  2. +
  3. 第三方运行时库许可证:包含 LGPLv3、MIT、Apache 2.0、BSD-3-Clause 等 — 见第5节
  4. +
  5. 内置色彩方案许可证:主要为 MIT,部分为 Apache 2.0 — 见第6节
  6. +
  7. 网站使用资源许可证:MIT、Apache 2.0、SIL OFL 1.1 等 — 见第7节
  8. +
  9. 开发工具许可证:Nuitka (AGPLv3 + Runtime Library Exception) — 见第8节
  10. +
+

详细的许可证信息请查阅对应章节或应用程序的"关于"窗口。

+
+ + +
+

4. 主项目许可证

+ +
+

GNU GENERAL PUBLIC LICENSE

+

Version 3, 29 June 2007

+
+ + + +

Preamble

+

The GNU General Public License is a free, copyleft license for software and other kinds of works.

+

The licenses for most software and other practical works are designed to take away your freedom to share and + change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share + and change all versions of a program--to make sure it remains free software for all its users. We, the Free + Software Foundation, use the GNU General Public License for most of our software; it applies also to any other + work released this way by its authors. You can apply it to your programs, too.

+

When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are + designed to make sure that you have the freedom to distribute copies of free software (and charge for them if + you wish), that you receive source code or can get it if you want it, that you can change the software or use + pieces of it in new free programs, and that you know you can do these things.

+

To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the + rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you + modify it: responsibilities to respect the freedom of others.

+

For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the + recipients the same freedoms that you received. You must make sure that they, too, receive or can get the + source code. And you must show them these terms so they know their rights.

+

Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and + (2) offer you this License giving you legal permission to copy, distribute and/or modify it.

+

For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free + software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so + that their problems will not be attributed erroneously to authors of previous versions.

+

Some devices are designed to deny users access to install or run modified versions of the software inside them, + although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' + freedom to change the software. The systematic pattern of such abuse occurs in the area of products for + individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version + of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, + we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect + the freedom of users.

+

Finally, every program is threatened constantly by software patents. States should not allow patents to + restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid + the special danger that patents applied to a free program could make it effectively proprietary. To prevent + this, the GPL assures that patents cannot be used to render the program non-free.

+

The precise terms and conditions for copying, distribution and modification follow.

-
-

⚠️ 重要提示

-

本项目包含以下许可证:

+

TERMS AND CONDITIONS

+ + + +
+

0. Definitions.

+

"This License" refers to version 3 of the GNU General Public License.

+

"Copyright" also means copyright-like laws that apply to other kinds of works, + such as semiconductor masks.

+

"The Program" refers to any copyrightable work licensed under this License. Each + licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations.

+

To "modify" a work means to copy from or adapt all or part of the work in a + fashion requiring copyright permission, other than the making of an exact copy. The resulting work is + called a "modified version" of the earlier work or a work "based on" the earlier work.

+

A "covered work" means either the unmodified Program or a work based on the + Program.

+

To "propagate" a work means to do anything with it that, without permission, would + make you directly or secondarily liable for infringement under applicable copyright law, except executing + it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without + modification), making available to the public, and in some countries other activities as well.

+

To "convey" a work means any kind of propagation that enables other parties to + make or receive copies. Mere interaction with a user through a computer network, with no transfer of a + copy, is not conveying.

+

An interactive user interface displays "Appropriate Legal Notices" to the extent + that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright + notice, and (2) tells the user that there is no warranty for the work (except to the extent that + warranties are provided), that licensees may convey the work under this License, and how to view a copy of + this License. If the interface presents a list of user commands or options, such as a menu, a prominent + item in the list meets this criterion.

+
+ +
+

1. Source Code.

+

The "source code" for a work means the preferred form of the work for making + modifications to it. "Object code" means any non-source form of a work.

+

A "Standard Interface" means an interface that either is an official standard + defined by a recognized standards body, or, in the case of interfaces specified for a particular + programming language, one that is widely used among developers working in that language.

+

The "System Libraries" of an executable work include anything, other than the work + as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part + of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to + implement a Standard Interface for which an implementation is available to the public in source code form. + A "Major Component", in this context, means a major essential component (kernel, window system, and so on) + of the specific operating system (if any) on which the executable work runs, or a compiler used to produce + the work, or an object code interpreter used to run it.

+

The "Corresponding Source" for a work in object code form means all the source + code needed to generate, install, and (for an executable work) run the object code and to modify the work, + including scripts to control those activities. However, it does not include the work's System Libraries, + or general-purpose tools or generally available free programs which are used unmodified in performing + those activities but which are not part of the work. For example, Corresponding Source includes interface + definition files associated with source files for the work, and the source code for shared libraries and + dynamically linked subprograms that the work is specifically designed to require, such as by intimate data + communication or control flow between those subprograms and other parts of the work.

+

The Corresponding Source need not include anything that users can regenerate + automatically from other parts of the Corresponding Source.

+

The Corresponding Source for a work in source code form is that same work.

+
+ +
+

2. Basic Permissions.

+

All rights granted under this License are granted for the term of copyright on the Program, and are + irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited + permission to run the unmodified Program. The output from running a covered work is covered by this + License only if the output, given its content, constitutes a covered work. This License acknowledges your + rights of fair use or other equivalent, as provided by copyright law.

+

You may make, run and propagate covered works that you do not convey, without conditions so long as your + license otherwise remains in force. You may convey covered works to others for the sole purpose of having + them make modifications exclusively for you, or provide you with facilities for running those works, + provided that you comply with the terms of this License in conveying all material for which you do not + control copyright. Those thus making or running the covered works for you must do so exclusively on your + behalf, under your direction and control, on terms that prohibit them from making any copies of your + copyrighted material outside their relationship with you.

+

Conveying under any other circumstances is permitted solely under the conditions stated below. + Sublicensing is not allowed; section 10 makes it unnecessary.

+
+ +
+

3. Protecting Users' Legal Rights From Anti-Circumvention Law.

+

No covered work shall be deemed part of an effective technological measure under any applicable law + fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or + similar laws prohibiting or restricting circumvention of such measures.

+

When you convey a covered work, you waive any legal power to forbid circumvention of technological + measures to the extent such circumvention is effected by exercising rights under this License with respect + to the covered work, and you disclaim any intention to limit operation or modification of the work as a + means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention + of technological measures.

+
+ +
+

4. Conveying Verbatim Copies.

+

You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided + that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact + all notices stating that this License and any non-permissive terms added in accord with section 7 apply to + the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this + License along with the Program.

+

You may charge any price or no price for each copy that you convey, and you may offer support or warranty + protection for a fee.

+
+ +
+

5. Conveying Modified Source Versions.

+

You may convey a work based on the Program, or the modifications to produce it from the Program, in the + form of source code under the terms of section 4, provided that you also meet all of these conditions:

    -
  1. 主项目许可证:GNU General Public License v3.0 (GPLv3)
  2. -
  3. 第三方库许可证:包含 LGPL-3.0、GPL-3.0、MIT 等多种开源许可证
  4. +
  5. a) The work must carry prominent notices stating that you modified it, and giving a + relevant date. +
  6. +
  7. b) The work must carry prominent notices stating that it is released under this + License and any conditions added under section 7. This requirement modifies the requirement in section + 4 to "keep intact all notices". +
  8. +
  9. c) You must license the entire work, as a whole, under this License to anyone who + comes into possession of a copy. This License will therefore apply, along with any applicable section + 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. + This License gives no permission to license the work in any other way, but it does not invalidate such + permission if you have separately received it. +
  10. +
  11. d) If the work has interactive user interfaces, each must display Appropriate Legal + Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal + Notices, your work need not make them do so. +
-

详细的第三方库许可证信息请查看后续章节或应用程序的"关于"窗口。

-
+

A compilation of a covered work with other separate and independent works, which are not by their nature + extensions of the covered work, and which are not combined with it such as to form a larger program, in or + on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its + resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what + the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to + apply to the other parts of the aggregate.

+ + +
+

6. Conveying Non-Source Forms.

+

You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you + also convey the machine-readable Corresponding Source under the terms of this License, in one of these + ways:

+
    +
  1. a) Convey the object code in, or embodied in, a physical product (including a + physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical + medium customarily used for software interchange. +
  2. +
  3. b) Convey the object code in, or embodied in, a physical product (including a + physical distribution medium), accompanied by a written offer, valid for at least three years and + valid for as long as you offer spare parts or customer support for that product model, to give anyone + who possesses the object code either (1) a copy of the Corresponding Source for all the software in + the product that is covered by this License, on a durable physical medium customarily used for + software interchange, for a price no more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the Corresponding Source from a network server at no + charge. +
  4. +
  5. c) Convey individual copies of the object code with a copy of the written offer to + provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, + and only if you received the object code with such an offer, in accord with subsection 6b. +
  6. +
  7. d) Convey the object code by offering access from a designated place (gratis or for a + charge), and offer equivalent access to the Corresponding Source in the same way through the same + place at no further charge. You need not require recipients to copy the Corresponding Source along + with the object code. If the place to copy the object code is a network server, the Corresponding + Source may be on a different server (operated by you or a third party) that supports equivalent + copying facilities, provided you maintain clear directions next to the object code saying where to + find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain + obligated to ensure that it is available for as long as needed to satisfy these requirements. +
  8. +
  9. e) Convey the object code using peer-to-peer transmission, provided you inform other + peers where the object code and Corresponding Source of the work are being offered to the general + public at no charge under subsection 6d. +
  10. +
+

A separable portion of the object code, whose source code is excluded from the Corresponding Source as a + System Library, need not be included in conveying the object code work.

+

A "User Product" is either (1) a "consumer product", which means any tangible + personal property which is normally used for personal, family, or household purposes, or (2) anything + designed or sold for incorporation into a dwelling. In determining whether a product is a consumer + product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a + particular user, "normally used" refers to a typical or common use of that class of product, regardless of + the status of the particular user or of the way in which the particular user actually uses, or expects or + is expected to use, the product. A product is a consumer product regardless of whether the product has + substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant + mode of use of the product.

+

"Installation Information" for a User Product means any methods, procedures, + authorization keys, or other information required to install and execute modified versions of a covered + work in that User Product from a modified version of its Corresponding Source. The information must + suffice to ensure that the continued functioning of the modified object code is in no case prevented or + interfered with solely because modification has been made.

+

If you convey an object code work under this section in, or with, or specifically for use in, a User + Product, and the conveying occurs as part of a transaction in which the right of possession and use of the + User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the + transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by + the Installation Information. But this requirement does not apply if neither you nor any third party + retains the ability to install modified object code on the User Product (for example, the work has been + installed in ROM).

+

The requirement to provide Installation Information does not include a requirement to continue to provide + support service, warranty, or updates for a work that has been modified or installed by the recipient, or + for the User Product in which it has been modified or installed. Access to a network may be denied when + the modification itself materially and adversely affects the operation of the network or violates the rules + and protocols for communication across the network.

+

Corresponding Source conveyed, and Installation Information provided, in accord with this section must be + in a format that is publicly documented (and with an implementation available to the public in source code + form), and must require no special password or key for unpacking, reading or copying.

+
+ +
+

7. Additional Terms.

+

"Additional permissions" are terms that supplement the terms of this License by + making exceptions from one or more of its conditions. Additional permissions that are applicable to the + entire Program shall be treated as though they were included in this License, to the extent that they are + valid under applicable law. If additional permissions apply only to part of the Program, that part may be + used separately under those permissions, but the entire Program remains governed by this License without + regard to the additional permissions.

+

When you convey a copy of a covered work, you may at your option remove any additional permissions from + that copy, or from any part of it. (Additional permissions may be written to require their own removal in + certain cases when you modify the work.) You may place additional permissions on material, added by you to + a covered work, for which you have or can give appropriate copyright permission.

+

Notwithstanding any other provision of this License, for material you add to a covered work, you may (if + authorized by the copyright holders of that material) supplement the terms of this License with terms:

+
    +
  1. a) Disclaiming warranty or limiting liability differently from the terms of sections + 15 and 16 of this License; or +
  2. +
  3. b) Requiring preservation of specified reasonable legal notices or author attributions + in that material or in the Appropriate Legal Notices displayed by works containing it; or +
  4. +
  5. c) Prohibiting misrepresentation of the origin of that material, or requiring that + modified versions of such material be marked in reasonable ways as different from the original + version; or +
  6. +
  7. d) Limiting the use for publicity purposes of names of licensors or authors of the + material; or +
  8. +
  9. e) Declining to grant rights under trademark law for use of some trade names, + trademarks, or service marks; or +
  10. +
  11. f) Requiring indemnification of licensors and authors of that material by anyone who + conveys the material (or modified versions of it) with contractual assumptions of liability to the + recipient, for any liability that these contractual assumptions directly impose on those licensors and + authors. +
  12. +
+

All other non-permissive additional terms are considered "further restrictions" within the meaning of + section 10. If the Program as you received it, or any part of it, contains a notice stating that it is + governed by this License along with a term that is a further restriction, you may remove that term. If a + license document contains a further restriction but permits relicensing or conveying under this License, + you may add to a covered work material governed by the terms of that license document, provided that the + further restriction does not survive such relicensing or conveying.

+

If you add terms to a covered work in accord with this section, you must place, in the relevant source + files, a statement of the additional terms that apply to those files, or a notice indicating where to find + the applicable terms.

+

Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, + or stated as exceptions; the above requirements apply either way.

+
+ +
+

8. Termination.

+

You may not propagate or modify a covered work except as expressly provided under this License. Any + attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under + this License (including any patent licenses granted under the third paragraph of section 11).

+

However, if you cease all violation of this License, then your license from a particular copyright holder + is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates + your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some + reasonable means prior to 60 days after the cessation.

+

Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder + notifies you of the violation by some reasonable means, this is the first time you have received notice of + violation of this License (for any work) from that copyright holder, and you cure the violation prior to + 30 days after your receipt of the notice.

+

Termination of your rights under this section does not terminate the licenses of parties who have received + copies or rights from you under this License. If your rights have been terminated and not permanently + reinstated, you do not qualify to receive new licenses for the same material under section 10.

+
+ +
+

9. Acceptance Not Required for Having Copies.

+

You are not required to accept this License in order to receive or run a copy of the Program. Ancillary + propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to + receive a copy likewise does not require acceptance. However, nothing other than this License grants you + permission to propagate or modify any covered work. These actions infringe copyright if you do not accept + this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this + License to do so.

+
+ +
+

10. Automatic Licensing of Downstream Recipients.

+

Each time you convey a covered work, the recipient automatically receives a license from the original + licensors, to run, modify and propagate that work, subject to this License. You are not responsible for + enforcing compliance by third parties with this License.

+

An "entity transaction" is a transaction transferring control of an organization, + or substantially all assets of one, or subdividing an organization, or merging organizations. If + propagation of a covered work results from an entity transaction, each party to that transaction who + receives a copy of the work also receives whatever licenses to the work the party's predecessor in + interest had or could give under the previous paragraph, plus a right to possession of the Corresponding + Source of the work from the predecessor in interest, if the predecessor has it or can get it with + reasonable efforts.

+

You may not impose any further restrictions on the exercise of the rights granted or affirmed under this + License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights + granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim + in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or + importing the Program or any portion of it.

+
+ +
+

11. Patents.

+

A "contributor" is a copyright holder who authorizes use under this License of + the Program or a work on which the Program is based. The work thus licensed is called the contributor's + "contributor version".

+

A contributor's "essential patent claims" are all patent claims owned or + controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by + some manner, permitted by this License, of making, using, or selling its contributor version, but do not + include claims that would be infringed only as a consequence of further modification of the contributor + version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a + manner consistent with the requirements of this License.

+

Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the + contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, + modify and propagate the contents of its contributor version.

+

In the following three paragraphs, a "patent license" is any express agreement or + commitment, however denominated, not to enforce a patent (such as an express permission to practice a + patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means + to make such an agreement or commitment not to enforce a patent against the party.

+

If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the + work is not available for anyone to copy, free of charge and under the terms of this License, through a + publicly available network server or other readily accessible means, then you must either (1) cause the + Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent + license for this particular work, or (3) arrange, in a manner consistent with the requirements of this + License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual + knowledge that, but for the patent license, your conveying the covered work in a country, or your + recipient's use of the covered work in a country, would infringe one or more identifiable patents in that + country that you have reason to believe are valid.

+

If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by + procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the + covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, + then the patent license you grant is automatically extended to all recipients of the covered work and + works based on it.

+

A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits + the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically + granted under this License. You may not convey a covered work if you are a party to an arrangement with a + third party that is in the business of distributing software, under which you make payment to the third + party based on the extent of your activity of conveying the work, and under which the third party grants, + to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in + connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) + primarily for and in connection with specific products or compilations that contain the covered work, + unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.

+

Nothing in this License shall be construed as excluding or limiting any implied license or other defenses + to infringement that may otherwise be available to you under applicable patent law.

+
+ +
+

12. No Surrender of Others' Freedom.

+

If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the + conditions of this License, they do not excuse you from the conditions of this License. If you cannot + convey a covered work so as to satisfy simultaneously your obligations under this License and any other + pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to + terms that obligate you to collect a royalty for further conveying from those to whom you convey the + Program, the only way you could satisfy both those terms and this License would be to refrain entirely + from conveying the Program.

+
+ +
+

13. Use with the GNU Affero General Public License.

+

Notwithstanding any other provision of this License, you have permission to link or combine any covered + work with a work licensed under version 3 of the GNU Affero General Public License into a single combined + work, and to convey the resulting work. The terms of this License will continue to apply to the part which + is the covered work, but the special requirements of the GNU Affero General Public License, section 13, + concerning interaction through a network will apply to the combination as such.

+
+ +
+

14. Revised Versions of this License.

+

The Free Software Foundation may publish revised and/or new versions of the GNU General Public License + from time to time. Such new versions will be similar in spirit to the present version, but may differ in + detail to address new problems or concerns.

+

Each version is given a distinguishing version number. If the Program specifies that a certain numbered + version of the GNU General Public License "or any later version" applies to it, you have the option of + following the terms and conditions either of that numbered version or of any later version published by + the Free Software Foundation. If the Program does not specify a version number of the GNU General Public + License, you may choose any version ever published by the Free Software Foundation.

+

If the Program specifies that a proxy can decide which future versions of the GNU General Public License + can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose + that version for the Program.

+

Later license versions may give you additional or different permissions. However, no additional obligations + are imposed on any author or copyright holder as a result of your choosing to follow a later version.

+
+ +
+

15. Disclaimer of Warranty.

+

THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE + STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY + OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF + THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY + SERVICING, REPAIR OR CORRECTION.

+
+ +
+

16. Limitation of Liability.

+

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY + OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, + INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO + USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES + SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF + SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

+
+ +
+

17. Interpretation of Sections 15 and 16.

+

If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect + according to their terms, reviewing courts shall apply local law that most closely approximates an + absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of + liability accompanies a copy of the Program in return for a fee.

+
+ +
END OF TERMS AND CONDITIONS
+
+ + +
+

5. 第三方依赖许可证(运行时)

+

本项目使用了以下第三方库,每个库都有其自己的开源许可证:

+ + +
+

5.1 PySide6

+
+

版权所有:The Qt Company

+

Qt官网:https://www.qt.io/

+

许可证:GNU Lesser General Public License v3.0

+
-
-

GNU GENERAL PUBLIC LICENSE

+

GNU LESSER GENERAL PUBLIC LICENSE

Version 3, 29 June 2007

- + of this license document, but changing it is not allowed. +

-

Preamble

-
-

The GNU General Public License is a free, copyleft license for software and other kinds of works.

-

The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.

-

When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.

-

To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.

-

For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.

-

Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.

-

For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.

-

Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.

-

Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.

-

The precise terms and conditions for copying, distribution and modification follow.

-
+

This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 + of the GNU General Public License, supplemented by the additional permissions listed below.

-

TERMS AND CONDITIONS

- - +

0. Additional Definitions.

+

As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU + GPL" refers to version 3 of the GNU General Public License.

+

"The Library" refers to a covered work governed by this License, other than an Application or a Combined + Work as defined below.

+

An "Application" is any work that makes use of an interface provided by the Library, but which is not + otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of + using an interface provided by the Library.

+

A "Combined Work" is a work produced by combining or linking an Application with the Library. The + particular version of the Library with which the Combined Work was made is also called the "Linked + Version".

+

The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined + Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based + on the Application, and not on the Linked Version.

+

The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the + Application, including any data and utility programs needed for reproducing the Combined Work from the + Application, but excluding the System Libraries of the Combined Work.

-
-

0. Definitions.

-
"This License" refers to version 3 of the GNU General Public License.
-
"Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.
-
"The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations.
-
To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work.
-
A "covered work" means either the unmodified Program or a work based on the Program.
-
To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.
-
To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.
-
An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.
-
+

1. Exception to Section 3 of the GNU GPL.

+

You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of + the GNU GPL.

-
-

1. Source Code.

-
The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work.
-
A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.
-
The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.
-
The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.
-
The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.
-
The Corresponding Source for a work in source code form is that same work.
-
+

2. Conveying Modified Versions.

+

If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data + to be supplied by an Application that uses the facility (other than as an argument passed when the + facility is invoked), then you may convey a copy of the modified version:

+
    +
  1. a) under this License, provided that you make a good faith effort to ensure that, in + the event an Application does not supply the function or data, the facility still operates, and + performs whatever part of its purpose remains meaningful, or +
  2. +
  3. b) under the GNU GPL, with none of the additional permissions of this License + applicable to that copy. +
  4. +
-
-

2. Basic Permissions.

-

All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.

-

You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.

-

Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.

-
+

3. Object Code Incorporating Material from Library Header Files.

+

The object code form of an Application may incorporate material from a header file that is part of the + Library. You may convey such object code under terms of your choice, provided that, if the incorporated + material is not limited to numerical parameters, data structure layouts and accessors, or small macros, + inline functions and templates (ten or fewer lines in length), you do both of the following:

+
    +
  1. a) Give prominent notice with each copy of the object code that the Library is used + in it and that the Library and its use are covered by this License. +
  2. +
  3. b) Accompany the object code with a copy of the GNU GPL and this license document. +
  4. +
-
-

3. Protecting Users' Legal Rights From Anti-Circumvention Law.

-

No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.

-

When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.

-
+

4. Combined Works.

+

You may convey a Combined Work under terms of your choice that, taken together, effectively do not + restrict modification of the portions of the Library contained in the Combined Work and reverse + engineering for debugging such modifications, if you also do each of the following:

+
    +
  1. a) Give prominent notice with each copy of the Combined Work that the Library is used + in it and that the Library and its use are covered by this License. +
  2. +
  3. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. +
  4. +
  5. c) For a Combined Work that displays copyright notices during execution, include the + copyright notice for the Library among these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. +
  6. +
  7. d) Do one of the following: +
      +
    1. 0) Convey the Minimal Corresponding Source under the terms of this License, + and the Corresponding Application Code in a form suitable for, and under terms that permit, + the user to recombine or relink the Application with a modified version of the Linked Version + to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for + conveying Corresponding Source. +
    2. +
    3. 1) Use a suitable shared library mechanism for linking with the Library. A + suitable mechanism is one that (a) uses at run time a copy of the Library already present on + the user's computer system, and (b) will operate properly with a modified version of the + Library that is interface-compatible with the Linked Version. +
    4. +
    +
  8. +
  9. e) Provide Installation Information, but only if you would otherwise be required to + provide such information under section 6 of the GNU GPL, and only to the extent that such information + is necessary to install and execute a modified version of the Combined Work produced by recombining or + relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the + Installation Information must accompany the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation Information in the manner specified by + section 6 of the GNU GPL for conveying Corresponding Source.) +
  10. +
-
-

4. Conveying Verbatim Copies.

-

You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.

-

You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.

-
+

5. Combined Libraries.

+

You may place library facilities that are a work based on the Library side by side in a single library + together with other library facilities that are not Applications and are not covered by this License, and + convey such a combined library under terms of your choice, if you do both of the following:

+
    +
  1. a) Accompany the combined library with a copy of the same work based on the Library, + uncombined with any other library facilities, conveyed under the terms of this License. +
  2. +
  3. b) Give prominent notice with the combined library that part of it is a work based on + the Library, and explaining where to find the accompanying uncombined form of the same work. +
  4. +
-
-

5. Conveying Modified Source Versions.

-

You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:

-
    -
  1. a) The work must carry prominent notices stating that you modified it, and giving a relevant date.
  2. -
  3. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices".
  4. -
  5. c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.
  6. -
  7. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.
  8. -
-

A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.

-
+

6. Revised Versions of the GNU Lesser General Public License.

+

The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public + License from time to time. Such new versions will be similar in spirit to the present version, but may + differ in detail to address new problems or concerns.

+

Each version is given a distinguishing version number. If the Library as you received it specifies that a + certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, + you have the option of following the terms and conditions either of that published version or of any later + version published by the Free Software Foundation. If the Library as you received it does not specify a + version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser + General Public License ever published by the Free Software Foundation.

+

If the Library as you received it specifies that a proxy can decide whether future versions of the GNU + Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is + permanent authorization for you to choose that version for the Library.

+
-
-

6. Conveying Non-Source Forms.

-

You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:

-
    -
  1. a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.
  2. -
  3. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.
  4. -
  5. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.
  6. -
  7. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.
  8. -
  9. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.
  10. -
-

A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.

-
A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.
-
"Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.
-

If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).

-

The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.

-

Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.

+ + -
-

7. Additional Terms.

-
"Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.
-

When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.

-

Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:

-
    -
  1. a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
  2. -
  3. b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or
  4. -
  5. c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
  6. -
  7. d) Limiting the use for publicity purposes of names of licensors or authors of the material; or
  8. -
  9. e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
  10. -
  11. f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.
  12. -
-

All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.

-

If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.

-

Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.

+ +
+

5.3 Pillow

+
+

版权所有:Python Imaging Library Team

+

项目地址:https://github.com/python-pillow/Pillow +

+

官网:https://python-pillow.github.io/ +

+

许可证:MIT-CMU License

-
-

8. Termination.

-

You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).

-

However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.

-

Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.

-

Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.

+
+

MIT License (MIT-CMU)

-
-

9. Acceptance Not Required for Having Copies.

-

You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.

-
+

The Python Imaging Library (PIL) is

+

Copyright © 1997-2011 by Secret Labs AB
+ Copyright © 1995-2011 by Fredrik Lundh and contributors

+

Pillow is the friendly PIL fork. It is

+

Copyright © 2010 by Jeffrey A. Clark and contributors

+

Like PIL, Pillow is licensed under the open source MIT-CMU License:

+

By obtaining, using, and/or copying this software and/or its associated documentation, you agree that you + have read, understood, and will comply with the following terms and conditions:

+

Permission to use, copy, modify and distribute this software and its documentation for any purpose and + without fee is hereby granted, provided that the above copyright notice appears in all copies, and that + both that copyright notice and this permission notice appear in supporting documentation, and that the name + of Secret Labs AB or the author not be used in advertising or publicity pertaining to distribution of the + software without specific, written prior permission.

+

SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE + LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

+
-
-

10. Automatic Licensing of Downstream Recipients.

-

Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.

-
An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.
-

You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.

+ +
+

5.4 requests

+
+

版权所有:Kenneth Reitz

+

项目地址:https://github.com/psf/requests +

+

许可证:Apache License 2.0

-
-

11. Patents.

-
A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version".
-
A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.
-

Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.

-
In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.
-

If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.

-

If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.

-

A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.

-

Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.

+
+

NOTICE

+

Requests
Copyright 2019 Kenneth Reitz

-
-

12. No Surrender of Others' Freedom.

-

If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.

+
+

Apache License

+

Version 2.0, January 2004

+ +

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

-
-

13. Use with the GNU Affero General Public License.

-

Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.

-
+

1. Definitions.

+

"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by + Sections 1 through 9 of this document.

+

"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the + License.

+

"Legal Entity" shall mean the union of the acting entity and all other entities that control, are + controlled by, or are under common control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding + shares, or (iii) beneficial ownership of such entity.

+

"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this + License.

+

"Source" form shall mean the preferred form for making modifications, including but not limited to + software source code, documentation source, and configuration files.

+

"Object" form shall mean any form resulting from mechanical transformation or translation of a Source + form, including but not limited to compiled object code, generated documentation, and conversions to other + media types.

+

"Work" shall mean the work of authorship, whether in Source or Object form, made available under the + License, as indicated by a copyright notice that is included in or attached to the work (an example is + provided in the Appendix below).

+

"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived + from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works + shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof.

+

"Contribution" shall mean any work of authorship, including the original version of the Work and any + modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to + Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized + to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any + form of electronic, verbal, or written communication sent to the Licensor or its representatives, + including but not limited to communication on electronic mailing lists, source code control systems, and + issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing + and improving the Work, but excluding communication that is conspicuously marked or otherwise designated + in writing by the copyright owner as "Not a Contribution."

+

"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has + been received by Licensor and subsequently incorporated within the Work.

-
-

14. Revised Versions of this License.

-

The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

-

Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.

-

If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.

-

Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.

-
+

2. Grant of Copyright License.

+

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare + Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such + Derivative Works in Source or Object form.

-
-

15. Disclaimer of Warranty.

-

THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

-
+

3. Grant of Patent License.

+

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent + license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such + license applies only to those patent claims licensable by such Contributor that are necessarily infringed + by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such + Contribution(s) was submitted. If You institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the + Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under + this License for that Work shall terminate as of the date such litigation is filed.

-
-

16. Limitation of Liability.

-

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

-
+

4. Redistribution.

+

You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or + without modifications, and in Source or Object form, provided that You meet the following conditions:

+
    +
  1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
  2. +
  3. You must cause any modified files to carry prominent notices stating that You changed the files; + and +
  4. +
  5. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, + patent, trademark, and attribution notices from the Source form of the Work, excluding those notices + that do not pertain to any part of the Derivative Works; and +
  6. +
  7. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that + You distribute must include a readable copy of the attribution notices contained within such NOTICE + file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed as part of the Derivative Works; within + the Source form or documentation, if provided along with the Derivative Works; or, within a display + generated by the Derivative Works, if and wherever such third-party notices normally appear. The + contents of the NOTICE file are for informational purposes only and do not modify the License. You may + add Your own attribution notices within Derivative Works that You distribute, alongside or as an + addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be + construed as modifying the License. +
  8. +
+

You may add Your own copyright statement to Your modifications and may provide additional or different + license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such + Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise + complies with the conditions stated in this License.

-
-

17. Interpretation of Sections 15 and 16.

-

If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.

-
+

5. Submission of Contributions.

+

Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of this License, without any additional + terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any + separate license agreement you may have executed with Licensor regarding such Contributions.

-
- END OF TERMS AND CONDITIONS -
+

6. Trademarks.

+

This License does not grant permission to use the trade names, trademarks, service marks, or product names + of the Licensor, except as required for reasonable and customary use in describing the origin of the Work + and reproducing the content of the NOTICE file.

-
-

How to Apply These Terms to Your New Programs

-

If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

-

To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.

-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>

- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.

- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.

- You should have received a copy of the GNU General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>. -
-

Also add information on how to contact you by electronic and paper mail.

-

If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:

-
- <program> Copyright (C) <year> <name of author>
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details. -
-

The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box".

-

You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <https://www.gnu.org/licenses/>.

-

The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read <https://www.gnu.org/licenses/why-not-lgpl.html>.

-
-
+

7. Disclaimer of Warranty.

+

Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, + NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for + determining the appropriateness of using or redistributing the Work and assume any risks associated with + Your exercise of permissions under this License.

-
-

第三方库许可证

-

本项目使用了以下第三方库,每个库都有其自己的开源许可证:

- - -
-

1. PySide6

-
-

版权所有:The Qt Company

-

Qt官网:https://www.qt.io/

-

许可证:GNU Lesser General Public License v3.0

-
-
-
-

GNU LESSER GENERAL PUBLIC LICENSE

-

Version 3, 29 June 2007

-
- -
-

This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below.

-
-

0. Additional Definitions.

-
-

As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License.

-

"The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below.

-

An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library.

-

A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version".

-

The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version.

-

The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work.

-
-

1. Exception to Section 3 of the GNU GPL.

-
-

You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL.

-
-

2. Conveying Modified Versions.

-
-

If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version:

-
    -
  1. a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or
  2. -
  3. b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy.
  4. -
-
-

3. Object Code Incorporating Material from Library Header Files.

-
-

The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following:

-
    -
  1. a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License.
  2. -
  3. b) Accompany the object code with a copy of the GNU GPL and this license document.
  4. -
-
-

4. Combined Works.

-
-

You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following:

-
    -
  1. a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License.
  2. -
  3. b) Accompany the Combined Work with a copy of the GNU GPL and this license document.
  4. -
  5. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document.
  6. -
  7. d) Do one of the following: -
      -
    1. 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.
    2. -
    3. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version.
    4. -
    -
  8. -
  9. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.)
  10. -
-
-

5. Combined Libraries.

-
-

You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following:

-
    -
  1. a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License.
  2. -
  3. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.
  4. -
-
-

6. Revised Versions of the GNU Lesser General Public License.

-
-

The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

-

Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation.

-

If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library.

-
-
-
- - -
-

2. PySide6-Fluent-Widgets

-
-

版权所有:zhiyiYo

-

项目地址:https://github.com/zhiyiYo/PyQt-Fluent-Widgets

-

许可证:GNU General Public License v3.0

-
-
-
-

PySide6-Fluent-Widgets 使用 GPLv3 许可证。由于本项目主许可证也为 GPLv3,完整的 GPLv3 许可证文本请参考本文档前面的GNU GENERAL PUBLIC LICENSE Version 3章节。

-
-
-
- - -
-

3. Pillow

-
-

版权所有:Python Imaging Library Team

-

项目地址:https://github.com/python-pillow/Pillow

-

官网:https://python-pillow.github.io/

-

许可证:MIT-CMU License

-
-
-
-

MIT License

-
-
-

The Python Imaging Library (PIL) is

-

Copyright © 1997-2011 by Secret Labs AB
- Copyright © 1995-2011 by Fredrik Lundh and contributors

-

Pillow is the friendly PIL fork. It is

-

Copyright © 2010 by Jeffrey A. Clark and contributors

-

Like PIL, Pillow is licensed under the open source MIT-CMU License:

-

By obtaining, using, and/or copying this software and/or its associated documentation, you agree that you have read, understood, and will comply with the following terms and conditions:

-

Permission to use, copy, modify and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appears in all copies, and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Secret Labs AB or the author not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission.

-

SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

-
-
-
- - -
-

4. requests

-
-

版权所有:Kenneth Reitz

-

项目地址:https://github.com/psf/requests

-

许可证:Apache License 2.0

-
-
-

NOTICE

-

Requests
Copyright 2019 Kenneth Reitz

-
-
-
-

Apache License

-

Version 2.0, January 2004

-
- -
-

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

-
-

1. Definitions.

-
-

"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

-

"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

-

"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

-

"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.

-

"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

-

"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

-

"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

-

"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

-

"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."

-

"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

-
-

2. Grant of Copyright License.

-
-

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

-
-

3. Grant of Patent License.

-
-

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

-
-

4. Redistribution.

-
-

You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

-
    -
  1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
  2. -
  3. You must cause any modified files to carry prominent notices stating that You changed the files; and
  4. -
  5. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
  6. -
  7. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
  8. -
-

You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

-
-

5. Submission of Contributions.

-
-

Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

-
-

6. Trademarks.

-
-

This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

-
-

7. Disclaimer of Warranty.

-
-

Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

-
-

8. Limitation of Liability.

-
-

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

-
-

9. Accepting Warranty or Additional Liability.

-
-

While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

-
-
- END OF TERMS AND CONDITIONS -
-
+

8. Limitation of Liability.

+

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, + shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, + or consequential damages of any character arising as a result of this License or out of the use or + inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, + computer failure or malfunction, or any and all other commercial damages or losses), even if such + Contributor has been advised of the possibility of such damages.

+ +

9. Accepting Warranty or Additional Liability.

+

While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, + acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with + this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole + responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and + hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor + by reason of your accepting any such warranty or additional liability.

+ +
END OF TERMS AND CONDITIONS
+
+ + +
+

5.5 numpy

+
+

版权所有:NumPy Developers

+

项目地址:https://github.com/numpy/numpy +

+

官网:https://numpy.org/

+

许可证:BSD 3-Clause License

- - -
-

5. numpy

-
-

版权所有:NumPy Developers

-

项目地址:https://github.com/numpy/numpy

-

官网:https://numpy.org/

-

许可证:BSD 3-Clause License

-
-
-
-

BSD 3-Clause License

-
-
-

Copyright (c) 2005-2025, NumPy Developers

-

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

-
    -
  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. -
  3. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  4. -
  5. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  6. -
-

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-
-
+ +
+

BSD 3-Clause License

- -
-

6. PySideSix-Frameless-Window

-
-

版权所有:zhiyiYo

-

项目地址:https://github.com/zhiyiYo/PyQt-Frameless-Window

-

许可证:GNU Lesser General Public License v3.0

-
-
-
-

PySideSix-Frameless-Window 使用 LGPLv3 许可证。由于本项目主许可证为 GPLv3,而 LGPLv3 是 GPLv3 的补充版本,完整的 LGPLv3 许可证文本请参考本文档 PySide6 章节中的 "GNU LESSER GENERAL PUBLIC LICENSE Version 3" 部分。

-
-
+

Copyright (c) 2005-2025, NumPy Developers

+

Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met:

+
    +
  1. Redistributions of source code must retain the above copyright notice, this list of conditions and + the following disclaimer. +
  2. +
  3. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + the following disclaimer in the documentation and/or other materials provided with the distribution. +
  4. +
  5. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or + promote products derived from this software without specific prior written permission. +
  6. +
+

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.

+
+ + +
+

5.6 PySideSix-Frameless-Window

+
+

版权所有:zhiyiYo

+

项目地址:https://github.com/zhiyiYo/PyQt-Frameless-Window +

+

许可证:GNU Lesser General Public License v3.0

+
+

引用说明:PySideSix-Frameless-Window 使用 LGPLv3 许可证。完整的 LGPLv3 许可证文本请参阅本文件第5.1节「PySide6」中的 GNU Lesser General Public License Version 3。

+
+
+
+ + +
+

6. 内置色彩方案

- -
-

7. Open Color

-
-

版权所有:heeyeun (Yeun)

-

项目地址:https://github.com/yeun/open-color

-

官网:https://yeun.github.io/open-color/

-

许可证:MIT License

-

用途:内置色彩配色方案

-
-
-
-

MIT License

-
-
-

Copyright (c) 2016 heeyeun

-

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

-

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

-

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-
-
+ +
+

6.1 Open Color

+
+

版权所有:heeyeun (Yeun)

+

项目地址:https://github.com/yeun/open-color +

+

官网:https://yeun.github.io/open-color/ +

+

许可证:MIT License

+

用途:内置色彩配色方案

+

MIT License

+

Copyright (c) 2016 heeyeun

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + associated documentation files (the "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the + following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO + EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
- -
-

8. Nice Color Palettes

-
-

版权所有:Jam3

-

项目地址:https://github.com/Experience-Monks/nice-color-palettes

-

许可证:MIT License

-

用途:内置色彩配色方案

-
-
-
-

The MIT License (MIT)

-
-
-

Copyright (c) 2016 Jam3

-

Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:

-

The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.

-

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
- OR OTHER DEALINGS IN THE SOFTWARE.

-
-
+ +
+

6.2 Nice Color Palettes

+
+

版权所有:Jam3

+

项目地址:https://github.com/Experience-Monks/nice-color-palettes

+

许可证:MIT License

+

用途:内置色彩配色方案

+

The MIT License (MIT)

+

Copyright (c) 2016 Jam3

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + associated documentation files (the "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the + following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO + EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
- -
-

9. Tailwind CSS Colors

-
-

版权所有:Tailwind Labs, Inc.

-

项目地址:https://github.com/tailwindlabs/tailwindcss

-

官网:https://tailwindcss.com

-

许可证:MIT License

-

用途:内置色彩配色方案

-
-
-
-

MIT License

-
-
-

Copyright (c) Tailwind Labs, Inc.

-

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

-

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

-

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-
-
+ +
+

6.3 Tailwind CSS Colors

+
+

版权所有:Tailwind Labs, Inc.

+

项目地址:https://github.com/tailwindlabs/tailwindcss +

+

官网:https://tailwindcss.com

+

许可证:MIT License

+

用途:内置色彩配色方案

+

MIT License

+

Copyright (c) Tailwind Labs, Inc.

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + associated documentation files (the "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the + following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO + EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
- -
-

10. Material Design Colors

-
-

版权所有:Google LLC

-

项目地址:https://m3.material.io/styles/color/system/overview

-

许可证:Apache License 2.0

-

用途:内置色彩配色方案

-
-
-

- Material Design Colors 使用 Apache License 2.0 许可证。完整的许可证文本请参考 requests 章节中的 "Apache License Version 2.0" 部分。 -

-
+ +
+

6.4 Material Design Colors

+
+

版权所有:Google LLC

+

项目地址:https://m3.material.io/styles/color/system/overview

+

许可证:Apache License 2.0

+

用途:内置色彩配色方案

+
+

引用说明:Material Design Colors 使用 Apache License 2.0 许可证。完整的许可证文本请参阅本文件第5.4节「requests」中的 Apache License Version 2.0。

+
+
- -
-

11. ColorBrewer

-
-

版权所有:Cynthia Brewer

-

项目地址:https://colorbrewer2.org/

-

官网:https://colorbrewer2.org/

-

许可证:Apache License 2.0

-

用途:内置色彩配色方案

-
-
-

- ColorBrewer 使用 Apache License 2.0 许可证。完整的许可证文本请参考 Material Design Colors 章节中的 "Apache License Version 2.0" 部分。 -

-
+ +
+

6.5 ColorBrewer

+
+

版权所有:Cynthia Brewer

+

官网:https://colorbrewer2.org/ +

+

许可证:Apache License 2.0

+

用途:内置色彩配色方案

+
+

引用说明:ColorBrewer 使用 Apache License 2.0 许可证。完整的许可证文本请参阅本文件第5.4节「requests」中的 Apache License Version 2.0。

+
+
- -
-

12. Radix UI Colors

-
-

版权所有:WorkOS

-

项目地址:https://github.com/radix-ui/colors

-

官网:https://www.radix-ui.com/colors

-

许可证:MIT License

-

用途:内置色彩配色方案

-
-
-
-

MIT License

-
-
-

Copyright (c) 2021-2022 Modulz

-

Copyright (c) 2022-Present WorkOS

-

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

-

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

-

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-
-
+ +
+

6.6 Radix UI Colors

+
+

版权所有:WorkOS

+

项目地址:https://github.com/radix-ui/colors +

+

官网:https://www.radix-ui.com/colors +

+

许可证:MIT License

+

用途:内置色彩配色方案

+

MIT License

+

Copyright (c) 2021-2022 Modulz

+

Copyright (c) 2022-Present WorkOS

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + associated documentation files (the "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the + following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO + EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
- -
-

13. Nord

-
-

版权所有:Sven Greb

-

项目地址:https://github.com/arcticicestudio/nord

-

官网:https://www.nordtheme.com/

-

许可证:MIT License

-

用途:内置色彩配色方案

-
-
-
-

MIT License (MIT)

-
-
-

Copyright (c) 2016-present Sven Greb <development@svengreb.de> (https://www.svengreb.de)

-

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

-

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

-

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-
-
+ +
+

6.7 Nord

+
+

版权所有:Sven Greb

+

项目地址:https://github.com/arcticicestudio/nord +

+

官网:https://www.nordtheme.com/ +

+

许可证:MIT License

+

用途:内置色彩配色方案

+

MIT License (MIT)

+

Copyright (c) 2016-present Sven Greb <development@svengreb.de> (https://www.svengreb.de)

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + associated documentation files (the "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the + following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO + EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
- -
-

14. Dracula

-
-

版权所有:Dracula Theme contributors

-

官网:https://draculatheme.com/

-

许可证:MIT License

-

用途:内置色彩配色方案

-
-
-
-

MIT License

-
-
-

Copyright (c) Dracula Theme contributors

-

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

-

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

-

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-
-
+ +
+

6.8 Dracula

+
+

版权所有:Dracula Theme contributors

+

官网:https://draculatheme.com/ +

+

许可证:MIT License

+

用途:内置色彩配色方案

+

MIT License

+

Copyright (c) Dracula Theme contributors

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + associated documentation files (the "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the + following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO + EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
- -
-

15. Rosé Pine

-
-

版权所有:Rosé Pine 团队

-

项目地址:https://github.com/rose-pine/rose-pine-theme

-

官网:https://www.rosepine.com/

-

许可证:MIT License

-

用途:内置色彩配色方案

-
-
-
-

MIT License

-
-
-

Copyright (c) 2023 Rosé Pine

-

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

-

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

-

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-
-
+ +
+

6.9 Rosé Pine

+
+

版权所有:Rosé Pine 团队

+

项目地址:https://github.com/rose-pine/rose-pine-theme +

+

官网:https://www.rosepine.com/ +

+

许可证:MIT License

+

用途:内置色彩配色方案

+

MIT License

+

Copyright (c) 2023 Rosé Pine

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + associated documentation files (the "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the + following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO + EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
- -
-

16. Solarized

-
-

版权所有:Ethan Schoonover

-

项目地址:https://github.com/altercation/solarized

-

官网:https://ethanschoonover.com/solarized/

-

许可证:MIT License

-

用途:内置色彩配色方案

-
-
-
-

Copyright (c) 2011 Ethan Schoonover

-

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

-

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

-

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-
-
+ +
+

6.10 Solarized

+
+

版权所有:Ethan Schoonover

+

项目地址:https://github.com/altercation/solarized +

+

官网:https://ethanschoonover.com/solarized/ +

+

许可证:MIT License

+

用途:内置色彩配色方案

+

Copyright (c) 2011 Ethan Schoonover

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + associated documentation files (the "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the + following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO + EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
- -
-

17. Catppuccin

-
-

版权所有:Catppuccin 团队

-

项目地址:https://github.com/catppuccin/catppuccin

-

官网:https://catppuccin.com/

-

许可证:MIT License

-

用途:内置色彩配色方案

-
-
-
-

MIT License

-
-
-

Copyright (c) 2021 Catppuccin

-

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

-

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

-

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-
-
+ +
+

6.11 Catppuccin

+
+

版权所有:Catppuccin 团队

+

项目地址:https://github.com/catppuccin/catppuccin +

+

官网:https://catppuccin.com/

+

许可证:MIT License

+

用途:内置色彩配色方案

+

MIT License

+

Copyright (c) 2021 Catppuccin

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + associated documentation files (the "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the + following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO + EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
- -
-

18. Gruvbox (MIT/X11 License)

-
-

版权所有:Pavel Pertsev

-

项目地址:https://github.com/morhetz/gruvbox

-

许可证:MIT License

-

用途:内置色彩配色方案

-
-
-
-

MIT License

-
-
-

Copyright (c) 2012 Pavel Pertsev

-

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

-

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

-

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-
-
+ +
+

6.12 Gruvbox

+
+

版权所有:Pavel Pertsev

+

项目地址:https://github.com/morhetz/gruvbox +

+

许可证:MIT/X11 License

+

用途:内置色彩配色方案

+

Copyright (c) 2012 Pavel Pertsev

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + associated documentation files (the "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the + following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO + EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
- -
-

19. Tokyo Night (MIT License)

-
-

版权所有:enkia

-

项目地址:https://github.com/enkia/tokyo-night-vscode-theme

-

许可证:MIT License

-

用途:内置色彩配色方案

-
-
-
-

The MIT License (MIT)

-

Copyright (c) 2018-present Enkia

-

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

-

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

-

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-
-
+ +
+

The MIT License (MIT)

+

Copyright (c) 2018-present Enkia

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + associated documentation files (the "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the + following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO + EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ +
+ + +
+

7. 网站使用资源

+

项目官网 (https://qingshangongzai.github.io/Color_Card/) + 使用了以下资源:

-
-

19. 网站使用资源

-

项目官网 (https://qingshangongzai.github.io/Color_Card/) 使用了以下资源:

- - -
-

1. Tailwind CSS (MIT License)

-
-

版权所有:Tailwind Labs, Inc.

-

项目地址:https://github.com/tailwindlabs/tailwindcss

-

官网:https://tailwindcss.com

-

来源:https://cdn.tailwindcss.com

-

许可证:MIT License

-

用途:CSS 样式框架

-
-

- Tailwind CSS 使用 MIT License 许可证。完整的许可证文本请参考第8节 "Tailwind CSS Colors" 中的 MIT License 部分。 + +

+

7.1 Tailwind CSS(CSS 框架)

+
+

版权所有:Tailwind Labs, Inc.

+

项目地址:https://github.com/tailwindlabs/tailwindcss

+

官网:https://tailwindcss.com

+

来源:https://cdn.tailwindcss.com +

+

许可证:MIT License

+

用途:CSS 样式框架(仅用于网站展示,不包含在最终分发的桌面应用程序中)

+

MIT License

+

Copyright (c) Tailwind Labs, Inc.

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + associated documentation files (the "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the + following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO + EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
- -
-

2. Inter 字体 (SIL OFL 1.1)

-
-

来源:Google Fonts

-

版权所有:© Rasmus Andersson

-

许可证:SIL Open Font License 1.1

-

用途:网站正文字体

-
+ +
+

7.2 Inter 字体

+
+

来源:Google Fonts +

+

版权所有:© Rasmus Andersson

+

许可证:SIL Open Font License 1.1

+

用途:网站正文字体(未随本软件分发,仅通过网站引用)

+
- -
-

3. Vue.js (MIT License)

-
-

版权所有:Yuxi (Evan) You and Vue contributors

-

项目地址:https://github.com/vuejs/core

-

官网:https://vuejs.org/

-

许可证:MIT License

-

用途:网站前端框架(仅用于开发,不包含在最终产品中)

-
-
-
-

MIT License

-
-
-

Copyright (c) 2018-present, Yuxi (Evan) You and Vue contributors

-

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

-

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

-

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-
-
+ +
+

7.3 Vue.js

+
+

版权所有:Yuxi (Evan) You and Vue contributors

+

项目地址:https://github.com/vuejs/core +

+

官网:https://vuejs.org/

+

许可证:MIT License

+

用途:网站前端框架(仅用于开发,不包含在最终产品中)

+

MIT License

+

Copyright (c) 2018-present, Yuxi (Evan) You and Vue contributors

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + associated documentation files (the "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the + following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO + EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
- -
-

4. TypeScript (Apache License 2.0)

-
-

版权所有:Microsoft Corporation

-

项目地址:https://github.com/microsoft/TypeScript

-

官网:https://www.typescriptlang.org/

-

许可证:Apache License 2.0

-

用途:网站开发类型系统(仅用于开发,不包含在最终产品中)

-
-

- TypeScript 使用 Apache License 2.0 许可证。完整的许可证文本请参考本文档第4节 "requests" 中的 Apache License 2.0 部分。 + +

- -
-

5. Vite (MIT License)

-
-

版权所有:Yuxi (Evan) You and Vite contributors

-

项目地址:https://github.com/vitejs/vite

-

官网:https://vitejs.dev/

-

许可证:MIT License

-

用途:网站开发构建工具(仅用于开发,不包含在最终产品中)

-
-
-
-

MIT License

-
-
-

Copyright (c) 2019-present, VoidZero Inc. and Vite contributors

-

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

-

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

-

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-
-
+ +
+

7.5 Vite

+
+

版权所有:Yuxi (Evan) You and Vite contributors

+

项目地址:https://github.com/vitejs/vite +

+

官网:https://vitejs.dev/

+

许可证:MIT License

+

用途:网站开发构建工具(仅用于开发,不包含在最终产品中)

+

MIT License

+

Copyright (c) 2019-present, VoidZero Inc. and Vite contributors

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + associated documentation files (the "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the + following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO + EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
- -
-

6. 开源配色方案展示

-
-

官网展示了13套开源配色方案(详见上文第6-18节),所有配色方案均遵循各自的开源许可证。

-
+ +
+

7.6 内置色彩方案展示

+
+

官网展示的13套开源配色方案(Open Color、Nice Color Palettes、Tailwind CSS Colors、Material Design + Colors、ColorBrewer、Radix UI Colors、Nord、Dracula、Rosé Pine、Solarized、Catppuccin、Gruvbox、Tokyo + Night)均遵循各自的开源许可证,具体信息请参见本文件第6节「内置色彩方案」

-
+ +
-
-

开发工具链许可证

-

本项目在开发过程中使用了以下工具:

- - -
-

1. Nuitka

-
-

版权所有:Kay Hayen

-

项目地址:https://github.com/Nuitka/Nuitka

-

官网:https://nuitka.net/

-

许可证:GNU Affero General Public License v3.0

-

用途:编译打包

-
-
-

说明:

-

Nuitka 是一款 Python 编译器,将 Python 代码编译为独立的可执行文件。

-

本项目使用 Nuitka 编译 Windows 和 Mac 版本。

-

Nuitka 采用双重许可:

-
    -
  1. GNU Affero General Public License v3.0 - 编译器本身
  2. -
  3. LICENSE-RUNTIME - 运行时组件,允许商业使用
  4. -
-

本项目仅使用 Nuitka 作为编译工具,生成的可执行文件适用 LICENSE-RUNTIME 条款。

-

Nuitka 编译器本身使用 AGPL-3.0 许可证。完整的 GPL-3.0 许可证文本请参考本文档前面的 "GNU GENERAL PUBLIC LICENSE Version 3" 章节,以下是 AGPL-3.0 相较 GPL-3.0 补充的部分。

-
-
-
-

GNU AFFERO GENERAL PUBLIC LICENSE

-

Section 13

-
-
-

13. Remote Network Interaction; Use with the GNU General Public License.

-

Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph.

-

Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the work with which it is combined will remain governed by version 3 of the GNU General Public License.

-
-
-
-
-

LICENSE-RUNTIME

-
-
-

Nuitka Runtime Library Exception

-

Version 1.0

-

This Nuitka Runtime Library Exception ("Exception") is an additional permission under section 7 of the GNU Affero General Public License, version 3 ("AGPLv3"). It applies to a given file (the "File") that bears a notice placed by the copyright holder of the file stating that the file is governed by AGPLv3 along with this Exception.

-

The purpose of this Exception is to allow the compilation of non-AGPL (including proprietary) Python programs to use, in this way, the header files and runtime libraries covered by this Exception, without the requirement that the resulting executable or library be licensed under the AGPLv3.

-

0. Definitions

-

"Runtime Library" means the Nuitka static C code, header files, and helper functions that are intended to be linked or included into the code generated by Nuitka.

-

"Independent Module" means a module which is not derived from or based on the Runtime Library. Usage of the Runtime Library interface (macros, function signatures, data structures) for the purpose of valid compilation/linking does not make a module "derived from" the Runtime Library for the purposes of this definition.

-

"Target Code" means an executable or library created by the Compilation Process.

-

"Compilation Process" means the process of transforming Python source code (or other input accepted by Nuitka) into C source code using Nuitka, and subsequently compiling and linking that C source code with the Runtime Library to produce Target Code.

-

1. Grant of Additional Permission

-

You have permission to propagate a work of Target Code formed by combining the Runtime Library with Independent Modules, even if such propagation would otherwise violate the terms of AGPLv3, provided that all Independent Modules are combined with the Runtime Library through the Compilation Process. You may then convey such a combination under terms of your choice.

-

2. No Weakening of Nuitka Copyleft

-

The availability of this Exception does not imply any general exception to the third-party beneficiary rights or other terms of the AGPLv3 for the Nuitka compiler itself (typically `nuitka` package logic), nor does it apply to the Compilation Process itself (i.e., you cannot distribute a modified version of the Nuitka compiler under proprietary terms). This Exception only applies to the *output* of the Compilation Process (the Target Code) that links against the Runtime Library.

-

3. Intention

-

This exception is intended to allow the creation of closed-source Python applications that use Nuitka, but it does prevent the creation of closed-source Nuitka itself except by the source code owner.

-
-
+ +
+

8. 开发工具链许可证

+

本项目在开发过程中使用了以下工具:

+ + +
+

8.1 Nuitka

+
+

版权所有:Kay Hayen

+

项目地址:https://github.com/Nuitka/Nuitka +

+

官网:https://nuitka.net/

+

主许可证类型:GNU Affero General Public License v3.0 (AGPLv3)

+

豁免性质:附带 Runtime Library Exception,明确允许编译生成的目标代码不受 AGPLv3 + 传染性限制,可选择不同的许可条款分发

+

用途:编译打包(仅作为开发工具使用)

-
-

使用说明

-
-

许可证约束

-
    -
  • 本项目整体受 GNU General Public License v3.0 约束
  • -
  • 使用本软件即表示您同意遵守所有相关许可证条款
  • -
+
+

说明:Nuitka 是一款 Python 编译器,将 Python 代码编译为独立的可执行文件。本项目使用 Nuitka 编译 Windows 和 Mac + 版本。Nuitka 采用双重许可:编译器本身使用 AGPLv3;运行时组件通过 LICENSE-RUNTIME 例外条款允许非 AGPL(包括专有)程序的编译产物以自选条款分发。本项目仅将 + Nuitka 作为编译工具使用,生成的可执行文件适用 LICENSE-RUNTIME 条款。以下为该豁免条款的全文。

- -
-

根据 GPLv3 要求:

-
    -
  • ✅ 您可以自由使用、修改、分发本软件
  • -
  • ✅ 您必须以 GPLv3 许可证开源您的修改版本
  • -
  • ✅ 您必须提供源代码
  • -
  • ❌ 您不能将本软件用于闭源商业项目
  • -
+ +
+

LICENSE-RUNTIME

- -

如有疑问,请联系: hxiao_studio@163.com

+ +

Nuitka Runtime Library Exception

+

Version 1.0

+

This Nuitka Runtime Library Exception ("Exception") is an additional permission under section 7 of the GNU + Affero General Public License, version 3 ("AGPLv3"). It applies to a given file (the "File") that bears a + notice placed by the copyright holder of the file stating that the file is governed by AGPLv3 along with + this Exception.

+

The purpose of this Exception is to allow the compilation of non-AGPL (including proprietary) Python + programs to use, in this way, the header files and runtime libraries covered by this Exception, without + the requirement that the resulting executable or library be licensed under the AGPLv3.

+ +

0. Definitions

+

"Runtime Library" means the Nuitka static C code, header files, and helper functions that are intended to + be linked or included into the code generated by Nuitka.

+

"Independent Module" means a module which is not derived from or based on the Runtime Library. Usage of + the Runtime Library interface (macros, function signatures, data structures) for the purpose of valid + compilation/linking does not make a module "derived from" the Runtime Library for the purposes of this + definition.

+

"Target Code" means an executable or library created by the Compilation Process.

+

"Compilation Process" means the process of transforming Python source code (or other input accepted by + Nuitka) into C source code using Nuitka, and subsequently compiling and linking that C source code with + the Runtime Library to produce Target Code.

+ +

1. Grant of Additional Permission

+

You have permission to propagate a work of Target Code formed by combining the Runtime Library with + Independent Modules, even if such propagation would otherwise violate the terms of AGPLv3, provided that + all Independent Modules are combined with the Runtime Library through the Compilation Process. You may + then convey such a combination under terms of your choice.

+ +

2. No Weakening of Nuitka Copyleft

+

The availability of this Exception does not imply any general exception to the third-party beneficiary + rights or other terms of the AGPLv3 for the Nuitka compiler itself (typically `nuitka` package logic), + nor does it apply to the Compilation Process itself (i.e., you cannot distribute a modified version of the + Nuitka compiler under proprietary terms). This Exception only applies to the *output* of the Compilation + Process (the Target Code) that links against the Runtime Library.

+ +

3. Intention

+

This exception is intended to allow the creation of closed-source Python applications that use Nuitka, but + it does prevent the creation of closed-source Nuitka itself except by the source code owner.

+
+
+ + +
+

9. 使用说明

+ +
+

许可证约束

+
    +
  • 本项目整体受 GNU General Public License v3.0 约束
  • +
  • 使用本软件即表示您同意遵守所有相关许可证条款
  • +
-
- 许可证文档结束 +
+

根据 GPLv3 要求:

+
    +
  • ✅ 您可以自由使用、修改、分发本软件
  • +
  • ✅ 您必须以 GPLv3 许可证开源您的修改版本
  • +
  • ✅ 您必须提供源代码
  • +
  • ❌ 您不能将本软件用于闭源商业项目
  • +
-
+ +

如有疑问,请联系: hxiao_studio@163.com

+
+ + + + +
- + \ No newline at end of file diff --git a/locales/EN_US.toml b/locales/EN_US.toml index 307207bd40173201ff7ac8a02299285b854837ac..8eef8107c618afb7605cd3c22bf3d2f8fbb38f3e 100644 --- a/locales/EN_US.toml +++ b/locales/EN_US.toml @@ -35,6 +35,8 @@ image_filter = "Image Files (*.png *.jpg *.jpeg *.bmp *.gif)" [gradient_generation] start_color = "Start Color" +mid_color = "Mid Color" +mid_position = "Mid Position" end_color = "End Color" base_color = "Base Color" steps = "Middle Colors" @@ -52,6 +54,10 @@ title = "Color Scheme:" random = "Random" favorite = "Save" brightness = "Brightness:" +copied = "Copied" +copied_content = "Color value {hex} copied to clipboard" +favorite_failed = "Cannot Save" +no_colors_to_favorite = "No colors available to save" [color_generation.schemes] monochromatic = "Monochromatic" @@ -63,10 +69,6 @@ double_complementary = "Double Complementary" [color_generation.favorite_success] title = "Saved" content = """Color scheme "{name}" has been added to palette management""" -copied = "Copied" -copied_content = "Color value {hex} copied to clipboard" -favorite_failed = "Cannot Save" -no_colors_to_favorite = "No colors available to save" [palette_management] title = "Palette Management" @@ -266,6 +268,7 @@ gradient_lab = "LAB Space" gradient_mode = "Gradient Mode" gradient_mode_desc = "Select the gradient extraction mode" gradient_mode_gradient = "Two-color Gradient" +gradient_mode_three_color = "Three-color Gradient" gradient_mode_shade = "Monochrome Gradient" luminance = "Luminance Extract" luminance_default_grayscale = "Default Grayscale Mode" @@ -353,6 +356,7 @@ simulated_color = "Simulated" original = "Original" simulated = "Simulated" description = "Note: {desc}" +severity = "Severity: {value}%" [dialogs.contrast] title = "Contrast Check" diff --git a/locales/FR_FR.toml b/locales/FR_FR.toml index e81b04f1826d5277f279ba14b8accd03dcd32c9a..cd384c36a708efae6b39d577ce06716418fc0616 100644 --- a/locales/FR_FR.toml +++ b/locales/FR_FR.toml @@ -35,6 +35,8 @@ image_filter = "Fichiers image (*.png *.jpg *.jpeg *.bmp *.gif)" [gradient_generation] start_color = "Couleur de départ" +mid_color = "Couleur médiane" +mid_position = "Position médiane" end_color = "Couleur de fin" base_color = "Couleur de base" steps = "Couleurs intermédiaires" @@ -52,6 +54,10 @@ title = "Schéma de couleurs:" random = "Hasard" favorite = "Sauver" brightness = "Luminosité:" +copied = "Copié" +copied_content = "Valeur de couleur {hex} copiée dans le presse-papiers" +favorite_failed = "Impossible de sauver" +no_colors_to_favorite = "Aucune couleur à sauver" [color_generation.schemes] monochromatic = "Monochromatique" @@ -63,10 +69,6 @@ double_complementary = "Double" [color_generation.favorite_success] title = "Enregistré" content = """Le schéma de couleurs "{name}" a été ajouté à la gestion des palettes""" -copied = "Copié" -copied_content = "Valeur de couleur {hex} copiée dans le presse-papiers" -favorite_failed = "Impossible de sauver" -no_colors_to_favorite = "Aucune couleur à sauver" [palette_management] title = "Gestion des palettes" @@ -266,6 +268,7 @@ gradient_lab = "Espace LAB" gradient_mode = "Mode de dégradé" gradient_mode_desc = "Sélectionner le mode d'extraction du dégradé" gradient_mode_gradient = "Dégradé bicolore" +gradient_mode_three_color = "Dégradé tricolore" gradient_mode_shade = "Dégradé monochrome" luminance = "Extraction de Luminance" luminance_default_grayscale = "Mode Niveaux de Gris par Défaut" @@ -353,6 +356,7 @@ simulated_color = "Couleur simulée" original = "Original" simulated = "Simulé" description = "Note: {desc}" +severity = "Sévérité: {value}%" [dialogs.contrast] title = "Vérification du contraste" diff --git a/locales/HY_FT.toml b/locales/HY_FT.toml index 7ac75bc0e38238645080e61363cdbbaea724775b..6b3b21c50412b18b704144d063c053ce6e62bc8a 100644 --- a/locales/HY_FT.toml +++ b/locales/HY_FT.toml @@ -35,6 +35,8 @@ image_filter = "圖片文件 (*.png *.jpg *.jpeg *.bmp *.gif)" [gradient_generation] start_color = "起始顏色" +mid_color = "中間色" +mid_position = "中間色位置" end_color = "結束顏色" base_color = "基準顏色" steps = "中間色數量" @@ -52,6 +54,10 @@ title = "配色生成:" random = "隨機" favorite = "收藏" brightness = "明度調整:" +copied = "已複製" +copied_content = "顏色值 {hex} 已複製到剪貼簿" +favorite_failed = "無法收藏" +no_colors_to_favorite = "沒有可收藏的顏色" [color_generation.schemes] monochromatic = "同色系" @@ -63,10 +69,6 @@ double_complementary = "雙補色" [color_generation.favorite_success] title = "已收藏" content = "配色「{name}」已添加到配色管理" -copied = "已複製" -copied_content = "顏色值 {hex} 已複製到剪貼簿" -favorite_failed = "無法收藏" -no_colors_to_favorite = "沒有可收藏的顏色" [palette_management] title = "配色管理" @@ -266,6 +268,7 @@ gradient_lab = "LAB 空間" gradient_mode = "漸變模式" gradient_mode_desc = "選擇漸變生成的模式" gradient_mode_gradient = "雙色漸變" +gradient_mode_three_color = "三色漸變" gradient_mode_shade = "單色漸變" luminance = "明度分析" luminance_default_grayscale = "預設黑白模式" @@ -353,6 +356,7 @@ simulated_color = "模擬顏色" original = "原始" simulated = "模擬" description = "說明: {desc}" +severity = "嚴重程度:{value}%" [dialogs.contrast] title = "對比度檢查" diff --git a/locales/HY_JT.toml b/locales/HY_JT.toml index 59ab3ea872dd577e2873702f0c9657cee988660c..ed2bfeed53958f9d48da84ecaf1405b3ec55919f 100644 --- a/locales/HY_JT.toml +++ b/locales/HY_JT.toml @@ -35,6 +35,8 @@ image_filter = "图片文件 (*.png *.jpg *.jpeg *.bmp *.gif)" [gradient_generation] start_color = "起始颜色" +mid_color = "中间色" +mid_position = "中间色位置" end_color = "结束颜色" base_color = "基准颜色" steps = "中间色数量" @@ -52,6 +54,10 @@ title = "配色生成:" random = "随机" favorite = "收藏" brightness = "明度调整:" +copied = "已复制" +copied_content = "颜色值 {hex} 已复制到剪贴板" +favorite_failed = "无法收藏" +no_colors_to_favorite = "没有可收藏的颜色" [color_generation.schemes] monochromatic = "同色系" @@ -63,10 +69,6 @@ double_complementary = "双补色" [color_generation.favorite_success] title = "已收藏" content = "配色「{name}」已添加到配色管理" -copied = "已复制" -copied_content = "颜色值 {hex} 已复制到剪贴板" -favorite_failed = "无法收藏" -no_colors_to_favorite = "没有可收藏的颜色" [palette_management] title = "配色管理" @@ -266,6 +268,7 @@ gradient_lab = "LAB 空间" gradient_mode = "渐变模式" gradient_mode_desc = "选择渐变生成的模式" gradient_mode_gradient = "双色渐变" +gradient_mode_three_color = "三色渐变" gradient_mode_shade = "单色渐变" luminance = "明度分析" luminance_default_grayscale = "默认黑白模式" @@ -353,6 +356,7 @@ simulated_color = "模拟颜色" original = "原始" simulated = "模拟" description = "说明: {desc}" +severity = "严重程度:{value}%" [dialogs.contrast] title = "对比度检查" diff --git a/locales/JA_JP.toml b/locales/JA_JP.toml index 35c9702afd8e023ce670efb17f844f3e477264e6..ba48f637e3f5bb5a900d4751f7da07b62230585d 100644 --- a/locales/JA_JP.toml +++ b/locales/JA_JP.toml @@ -35,6 +35,8 @@ image_filter = "画像ファイル (*.png *.jpg *.jpeg *.bmp *.gif)" [gradient_generation] start_color = "開始色" +mid_color = "中間色" +mid_position = "中間色位置" end_color = "終了色" base_color = "ベース色" steps = "中間色数" @@ -52,6 +54,10 @@ title = "カラースキーム:" random = "ランダム" favorite = "保存" brightness = "輝度調整:" +copied = "コピーしました" +copied_content = "色値 {hex} をクリップボードにコピーしました" +favorite_failed = "保存できません" +no_colors_to_favorite = "保存できる色がありません" [color_generation.schemes] monochromatic = "モノクロマティック" @@ -63,10 +69,6 @@ double_complementary = "ダブルコンプリメンタリー" [color_generation.favorite_success] title = "保存しました" content = "配色「{name}」をパレット管理に追加しました" -copied = "コピーしました" -copied_content = "色値 {hex} をクリップボードにコピーしました" -favorite_failed = "保存できません" -no_colors_to_favorite = "保存できる色がありません" [palette_management] title = "パレット管理" @@ -266,6 +268,7 @@ gradient_lab = "LAB 空間" gradient_mode = "グラデーションモード" gradient_mode_desc = "グラデーション抽出のモードを選択" gradient_mode_gradient = "二色グラデーション" +gradient_mode_three_color = "三色グラデーション" gradient_mode_shade = "単色グラデーション" luminance = "明度抽出" luminance_default_grayscale = "デフォルト白黒モード" @@ -353,6 +356,7 @@ simulated_color = "シミュレートカラー" original = "元" simulated = "シミュレート" description = "注: {desc}" +severity = "重症度:{value}%" [dialogs.contrast] title = "コントラストチェック" diff --git a/locales/RU_RU.toml b/locales/RU_RU.toml index 3cfd1c10c9c0b6c3340ab8201fd5d20b8cd4f031..5755c33bc171b2a166e8f5247c5f616b3432313f 100644 --- a/locales/RU_RU.toml +++ b/locales/RU_RU.toml @@ -35,6 +35,8 @@ image_filter = "Файлы изображений (*.png *.jpg *.jpeg *.bmp *.gi [gradient_generation] start_color = "Начальный цвет" +mid_color = "Средний цвет" +mid_position = "Позиция среднего" end_color = "Конечный цвет" base_color = "Базовый цвет" steps = "Промежуточные цвета" @@ -52,6 +54,10 @@ title = "Цветовая схема:" random = "Случай" favorite = "Сохр." brightness = "Яркость:" +copied = "Скопировано" +copied_content = "Значение цвета {hex} скопировано в буфер обмена" +favorite_failed = "Невозможно сохранить" +no_colors_to_favorite = "Нет цветов для сохранения" [color_generation.schemes] monochromatic = "Монохроматическая" @@ -63,10 +69,6 @@ double_complementary = "Двойная" [color_generation.favorite_success] title = "Сохранено" content = """Цветовая схема "{name}" добавлена в управление палитрами""" -copied = "Скопировано" -copied_content = "Значение цвета {hex} скопировано в буфер обмена" -favorite_failed = "Невозможно сохранить" -no_colors_to_favorite = "Нет цветов для сохранения" [palette_management] title = "Палитры" @@ -267,6 +269,7 @@ gradient_lab = "LAB пространство" gradient_mode = "Режим градиента" gradient_mode_desc = "Выберите режим извлечения градиента" gradient_mode_gradient = "Двухцветный градиент" +gradient_mode_three_color = "Трёхцветный градиент" gradient_mode_shade = "Монохромный градиент" luminance = "Извлечение яркости" luminance_default_grayscale = "Оттенки серого по умолчанию" @@ -354,6 +357,7 @@ simulated_color = "Симулированный цвет" original = "Исходный" simulated = "Симулированный" description = "Примечание: {desc}" +severity = "Степень: {value}%" [dialogs.contrast] title = "Проверка контраста" diff --git a/tests/test_color_info_batch.py b/tests/test_color_info_batch.py new file mode 100644 index 0000000000000000000000000000000000000000..0ec14f70b81042b33bfd49d155659864c7327d59 --- /dev/null +++ b/tests/test_color_info_batch.py @@ -0,0 +1,217 @@ +"""测试 get_color_info_batch 批量处理函数 + +验证批量处理函数的正确性、性能优化和结果一致性 +""" +from __future__ import annotations + +import sys +import os + +# 添加项目根目录到 Python 路径 +project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +if project_root not in sys.path: + sys.path.insert(0, project_root) + +import pytest +import time +from core.color import get_color_info, get_color_info_batch + + +class TestGetColorInfoBatch: + """测试批量处理函数""" + + def test_batch_basic_functionality(self): + """测试批量处理基本功能""" + # 测试数据:常见颜色 + test_colors = [ + (255, 0, 0), # 红色 + (0, 255, 0), # 绿色 + (0, 0, 255), # 蓝色 + (255, 255, 0), # 黄色 + (0, 255, 255), # 青色 + (255, 0, 255), # 紫色 + (255, 255, 255), # 白色 + (0, 0, 0), # 黑色 + ] + + results = get_color_info_batch(test_colors) + + # 验证结果数量 + assert len(results) == len(test_colors), "批量处理结果数量应与输入数量一致" + + # 验证每个结果的结构 + for result in results: + assert 'rgb' in result, "结果应包含 RGB" + assert 'hsb' in result, "结果应包含 HSB" + assert 'lab' in result, "结果应包含 LAB" + assert 'hsl' in result, "结果应包含 HSL" + assert 'cmyk' in result, "结果应包含 CMYK" + assert 'hex' in result, "结果应包含 HEX" + + def test_batch_vs_single_consistency(self): + """测试批量处理与单次处理结果一致性""" + # 测试数据 + test_colors = [ + (255, 0, 0), + (128, 128, 128), + (64, 32, 16), + ] + + # 批量处理 + batch_results = get_color_info_batch(test_colors) + + # 单次处理 + for i, (r, g, b) in enumerate(test_colors): + single_result = get_color_info(r, g, b) + batch_result = batch_results[i] + + # 验证 RGB + assert single_result['rgb'] == batch_result['rgb'], \ + f"RGB 不一致: {single_result['rgb']} vs {batch_result['rgb']}" + + # 验证 HSB + assert single_result['hsb'] == batch_result['hsb'], \ + f"HSB 不一致: {single_result['hsb']} vs {batch_result['hsb']}" + + # 验证 LAB + assert single_result['lab'] == batch_result['lab'], \ + f"LAB 不一致: {single_result['lab']} vs {batch_result['lab']}" + + # 验证 HSL + assert single_result['hsl'] == batch_result['hsl'], \ + f"HSL 不一致: {single_result['hsl']} vs {batch_result['hsl']}" + + # 验证 CMYK + assert single_result['cmyk'] == batch_result['cmyk'], \ + f"CMYK 不一致: {single_result['cmyk']} vs {batch_result['cmyk']}" + + # 验证 HEX + assert single_result['hex'] == batch_result['hex'], \ + f"HEX 不一致: {single_result['hex']} vs {batch_result['hex']}" + + def test_batch_performance(self): + """测试批量处理性能提升""" + # 生成大量测试数据 + test_colors = [(i % 256, (i * 2) % 256, (i * 3) % 256) for i in range(100)] + + # 测试批量处理性能 + start_time = time.time() + batch_results = get_color_info_batch(test_colors) + batch_time = time.time() - start_time + + # 测试单次处理性能 + start_time = time.time() + single_results = [get_color_info(r, g, b) for r, g, b in test_colors] + single_time = time.time() - start_time + + # 验证结果数量一致 + assert len(batch_results) == len(single_results), "结果数量应一致" + + # 验证性能提升(批量处理应该更快) + # 注意:由于测试环境差异,这里只验证批量处理不比单次处理慢太多 + # 实际优化效果在真实环境中会更明显 + print(f"\n批量处理时间: {batch_time:.4f}s") + print(f"单次处理时间: {single_time:.4f}s") + print(f"性能提升: {(single_time - batch_time) / single_time * 100:.2f}%") + + def test_batch_empty_input(self): + """测试空输入""" + results = get_color_info_batch([]) + assert results == [], "空输入应返回空列表" + + def test_batch_single_color(self): + """测试单个颜色""" + test_colors = [(255, 128, 64)] + results = get_color_info_batch(test_colors) + + assert len(results) == 1, "单个颜色应返回一个结果" + assert results[0]['rgb'] == (255, 128, 64), "RGB 应一致" + + def test_batch_colorspace_parameter(self): + """测试色彩空间参数""" + test_colors = [(255, 0, 0)] + + # 测试不同色彩空间 + results_srgb = get_color_info_batch(test_colors, 'sRGB') + results_adobe = get_color_info_batch(test_colors, 'Adobe RGB') + + assert len(results_srgb) == 1, "sRGB 结果数量应正确" + assert len(results_adobe) == 1, "Adobe RGB 结果数量应正确" + + # 不同色彩空间的 LAB 值应该不同 + # 注意:RGB 和 HSB/HSL 应该相同,只有 LAB 不同 + assert results_srgb[0]['rgb'] == results_adobe[0]['rgb'], \ + "RGB 应相同" + assert results_srgb[0]['lab'] != results_adobe[0]['lab'], \ + "LAB 应不同(不同色彩空间)" + + def test_batch_extreme_values(self): + """测试极端值""" + test_colors = [ + (0, 0, 0), # 最小值 + (255, 255, 255), # 最大值 + (1, 1, 1), # 接近最小值 + (254, 254, 254), # 接近最大值 + ] + + results = get_color_info_batch(test_colors) + + assert len(results) == 4, "应返回 4 个结果" + + # 验证黑色 + assert results[0]['rgb'] == (0, 0, 0), "黑色 RGB 应正确" + assert results[0]['hsb'][2] == 0, "黑色亮度应为 0" + + # 验证白色 + assert results[1]['rgb'] == (255, 255, 255), "白色 RGB 应正确" + assert results[1]['hsb'][2] == 100, "白色亮度应为 100" + + +class TestPaletteImporterIntegration: + """测试 PaletteImporter 集成""" + + def test_import_logic_simulation(self): + """模拟导入逻辑""" + # 模拟 PaletteImporter 的处理逻辑 + hex_colors = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00'] + + from core.color import hex_to_rgb + + rgb_list = [] + for hex_color in hex_colors: + r, g, b = hex_to_rgb(hex_color) + rgb_list.append((r, g, b)) + + # 批量处理 + results = get_color_info_batch(rgb_list) + + # 验证结果 + assert len(results) == 4, "应返回 4 个结果" + assert results[0]['hex'] == '#FF0000', "第一个颜色应为红色" + assert results[1]['hex'] == '#00FF00', "第二个颜色应为绿色" + assert results[2]['hex'] == '#0000FF', "第三个颜色应为蓝色" + assert results[3]['hex'] == '#FFFF00', "第四个颜色应为黄色" + + +@pytest.mark.unit +def test_batch_function_exists(): + """测试批量处理函数存在""" + from core import get_color_info_batch + assert get_color_info_batch is not None, "批量处理函数应存在" + + +@pytest.mark.unit +def test_batch_function_signature(): + """测试批量处理函数签名""" + # 验证函数可以正常调用 + test_colors = [(255, 0, 0)] + results = get_color_info_batch(test_colors) + + assert isinstance(results, list), "应返回列表" + assert len(results) == 1, "应返回一个结果" + assert isinstance(results[0], dict), "结果应为字典" + + +if __name__ == '__main__': + # 运行测试 + pytest.main([__file__, '-v']) \ No newline at end of file diff --git a/ui/gradient_generation.py b/ui/gradient_generation.py index dda5ddff06dc3625bffdba3adba69e94775f0565..776845ba5e2eb91e92e6e83675d49ee87afe1fcb 100644 --- a/ui/gradient_generation.py +++ b/ui/gradient_generation.py @@ -15,7 +15,7 @@ from qfluentwidgets import ( ) # 项目模块导入 -from core import generate_gradient, generate_random_gradient, generate_lightness_shades, generate_random_lightness_shade, get_color_info +from core import generate_gradient, generate_random_gradient, generate_lightness_shades, generate_random_lightness_shade, generate_three_color_gradient, generate_random_three_color_gradient, get_color_info from core import get_config_manager from core.logger import get_logger, log_user_action from ui.cards import ColorCard @@ -82,21 +82,34 @@ class ColorDot(QWidget): class GradientPreviewWidget(QWidget): - """渐变预览控件,显示渐变色竖条""" + """渐变预览控件,显示渐变色竖条,支持拖拽中间色位置""" + + mid_position_changed = Signal(float) # 中间色位置改变信号 def __init__(self, parent=None): super().__init__(parent) self._colors: list[tuple[int, int, int]] = [] + self._mid_position: float | None = None + self._dragging = False self.setMinimumHeight(150) self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) + self.setCursor(Qt.CursorShape.ArrowCursor) + qconfig.themeChangedFinished.connect(self.update) - def set_colors(self, colors: list[tuple[int, int, int]]): + def set_colors(self, colors: list[tuple[int, int, int]], mid_position: float | None = None): """设置渐变色 Args: colors: RGB颜色列表 [(r, g, b), ...] + mid_position: 中间色位置 (0.0~1.0),三色模式下使用 """ self._colors = colors + self._mid_position = mid_position + # 三色渐变时增加30px高度 + if mid_position is not None: + self.setMinimumHeight(180) + else: + self.setMinimumHeight(150) self.update() def paintEvent(self, event): @@ -114,18 +127,109 @@ class GradientPreviewWidget(QWidget): if color_count == 0: return - # 计算每个颜色条的宽度 bar_width = width / color_count - # 绘制每个颜色条 for i, (r, g, b) in enumerate(self._colors): painter.setPen(Qt.PenStyle.NoPen) painter.setBrush(QColor(r, g, b)) x = i * bar_width - # 最后一个条可能稍微宽一点以填满空间 w = bar_width if i < color_count - 1 else width - x painter.drawRect(int(x), 0, int(w) + 1, height) + if self._mid_position is not None: + self._draw_mid_indicator(painter, width, height) + + def _get_mid_block_index(self) -> int: + """获取中间控制色在色卡序列中的索引 + + 从 mid_position 反推 block_index: mid_position = block_index / (color_count - 1) + 限制范围:第2个色块(索引1)到倒数第2个色块(索引color_count-2) + """ + color_count = len(self._colors) + block_index = round(self._mid_position * (color_count - 1)) + return max(1, min(color_count - 2, block_index)) + + def _draw_mid_indicator(self, painter: QPainter, width: int, height: int): + """绘制中间色位置指示器""" + from PySide6.QtGui import QPolygonF + from PySide6.QtCore import QPointF + + indicator_color = get_text_color() + painter.setPen(Qt.PenStyle.NoPen) + painter.setBrush(indicator_color) + + color_count = len(self._colors) + if color_count < 2: + return + + block_index = self._get_mid_block_index() + bar_width = width / color_count + x = int(bar_width * block_index + bar_width / 2) + triangle_size = 8 + + triangle = QPolygonF([ + QPointF(x, 0), + QPointF(x - triangle_size, triangle_size + 2), + QPointF(x + triangle_size, triangle_size + 2) + ]) + painter.drawPolygon(triangle) + + def _get_block_index_from_x(self, x: int) -> int: + """根据鼠标X坐标计算色块索引(限制在起始和结束颜色之间)""" + color_count = len(self._colors) + bar_width = self.width() / color_count + block_index = int(x / bar_width) + return max(1, min(color_count - 2, block_index)) + + def _get_position_from_block_index(self, block_index: int) -> float: + """根据色块索引计算中间色位置比例""" + return block_index / (len(self._colors) - 1) + + def _is_on_indicator(self, pos) -> bool: + """检查鼠标是否在指示器上""" + if self._mid_position is None: + return False + + color_count = len(self._colors) + if color_count < 2: + return False + + block_index = self._get_mid_block_index() + bar_width = self.width() / color_count + indicator_x = int(bar_width * block_index + bar_width / 2) + + return abs(pos.x() - indicator_x) <= 15 + + def mousePressEvent(self, event): + """鼠标按下事件""" + if event.button() == Qt.MouseButton.LeftButton and self._is_on_indicator(event.pos()): + self._dragging = True + self.setCursor(Qt.CursorShape.SizeHorCursor) + super().mousePressEvent(event) + + def mouseMoveEvent(self, event): + """鼠标移动事件""" + if self._dragging and self._mid_position is not None: + block_index = self._get_block_index_from_x(event.pos().x()) + new_position = self._get_position_from_block_index(block_index) + if abs(new_position - self._mid_position) > 0.001: + self._mid_position = new_position + self.mid_position_changed.emit(new_position) + self.update() + elif self._mid_position is not None: + if self._is_on_indicator(event.pos()): + self.setCursor(Qt.CursorShape.SizeHorCursor) + else: + self.setCursor(Qt.CursorShape.ArrowCursor) + super().mouseMoveEvent(event) + + def mouseReleaseEvent(self, event): + """鼠标释放事件""" + if event.button() == Qt.MouseButton.LeftButton and self._dragging: + self._dragging = False + self.setCursor(Qt.CursorShape.ArrowCursor) + super().mouseReleaseEvent(event) + class GradientCardPanel(QWidget): """渐变色卡面板""" @@ -260,8 +364,10 @@ class GradientGenerationInterface(QWidget): self._color_space = self._config_manager.get('settings.gradient_color_space', 'lab') self._gradient_mode = self._config_manager.get('settings.gradient_mode', 'gradient') self._start_color = "#FF5733" + self._mid_color = "#C8B943" + self._mid_position = 0.5 self._end_color = "#33FF57" - self._steps = 2 # 默认2个中间色,共4个颜色 + self._steps = 2 self.setup_ui() self._update_styles() @@ -269,7 +375,6 @@ class GradientGenerationInterface(QWidget): qconfig.themeChangedFinished.connect(self._update_styles) get_locale_manager().language_changed.connect(self._on_language_changed) - # 初始生成渐变 self._generate_gradient() def setup_ui(self): @@ -323,6 +428,31 @@ class GradientGenerationInterface(QWidget): start_color_layout.addStretch() control_layout.addLayout(start_color_layout) + # 中间控制色选择(三色模式) + self.mid_color_widget = QWidget() + mid_color_inner_layout = QHBoxLayout(self.mid_color_widget) + mid_color_inner_layout.setContentsMargins(0, 0, 0, 0) + mid_color_inner_layout.setSpacing(8) + self.mid_color_dot = ColorDot(self._mid_color) + self.mid_color_label = QLabel(tr('gradient_generation.mid_color')) + self.mid_color_label.setFixedWidth(56) + self.mid_color_input = QLineEdit(self._mid_color) + self.mid_color_input.setFixedWidth(105) + self.mid_color_input.setFixedHeight(28) + self.mid_color_input.setAlignment(Qt.AlignmentFlag.AlignCenter) + self.mid_color_input.setContextMenuPolicy(Qt.ContextMenuPolicy.NoContextMenu) + self.mid_color_input.setMaxLength(7) + self.mid_color_input.setPlaceholderText("#RRGGBB") + self.mid_color_input.textChanged.connect(self._on_mid_color_text_changed) + self.mid_color_input.editingFinished.connect(self._on_mid_color_editing_finished) + self.mid_color_dot.clicked.connect(self._open_mid_color_picker) + mid_color_inner_layout.addStretch() + mid_color_inner_layout.addWidget(self.mid_color_dot) + mid_color_inner_layout.addWidget(self.mid_color_label) + mid_color_inner_layout.addWidget(self.mid_color_input) + mid_color_inner_layout.addStretch() + control_layout.addWidget(self.mid_color_widget) + # 结束颜色选择 self.end_color_widget = QWidget() end_color_inner_layout = QHBoxLayout(self.end_color_widget) @@ -379,6 +509,7 @@ class GradientGenerationInterface(QWidget): preview_layout.setSpacing(0) self.gradient_preview = GradientPreviewWidget() + self.gradient_preview.mid_position_changed.connect(self._on_preview_mid_position_changed) preview_layout.addWidget(self.gradient_preview) top_layout.addWidget(preview_widget, stretch=1, alignment=Qt.AlignmentFlag.AlignBottom) @@ -420,6 +551,7 @@ class GradientGenerationInterface(QWidget): secondary_text = get_text_color(secondary=True) self.start_color_label.setStyleSheet(f"color: {text_color.name()}; font-size: 13px;") + self.mid_color_label.setStyleSheet(f"color: {text_color.name()}; font-size: 13px;") self.end_color_label.setStyleSheet(f"color: {text_color.name()}; font-size: 13px;") self.steps_label.setStyleSheet(f"color: {text_color.name()}; font-size: 13px;") self.steps_value_label.setStyleSheet(f"color: {secondary_text.name()}; font-size: 13px;") @@ -446,6 +578,7 @@ class GradientGenerationInterface(QWidget): }} """ self.start_color_input.setStyleSheet(input_style) + self.mid_color_input.setStyleSheet(input_style) self.end_color_input.setStyleSheet(input_style) def _on_language_changed(self, language_code): @@ -456,165 +589,139 @@ class GradientGenerationInterface(QWidget): else: self.start_color_label.setText(tr('gradient_generation.start_color')) self.steps_label.setText(tr('gradient_generation.steps')) + self.mid_color_label.setText(tr('gradient_generation.mid_color')) self.end_color_label.setText(tr('gradient_generation.end_color')) self.random_button.setText(tr('gradient_generation.random')) self.favorite_button.setText(tr('gradient_generation.favorite')) - def _on_start_color_text_changed(self, text: str): - """起始颜色文本变化处理(自动格式化为大写并确保#前缀)""" + def _format_hex_input(self, text: str, input_widget: QLineEdit): + """格式化HEX颜色输入(自动转大写、确保#前缀、限制长度)""" if not text: return - # 自动转大写 upper_text = text.upper() - - # 只允许有效的十六进制字符和# valid_chars = '#0123456789ABCDEF' filtered_text = ''.join(c for c in upper_text if c in valid_chars) - # 确保以#开头 if not filtered_text.startswith('#'): filtered_text = '#' + filtered_text - # 限制长度(# + 6位十六进制) if len(filtered_text) > 7: filtered_text = filtered_text[:7] - # 更新文本(如果发生变化) if text != filtered_text: - cursor_pos = self.start_color_input.cursorPosition() - self.start_color_input.setText(filtered_text) - # 保持光标位置 + cursor_pos = input_widget.cursorPosition() + input_widget.setText(filtered_text) new_pos = min(len(filtered_text), cursor_pos + (1 if not text.startswith('#') else 0)) - self.start_color_input.setCursorPosition(new_pos) - - def _on_start_color_editing_finished(self): - """起始颜色编辑完成处理(验证并更新颜色)""" - text = self.start_color_input.text().strip().upper() + input_widget.setCursorPosition(new_pos) - if not text: - return - - # 添加 # 前缀 - if not text.startswith('#'): - text = '#' + text - - # 验证HEX格式 - if not self._is_valid_hex(text): - # 无效则恢复原值 - self.start_color_input.setText(self._start_color) - return + def _on_start_color_text_changed(self, text: str): + """起始颜色文本变化处理""" + self._format_hex_input(text, self.start_color_input) - # 如果颜色没有变化,不进行处理 - if text == self._start_color: - return - - # 更新颜色 - self._start_color = text - self.start_color_dot.set_color(self._start_color) - log_user_action("change_start_color", {"color": self._start_color}) - self._generate_gradient() + def _on_mid_color_text_changed(self, text: str): + """中间色文本变化处理""" + self._format_hex_input(text, self.mid_color_input) def _on_end_color_text_changed(self, text: str): - """结束颜色文本变化处理(自动格式化为大写并确保#前缀)""" - if not text: - return + """结束颜色文本变化处理""" + self._format_hex_input(text, self.end_color_input) - # 自动转大写 - upper_text = text.upper() - - # 只允许有效的十六进制字符和# - valid_chars = '#0123456789ABCDEF' - filtered_text = ''.join(c for c in upper_text if c in valid_chars) - - # 确保以#开头 - if not filtered_text.startswith('#'): - filtered_text = '#' + filtered_text + def _handle_color_editing_finished(self, input_widget: QLineEdit, dot_widget: ColorDot, + current_color: str, color_attr: str, action_name: str) -> str | None: + """处理颜色编辑完成 - # 限制长度(# + 6位十六进制) - if len(filtered_text) > 7: - filtered_text = filtered_text[:7] - - # 更新文本(如果发生变化) - if text != filtered_text: - cursor_pos = self.end_color_input.cursorPosition() - self.end_color_input.setText(filtered_text) - # 保持光标位置 - new_pos = min(len(filtered_text), cursor_pos + (1 if not text.startswith('#') else 0)) - self.end_color_input.setCursorPosition(new_pos) + Args: + input_widget: 输入框控件 + dot_widget: 颜色圆点控件 + current_color: 当前颜色值 + color_attr: 颜色属性名('_start_color', '_mid_color', '_end_color') + action_name: 日志动作名称 - def _on_end_color_editing_finished(self): - """结束颜色编辑完成处理(验证并更新颜色)""" - text = self.end_color_input.text().strip().upper() + Returns: + 新颜色值(如果有效且发生变化),否则返回None + """ + text = input_widget.text().strip().upper() if not text: - return + return None - # 添加 # 前缀 if not text.startswith('#'): text = '#' + text - # 验证HEX格式 if not self._is_valid_hex(text): - # 无效则恢复原值 - self.end_color_input.setText(self._end_color) - return + input_widget.setText(current_color) + return None - # 如果颜色没有变化,不进行处理 - if text == self._end_color: - return + if text == current_color: + return None - # 更新颜色 - self._end_color = text - self.end_color_dot.set_color(self._end_color) - log_user_action("change_end_color", {"color": self._end_color}) + setattr(self, color_attr, text) + dot_widget.set_color(text) + log_user_action(action_name, {"color": text}) self._generate_gradient() + return text - def _open_start_color_picker(self): - """打开起始颜色选择器""" - self._open_color_picker(self._start_color, self._on_start_color_selected) + def _on_start_color_editing_finished(self): + """起始颜色编辑完成处理""" + self._handle_color_editing_finished( + self.start_color_input, self.start_color_dot, + self._start_color, '_start_color', 'change_start_color' + ) - def _open_end_color_picker(self): - """打开结束颜色选择器""" - self._open_color_picker(self._end_color, self._on_end_color_selected) + def _on_mid_color_editing_finished(self): + """中间色编辑完成处理""" + self._handle_color_editing_finished( + self.mid_color_input, self.mid_color_dot, + self._mid_color, '_mid_color', 'change_mid_color' + ) - def _open_color_picker(self, current_color: str, callback): - """打开颜色选择器对话框 + def _on_end_color_editing_finished(self): + """结束颜色编辑完成处理""" + self._handle_color_editing_finished( + self.end_color_input, self.end_color_dot, + self._end_color, '_end_color', 'change_end_color' + ) - Args: - current_color: 当前HEX颜色值 - callback: 选择完成后的回调函数 - """ + def _open_color_picker_for(self, current_color: str, color_attr: str, action_name: str): + """打开颜色选择器并处理选择结果""" from dialogs import ColorPickerDialog from PySide6.QtWidgets import QDialog - # 将HEX转换为RGB r, g, b = self._hex_to_rgb(current_color) - - # 使用顶层窗口作为父窗口,避免背景色异常和两套窗口控制器 dialog = ColorPickerDialog((r, g, b), self.window()) + if dialog.exec() == QDialog.DialogCode.Accepted: color_info = dialog.get_color_info() if color_info: - callback(color_info) - - def _on_start_color_selected(self, color_info: dict): - """起始颜色选择完成回调""" - hex_color = color_info.get('hex', '') - self._start_color = hex_color - self.start_color_dot.set_color(hex_color) - self.start_color_input.setText(hex_color) - self._generate_gradient() - log_user_action("change_start_color", {"color": hex_color, "source": "color_picker"}) - - def _on_end_color_selected(self, color_info: dict): - """结束颜色选择完成回调""" - hex_color = color_info.get('hex', '') - self._end_color = hex_color - self.end_color_dot.set_color(hex_color) - self.end_color_input.setText(hex_color) - self._generate_gradient() - log_user_action("change_end_color", {"color": hex_color, "source": "color_picker"}) + hex_color = color_info.get('hex', '') + setattr(self, color_attr, hex_color) + + # 更新对应的UI控件 + if color_attr == '_start_color': + self.start_color_dot.set_color(hex_color) + self.start_color_input.setText(hex_color) + elif color_attr == '_mid_color': + self.mid_color_dot.set_color(hex_color) + self.mid_color_input.setText(hex_color) + elif color_attr == '_end_color': + self.end_color_dot.set_color(hex_color) + self.end_color_input.setText(hex_color) + + self._generate_gradient() + log_user_action(action_name, {"color": hex_color, "source": "color_picker"}) + + def _open_start_color_picker(self): + """打开起始颜色选择器""" + self._open_color_picker_for(self._start_color, '_start_color', 'change_start_color') + + def _open_mid_color_picker(self): + """打开中间色选择器""" + self._open_color_picker_for(self._mid_color, '_mid_color', 'change_mid_color') + + def _open_end_color_picker(self): + """打开结束颜色选择器""" + self._open_color_picker_for(self._end_color, '_end_color', 'change_end_color') def _hex_to_rgb(self, hex_color: str) -> tuple: """HEX颜色转换为RGB @@ -644,11 +751,30 @@ class GradientGenerationInterface(QWidget): log_user_action("change_steps", {"steps": value}) self._generate_gradient() + def _on_preview_mid_position_changed(self, position: float): + """渐变预览条拖拽中间色位置改变""" + self._mid_position = position + log_user_action("change_mid_position", {"position": round(position * 100)}) + self._generate_gradient() + def _generate_gradient(self): """生成渐变色""" try: if self._gradient_mode == 'shade': colors = generate_lightness_shades(self._start_color, self._steps, self._color_space) + self._current_colors = colors + self.gradient_preview.set_colors(colors) + elif self._gradient_mode == 'three_color': + colors = generate_three_color_gradient( + self._start_color, + self._mid_color, + self._end_color, + self._mid_position, + self._steps, + self._color_space + ) + self._current_colors = colors + self.gradient_preview.set_colors(colors, mid_position=self._mid_position) else: colors = generate_gradient( self._start_color, @@ -656,8 +782,8 @@ class GradientGenerationInterface(QWidget): self._steps, self._color_space ) - self._current_colors = colors - self.gradient_preview.set_colors(colors) + self._current_colors = colors + self.gradient_preview.set_colors(colors) self.card_panel.set_colors(colors) logger.debug(f"生成渐变成功: mode={self._gradient_mode}, start={self._start_color}, steps={self._steps}") except (ValueError, TypeError) as e: @@ -670,7 +796,29 @@ class GradientGenerationInterface(QWidget): self._start_color = base_hex self.start_color_dot.set_color(base_hex) self.start_color_input.setText(base_hex) + self._current_colors = colors + self.gradient_preview.set_colors(colors) log_user_action("random_lightness_shade", {"base": base_hex, "count": self._steps}) + elif self._gradient_mode == 'three_color': + start_hex, mid_hex, end_hex, mid_position, colors = generate_random_three_color_gradient( + self._steps, self._color_space + ) + self._start_color = start_hex + self._mid_color = mid_hex + self._end_color = end_hex + self._mid_position = mid_position + self.start_color_dot.set_color(start_hex) + self.mid_color_dot.set_color(mid_hex) + self.end_color_dot.set_color(end_hex) + self.start_color_input.setText(start_hex) + self.mid_color_input.setText(mid_hex) + self.end_color_input.setText(end_hex) + self._current_colors = colors + self.gradient_preview.set_colors(colors, mid_position=mid_position) + log_user_action("random_three_color_gradient", { + "start": start_hex, "mid": mid_hex, "end": end_hex, + "position": mid_position, "steps": self._steps + }) else: start_hex, end_hex, colors = generate_random_gradient(self._steps, self._color_space) self._start_color = start_hex @@ -679,10 +827,10 @@ class GradientGenerationInterface(QWidget): self.end_color_dot.set_color(end_hex) self.start_color_input.setText(start_hex) self.end_color_input.setText(end_hex) + self._current_colors = colors + self.gradient_preview.set_colors(colors) log_user_action("random_gradient", {"start": start_hex, "end": end_hex, "steps": self._steps}) - self._current_colors = colors - self.gradient_preview.set_colors(colors) self.card_panel.set_colors(colors) def _on_favorite_clicked(self): @@ -758,7 +906,7 @@ class GradientGenerationInterface(QWidget): """设置渐变模式 Args: - mode: 'gradient' 或 'shade' + mode: 'gradient', 'three_color' 或 'shade' """ self._gradient_mode = mode self._apply_gradient_mode_ui() @@ -768,23 +916,30 @@ class GradientGenerationInterface(QWidget): def _apply_gradient_mode_ui(self): """根据当前渐变模式更新UI""" is_shade = self._gradient_mode == 'shade' + is_three_color = self._gradient_mode == 'three_color' self.end_color_widget.setVisible(not is_shade) + self.mid_color_widget.setVisible(is_three_color) if is_shade: self.start_color_label.setText(tr('gradient_generation.base_color')) self.steps_label.setText(tr('gradient_generation.shade_count')) self.steps_slider.setMinimum(3) self.steps_slider.setMaximum(12) - if self._steps < 3: - self.steps_slider.setValue(3) + default_steps = 5 else: self.start_color_label.setText(tr('gradient_generation.start_color')) self.steps_label.setText(tr('gradient_generation.steps')) self.steps_slider.setMinimum(1) self.steps_slider.setMaximum(10) - if self._steps > 10: - self.steps_slider.setValue(10) + default_steps = 2 + + # 断开槽函数,避免触发冗余日志和重复生成 + self.steps_slider.valueChanged.disconnect(self._on_steps_changed) + self.steps_slider.setValue(default_steps) + self.steps_slider.valueChanged.connect(self._on_steps_changed) + self._steps = default_steps + self.steps_value_label.setText(str(default_steps)) def set_hex_visible(self, visible: bool): """设置16进制显示""" diff --git a/ui/settings.py b/ui/settings.py index 151c6ebd45edb118b576cfb44e8598d9d7efe17f..ba492b5d92c6d05949ec0d19199e7035473e6354 100644 --- a/ui/settings.py +++ b/ui/settings.py @@ -432,7 +432,8 @@ class SettingsInterface(QWidget): self.gradient_mode_card.titleLabel.setText(tr('settings.gradient_mode')) self.gradient_mode_card.contentLabel.setText(tr('settings.gradient_mode_desc')) self.gradient_mode_card.combo_box.setItemText(0, tr('settings.gradient_mode_gradient')) - self.gradient_mode_card.combo_box.setItemText(1, tr('settings.gradient_mode_shade')) + self.gradient_mode_card.combo_box.setItemText(1, tr('settings.gradient_mode_three_color')) + self.gradient_mode_card.combo_box.setItemText(2, tr('settings.gradient_mode_shade')) self.gradient_color_space_card.titleLabel.setText(tr('settings.gradient_color_space')) self.gradient_color_space_card.contentLabel.setText(tr('settings.gradient_color_space_desc')) # 重建颜色空间下拉框(单色模式下无RGB选项) @@ -862,8 +863,10 @@ class SettingsInterface(QWidget): combo_box = ComboBox(self.content_widget) combo_box.addItem(tr('settings.gradient_mode_gradient')) combo_box.setItemData(0, "gradient") + combo_box.addItem(tr('settings.gradient_mode_three_color')) + combo_box.setItemData(1, "three_color") combo_box.addItem(tr('settings.gradient_mode_shade')) - combo_box.setItemData(1, "shade") + combo_box.setItemData(2, "shade") for i in range(combo_box.count()): if combo_box.itemData(i) == self._gradient_mode: diff --git a/version.py b/version.py index ecf92ec091317476ee9f1c1d25b7ed00b63ecf55..0c642aef1f589f860eba0e17d84c20f356b9fb0e 100644 --- a/version.py +++ b/version.py @@ -9,9 +9,9 @@ class VersionManager: """初始化版本管理器""" # 版本号组件 self.major: int = 1 - self.minor: int = 10 - self.patch: int = 2 - self.build: int = 2 + self.minor: int = 11 + self.patch: int = 0 + self.build: int = 1 self.prerelease: str = "" # 核心版本信息 diff --git a/version.txt b/version.txt index 1fd142495aeb5aad0edf1486db31339194774e9e..d320a08a40d829a3612010f999b87df6e330d4fe 100644 --- a/version.txt +++ b/version.txt @@ -1,6 +1,6 @@ -1.10.2 -2026.5.31.1 -1.10.2.2 +1.11.0 +2026.6.7.1 +1.10.11.1 浮晓 HXiao Studio © 2026 浮晓 HXiao Studio 取色卡(Color Card) - 一站式色彩工具 \ No newline at end of file diff --git a/version_info.txt b/version_info.txt index 5cdd70a8d4806df8d00a15f08fc9172aec5ce502..1be11a98766b5c86c1c664f14096dd8167f9e347 100644 --- a/version_info.txt +++ b/version_info.txt @@ -1,7 +1,7 @@ VSVersionInfo( ffi=FixedFileInfo( - filevers=(2026,5,31,1), - prodvers=(1,10,2,2), + filevers=(2026,6,7,1), + prodvers=(1,11,0,1), mask=0x3f, flags=0x0, OS=0x4, @@ -17,12 +17,12 @@ VSVersionInfo( [ StringStruct(u'CompanyName', u'浮晓 HXiao Studio'), StringStruct(u'FileDescription', u'取色卡(Color Card) - 一站式色彩工具'), - StringStruct(u'FileVersion', u'1.10.2'), + StringStruct(u'FileVersion', u'1.11.0'), StringStruct(u'InternalName', u'Color_Card'), StringStruct(u'LegalCopyright', u'© 2026 浮晓 HXiao Studio'), StringStruct(u'OriginalFilename', u'Color_Card.exe'), StringStruct(u'ProductName', u'取色卡'), - StringStruct(u'ProductVersion', u'1.10.2'), + StringStruct(u'ProductVersion', u'1.11.0'), StringStruct(u'Comments', u'一站式的图片的图片分析和配色工具') ] ) diff --git a/website/public/changelog.json b/website/public/changelog.json index 6d5e9ecae05dbdb3f02b8e995425a48109c6d380..9631c16077501c240d7a0a01a89733630661c3a6 100644 --- a/website/public/changelog.json +++ b/website/public/changelog.json @@ -1,5 +1,54 @@ { "versions": [ + { + "version": "v1.11.0", + "date": "2026-06-07", + "changes": [ + { + "category": "新增功能", + "items": [ + { + "title": "渐变生成", + "desc": "新增三色渐变模式" + }, + { + "title": "色盲模拟", + "desc": "色盲模拟算法升级为 Machado 2009 矩阵,新增异常三色视支持" + } + ] + }, + { + "category": "问题修复", + "items": [ + "修正配色生成面板翻译键层级错误", + "修复渐变模式切换后滑块位置显示异常,切换时自动重置中间色数量为默认值" + ] + }, + { + "category": "界面优化", + "items": [ + "色盲模拟对话框:扩大对话框尺寸,新增色块条预览功能,新增严重程度调节功能" + ] + }, + { + "category": "性能提升", + "items": [ + "提升颜色转换函数性能,避免重复创建函数对象", + "像素提取函数性能优化,消除 Python 对象创建开销", + "移除图片转 numpy 数组及 QImage 构造时冗余的数组拷贝", + "优化配色导入性能,添加批量处理函数", + "K-Means 聚类算法与主色调位置查找广播内存优化", + "直方图服务 numpy 导入提升至模块顶层" + ] + }, + { + "category": "代码优化", + "items": [ + "删除 color.py 和 gradient.py 中的重复函数定义" + ] + } + ] + }, { "version": "v1.10.2", "date": "2026-05-31",