diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..81b18f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +# Ignore the Yukkuri's folders +99-* +Resource + +# Ignore bat folders +proxy +git-commit + +# Ignore the Reference folders +Reference + +# Ignore the pyinstaller's folders +__pycache__ +build +dist +*.spec +dh-psd-ymm-convert.exe \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d7e08e9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + 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: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) 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 + + (d) 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. + + 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 + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + © 2021 DriCro6663. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README-en.md b/README-en.md new file mode 100644 index 0000000..f973cfb --- /dev/null +++ b/README-en.md @@ -0,0 +1,233 @@ +dh-psd-ymm-converter +===== + +# Introduction + +I'm not good at English. There may be parts that are difficult to understand. In that case, please feel free to ask me questions. + +* [Touhou deformed image](https://goo.gl/3G91VJ) by dairi & Haruka. + +I made this program because I thought it would be possible to implement mouth clicks and blinks when using dairi & Haruka's [Touhou Deformed Image](https://goo.gl/3G91VJ) in a Yukkuri's video. + +In the meantime, you can create folders for [YMM3](https://manjubox.net/ymm3/) and [YMM4](https://manjubox.net/ymm4/). + +# Overview +This program creates an image folder for YMM: Yukkuri Movie Maker from a deformed psd file of [Touhou Deformed Images](https://goo.gl/3G91VJ) by dairi & Haruka. + +
+ If you want to know the image of mouthing and blinking, click here. +
   + +--- + +| Lip-sync 00 | YMM3 | YMM4 | State | +| :--- | :----: | :----: | :---- | +| 口閉じ: Mouth closed | 00b.png | 00.0.png | Mouth closed | +| 小口開け: Small mouth open | 00a.png | 00.1.png | Intermediate | +| 大口開け: Large mouth open | 00.png | 00.png | Mouth open | + +--- + +| Lip-sync 01 | YMM3 | YMM4 | State | +| :--- | :----: | :----: | :---- | +| 口閉じ笑い: Closed-mouth laughter | 01b.png | 01.0.png | Mouth closed | +| 小口笑い: Small smile | 01a.png | 01.1.png | Intermediate | +| 大口笑い: Smile | 01.png | 01.png | Mouth open | + +--- + +| Blink | YMM3 | YMM4 | State | +| :--- | :----: | :----: | :---- | +| 閉じ目(下): Closed eyes (bottom) | 00b.png | 00.0.png | Eyes closed | +| ジト目: disgusted eyes | 00a.png | 00.1.png | Intermediate | +| 普通目: Normal eyes | 00.png | 00.png | Eyes open | + +--- + +
   + + +# Usage + +1. Put the deformed psd files in the [00-full-psd] and [00-icon-psd] folders. + +``` +# Example tree +/Chara's +|-- 00-full-psd +| |-- Seija.psd +|-- 00-icon-psd +| |-- Seija-icon.psd +|-- 00-result +|-- dist +| |-- dh-psd-ymm-convert +| | |-- 00-full-psd +| | |-- 00-icon-psd +| | |-- 00-result +| | |-- Other files and folders +| | |-- dh-psd-ymm-convert.exe <= [Quick Ver.] +|-- dh-psd-ymm-convert.bat <= [Quick Ver.] +|-- dh-psd-ymm-convert.exe <= [OneFile Ver.] +``` + +2. Please execute [dh-psd-ymm-convert.exe] or [dh-psd-ymm-convert.bat]. The differences between exe Ver. and bat Ver. are as follows. + +* exe: An executable file that includes the modules used.
+ Merit: A single executable file.
+ Demerit: Execution speed is slower than bat Ver. +* bat: Separate modules and executables for use.
+ Merit: Faster execution than exe Ver.
+ Demerit: It is associated with a large number of files. + +3. After execution, an image folder corresponding to YMM will be created in the [00-result] folder. + +``` +# Example tree -exe Ver.- +/Chara's +|-- 00-full-psd +| |-- Seija.psd +|-- 00-icon-psd +| |-- Seija-icon.psd +|-- 00-result +| |-- Seija-YMM3 +| |-- Seija-YMM4 +| |-- Seija-icon-YMM3 +| |-- Seija-icon-YMM4 +|-- dist +| |-- dh-psd-ymm-convert +| | |-- 00-full-psd +| | |-- 00-icon-psd +| | |-- 00-result +| | |-- Other files and folders +| | |-- dh-psd-ymm-convert.exe <= [Quick Ver.] +|-- dh-psd-ymm-convert.bat <= [Quick Ver.] +|-- dh-psd-ymm-convert.exe <= [OneFile Ver.] + +# Example tree -bat Ver.- +/Chara's +|-- 00-full-psd +| |-- Seija.psd +|-- 00-icon-psd +| |-- Seija-icon.psd +|-- 00-result +| |-- Seija-YMM3 +| |-- Seija-YMM4 +| |-- Seija-icon-YMM3 +| |-- Seija-icon-YMM4 +|-- dist +| |-- dh-psd-ymm-convert +| | |-- 00-full-psd +| | | |-- Seija.psd +| | |-- 00-icon-psd +| | | |-- Seija-icon.psd +| | |-- 00-result +| | | |-- Seija-YMM3 +| | | |-- Seija-YMM4 +| | | |-- Seija-icon-YMM3 +| | | |-- Seija-icon-YMM4 +| | |-- dh-psd-ymm-convert.exe <= [Quick Ver.] +|-- dh-psd-ymm-convert.bat <= [Quick Ver.] +|-- dh-psd-ymm-convert.exe <= [OneFile Ver.] +``` + +# BuildTheEnvironment +If you want to edit the source code, please refer to the following to build the environment. + +
+ Click here +
   + +## Virtual environment construction +Anaconda Ver. +``` +# create virtual env: python ver. 3.8 or higher +conda create --name exepy python=3.8 + - or - +conda create -n pyins + +# Active virtual env +conda activate [venv-name] +``` + +## Required modules + +* os : Standard library +* re : Standard library +* shutil : Standard library +* numpy : Computational Extension Library +* Pillow : Image Processing Library +* psd_tools : Photoshop: psd file processing library +* pyinstaller : py -> exe + +``` +conda install -y -c anaconda numpy pillow +conda install -y -c conda-forge pyinstaller +conda install -y -c auto psd-tools + - or - +pip install numpy pyinstaller psd-tools Pillow +``` + +If you need to set up a proxy, please refer to the following. +``` +# windows +# if you need to use proxy, please set proxy setting. +set HTTP_PROXY=http://:@: +set HTTPS_PROXY=http://:@: + +# example +set HTTP_PROXY=http://proxy.example.com:8080 +set HTTPS_PROXY=http://proxy.example.com:8080 + +# check proxy +echo %HTTP_PROXY% +echo %HTTPS_PROXY% +``` + +## py -> exe +``` +# Example +pyinstaller main.py --onefile + +""" + --name : Specify the name of the exe file + --onefile : Combine all exe files into one + --noconsole : Suppress console display when running exe + --debug all : Debug output + --clean : Delete the cache + --icon : Specify the path of the icon file + +pyinstaller main.py --name [fileName] --onefile --icon [./img/icon.ico] --noconsole +""" +``` + +
   + +# Note + +* I have not confirmed any conversions other than Seija and Shinmyoumaru. If you encounter any mishandling, I would appreciate it if you could contact us via the developer information below. +* I don't provide command / sh files for Mac / Linux. Mac / Linux users should refer to the bat file to create their own files. + +# Disclaimer +I don't guarantee any loss or damage caused by this program. + +Please be aware of this. + +The distribution of this program may be terminated without notice. + +# Updates + +* 2021/12/23:
+Completed / First commit + +# Developer Information + +* [Github DriCro6663](https://github.com/DriCro6663) +* [Twitter Dri_Cro_6663](https://twitter.com/Dri_Cro_6663) +* [YouTube -DriCro-](https://www.youtube.com/channel/UCyWgav9wdiPVjYphB7jrWCQ) +* [PieceX DriCro6663](https://www.piecex.com/users/profile/DriCro6663) +* [Dri-Cro's Memorandum](https://dri-cro-6663.jp/) +* dri.cro.6663@gmail.com + +# License + +Please check the [LICENSE](./LICENSE) file. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..1563cbd --- /dev/null +++ b/README.md @@ -0,0 +1,228 @@ +dh-psd-ymm-converter +===== + +# はじめ +* dairi&はるか 様の [東方デフォルメ画像](https://goo.gl/3G91VJ) + +dairi&はるか 様の [東方デフォルメ画像](https://goo.gl/3G91VJ) をゆっくり動画で使用する際、口と目の画像で口パク・瞬きが実装できそうだったので、本プログラムを作りました。 + +一応、 [YMM3](https://manjubox.net/ymm3/) と [YMM4](https://manjubox.net/ymm4/) に対応したフォルダを作成できます。 + +# 概要 +本プログラムは、dairi&はるか 様の [東方デフォルメ画像](https://goo.gl/3G91VJ) のデフォルメ psd ファイルから YMM: ゆっくりムービーメーカー に対応する画像フォルダを作成するプログラムです。 + +
+ 口パク・瞬きの画像を知りたい方は、こちらをクリックしてください +
   + +--- + +| 口パク | YMM3 | YMM4 | State | +| :--: | :----: | :----: | :---- | +| 口閉じ | 00b.png | 00.0.png | 口が閉じた状態 | +| 小口開け | 00a.png | 00.1.png | 中間フレーム | +| 大口開け | 00.png | 00.png | 口が開いた状態 | + +--- + +| 口パク笑い | YMM3 | YMM4 | State | +| :--: | :----: | :----: | :---- | +| 口閉じ笑い | 01b.png | 01.0.png | 口が閉じた状態 | +| 小口笑い | 01a.png | 01.1.png | 中間フレーム | +| 大口笑い | 01.png | 01.png | 口が開いた状態 | + +--- + +| 瞬き | YMM3 | YMM4 | State | +| :--: | :----: | :----: | :---- | +| 閉じ目(下) | 00b.png | 00.0.png | 目が閉じた状態 | +| ジト目 | 00a.png | 00.1.png | 中間フレーム | +| 普通目 | 00.png | 00.png | 目が開いた状態 | + +--- + +
   + +# 使い方 +1. [00-full-psd], [00-icon-psd] フォルダにデフォルメ psd ファイルを入れてください。 + +``` +# Example tree +/Chara's +|-- 00-full-psd +| |-- せいじゃ.psd +|-- 00-icon-psd +| |-- せいじゃアイコン.psd +|-- 00-result +|-- dist +| |-- dh-psd-ymm-convert +| | |-- 00-full-psd +| | |-- 00-icon-psd +| | |-- 00-result +| | |-- その他のファイル・フォルダ群 +| | |-- dh-psd-ymm-convert.exe <= [Quick Ver.] +|-- dh-psd-ymm-convert.bat <= [Quick Ver.] +|-- dh-psd-ymm-convert.exe <= [OneFile Ver.] +``` + +2. [dh-psd-ymm-convert.exe] または [dh-psd-ymm-convert.bat] を実行してください。exe Ver. と bat Ver. の違いは以下の通りです。 + +* exe Ver.: 使用モジュールを含めた実行ファイル
+ 利点:単独の実行ファイル
+ 欠点: bat Ver. よりも実行速度が遅い +* bat Ver.: 使用モジュールと実行ファイルが分かれている
+ 利点: exe Ver. よりも実行測度が速い
+ 欠点:大量のファイルと関係付けられている + +3. 実行後、[00-result] フォルダに YMM に対応した画像フォルダが作成されます。 + +``` +# Example tree -exe Ver.- +/Chara's +|-- 00-full-psd +| |-- せいじゃ.psd +|-- 00-icon-psd +| |-- せいじゃアイコン.psd +|-- 00-result +| |-- せいじゃ-YMM3 +| |-- せいじゃ-YMM4 +| |-- せいじゃアイコン-YMM3 +| |-- せいじゃアイコン-YMM4 +|-- dist +| |-- dh-psd-ymm-convert +| | |-- 00-full-psd +| | |-- 00-icon-psd +| | |-- 00-result +| | |-- その他のファイル・フォルダ群 +| | |-- dh-psd-ymm-convert.exe <= [Quick Ver.] +|-- dh-psd-ymm-convert.bat <= [Quick Ver.] +|-- dh-psd-ymm-convert.exe <= [OneFile Ver.] + +# Example tree -bat Ver.- +/Chara's +|-- 00-full-psd +| |-- せいじゃ.psd +|-- 00-icon-psd +| |-- せいじゃアイコン.psd +|-- 00-result +| |-- せいじゃ-YMM3 +| |-- せいじゃ-YMM4 +| |-- せいじゃアイコン-YMM3 +| |-- せいじゃアイコン-YMM4 +|-- dist +| |-- dh-psd-ymm-convert +| | |-- 00-full-psd +| | | |-- せいじゃ.psd +| | |-- 00-icon-psd +| | | |-- せいじゃアイコン.psd +| | |-- 00-result +| | | |-- せいじゃ-YMM3 +| | | |-- せいじゃ-YMM4 +| | | |-- せいじゃアイコン-YMM3 +| | | |-- せいじゃアイコン-YMM4 +| | |-- dh-psd-ymm-convert.exe <= [Quick Ver.] +|-- dh-psd-ymm-convert.bat <= [Quick Ver.] +|-- dh-psd-ymm-convert.exe <= [OneFile Ver.] +``` + +# 環境構築 +ソースコードを編集したい方は、下記を参考に環境を構築してください。 + +
+ こちらをクリックしてください +
   + +## 仮想環境構築 +Anaconda Ver. +``` +# create virtual env: python ver. 3.8 or higher +conda create --name exepy python=3.8 + - or - +conda create -n pyins + +# Active virtual env +conda activate [venv-name] +``` + +## 使用モジュール + +* os : 標準ライブラリ +* re : 標準ライブラリ +* shutil : 標準ライブラリ +* numpy : 計算拡張ライブラリ +* Pillow : 画像処理ライブラリ +* psd_tools : Photoshop: psd ファイル処理ライブラリ +* pyinstaller : py -> exe に使用 + +``` +conda install -y -c anaconda numpy pillow +conda install -y -c conda-forge pyinstaller +conda install -y -c auto psd-tools + - or - +pip install numpy pyinstaller psd-tools Pillow +``` + +プロキシ設定が必要な方は、下記を参考に設定してください。 +``` +# windows +# if you need to use proxy, please set proxy setting. +set HTTP_PROXY=http://:@: +set HTTPS_PROXY=http://:@: + +# example +set HTTP_PROXY=http://proxy.example.com:8080 +set HTTPS_PROXY=http://proxy.example.com:8080 + +# check proxy +echo %HTTP_PROXY% +echo %HTTPS_PROXY% +``` + +## py -> exe +``` +# Example +pyinstaller main.py --onefile + +""" + --name : exe ファイル名の指定 + --onefile : exe ファイルを1つにまとめる + --noconsole : exe 実行時にコンソールの表示を抑制 + --debug all : デバッグ出力 + --clean : キャッシュを削除 + --icon : アイコンファイルのパスを指定 + +pyinstaller main.py --name [fileName] --onefile --icon [./img/icon.ico] --noconsole +""" +``` + +
   + +# 注意 + +* 正邪・針妙丸 以外の変換を確認しておりません。誤処理が発生した場合は、下記の開発者情報より、連絡していただくと幸いです。 +* Mac / Linux 用の command / sh ファイルは用意しておりません。Mac / Linux ユーザーは bat ファイルを参考にして、それぞれのファイルを作成してください。 + +# 免責事項 +本プログラムで生じた如何なる損失・損害も保証いたしません。 + +ご了承ください。 + +また、本プログラムは予告なく配布を終了する場合があります。 + +# 更新情報 + +* 2021/12/23:
+完成・First commit + +# 開発者情報 + +* [Github DriCro6663](https://github.com/DriCro6663) +* [Twitter Dri_Cro_6663](https://twitter.com/Dri_Cro_6663) +* [YouTube ドリクロ -DriCro-](https://www.youtube.com/channel/UCyWgav9wdiPVjYphB7jrWCQ) +* [PieceX DriCro6663](https://www.piecex.com/users/profile/DriCro6663) +* [ドリクロの備忘録](https://dri-cro-6663.jp/) +* dri.cro.6663@gmail.com + +# ライセンス + +[LICENSE](./LISENCE) ファイルをご確認してください。 \ No newline at end of file diff --git a/convert.ipynb b/convert.ipynb new file mode 100644 index 0000000..974eaa4 --- /dev/null +++ b/convert.ipynb @@ -0,0 +1,441 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# /* Import library */\n", + "from psd_tools import PSDImage\n", + "from PIL import Image\n", + "import psd_tools\n", + "import numpy as np\n", + "import matplotlib\n", + "import sys\n", + "import os\n", + "import shutil\n", + "import itertools\n", + "import re" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# /* Constant */\n", + "PATH = os.getcwd()\n", + "PSD_PATH = os.path.join(PATH, \"00-full-psd\")\n", + "PSD_ICO_PATH = os.path.join(PATH, \"00-icon-psd\")\n", + "OUTPUT_PATH = os.path.join(PATH, \"00-result\")\n", + "YMM3 = \"-YMM3\"\n", + "YMM4 = \"-YMM4\"\n", + "\n", + "# Array\n", + "Y_VER_ARR = np.array(\n", + " [YMM3, YMM4], dtype=object\n", + ")\n", + "Y_FOLDER_ARR = np.array(\n", + " [\"顔\", \"後\", \"口\", \"全\", \"他\", \"体\", \"髪\", \"眉\", \"目\"], \n", + " dtype=object\n", + ")\n", + "\n", + "# Dictionary\n", + "DH_DICT = {\n", + " \"感情マーク\": \"他\",\n", + " \"汗、涙\": \"顔\",\n", + " \"表情サンプル\": \"顔\",\n", + " \"眉\": \"眉\",\n", + " \"目\": \"目\",\n", + " \"口\": \"口\",\n", + " \"顔色\": \"顔\",\n", + " \"体\": \"体\",\n", + " \"その他\": \"他\"\n", + "}\n", + "EYE_DICT_Y3 = {\n", + " \"閉じ目(下)\": \"00b\",\n", + " \"ジト目\": \"00a\",\n", + " \"普通目\": \"00\"\n", + "}\n", + "EYE_DICT_Y4 = {\n", + " \"閉じ目(下)\": \"00.0\",\n", + " \"ジト目\": \"00.1\",\n", + " \"普通目\": \"00\"\n", + "}\n", + "MOUTH_DICT_00_Y3 = {\n", + " \"口閉じ\": \"00b\",\n", + " \"小口開け\": \"00a\",\n", + " \"大口開け\": \"00\",\n", + "}\n", + "MOUTH_DICT_00_Y4 = {\n", + " \"口閉じ\": \"00.0\",\n", + " \"小口開け\": \"00.1\",\n", + " \"大口開け\": \"00\",\n", + "}\n", + "MOUTH_DICT_01_Y3 = {\n", + " \"口閉じ笑い\": \"01b\",\n", + " \"小口笑い\": \"01a\",\n", + " \"大口笑い\": \"01\",\n", + "}\n", + "MOUTH_DICT_01_Y4 = {\n", + " \"口閉じ笑い\": \"01.0\",\n", + " \"小口笑い\": \"01.1\",\n", + " \"大口笑い\": \"01\",\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# /* Def */\n", + "def change_dir(psd_name, parts_name):\n", + " p = os.path.join(OUTPUT_PATH, psd_name)\n", + " p = os.path.join(p, parts_name)\n", + " os.chdir(p)\n", + "\n", + "def save_psd_img(psd, layer, ver = 0):\n", + " if layer.is_group() and ( (\"目\" in layer.name) or (\"口\" in layer.name) ):\n", + " for l in layer:\n", + " save_psd_layer_img(psd=psd, layer=l)\n", + " save_psd_layer_em_img(psd=psd, layer=l, ver=ver)\n", + " elif layer.is_group():\n", + " for l in layer:\n", + " save_psd_layer_img(psd=psd, layer=l)\n", + " elif not layer.is_group():\n", + " save_psd_layer_img(psd=psd, layer=layer)\n", + "\n", + "def save_psd_layer_img(psd, layer):\n", + " file_name = layer.name\n", + " file_name = re.sub(r'[\\\\/:*?\"<>|]+', '', file_name) # ファイル名に使えないものは置換\n", + " img = Image.new('RGBA', psd.size)\n", + " img.paste(layer.topil(), (layer.left, layer.top))\n", + " img = img.crop(psd.bbox)\n", + " img.save(\"./\"+file_name+\".png\", quality=95)\n", + "\n", + "def save_psd_layer_em_img(psd, layer, ver):\n", + " file_name = layer.name\n", + " file_name = re.sub(r'[\\\\/:*?\"<>|]+', '', file_name) # ファイル名に使えないものは置換\n", + " img = Image.new('RGBA', psd.size)\n", + " img.paste(layer.topil(), (layer.left, layer.top))\n", + " img = img.crop(psd.bbox)\n", + " layer_name = re.sub('!|\\*', '', layer.name)\n", + " if ver == YMM3:\n", + " # eye\n", + " if layer_name in EYE_DICT_Y3:\n", + " img.save(\"./\"+EYE_DICT_Y3[layer_name]+\".png\", quality=95)\n", + " elif layer_name in MOUTH_DICT_00_Y3:\n", + " img.save(\"./\"+MOUTH_DICT_00_Y3[layer_name]+\".png\", quality=95)\n", + " elif layer_name in MOUTH_DICT_01_Y3:\n", + " img.save(\"./\"+MOUTH_DICT_01_Y3[layer_name]+\".png\", quality=95)\n", + " elif ver == YMM4:\n", + " # mouth\n", + " if layer_name in EYE_DICT_Y4:\n", + " img.save(\"./\"+EYE_DICT_Y4[layer_name]+\".png\", quality=95)\n", + " elif layer_name in MOUTH_DICT_00_Y4:\n", + " img.save(\"./\"+MOUTH_DICT_00_Y4[layer_name]+\".png\", quality=95)\n", + " elif layer_name in MOUTH_DICT_01_Y4:\n", + " img.save(\"./\"+MOUTH_DICT_01_Y4[layer_name]+\".png\", quality=95)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# /* Class */\n", + "class Converter:\n", + " def __init__(self) -> None:\n", + " self.output_path_arr = np.array([], dtype=object)\n", + " \n", + " def load_psd(self):\n", + " # Get a list of file names only\n", + " path = PSD_PATH\n", + " files = os.listdir(path)\n", + " files_file = [os.path.join(path, f) for f in files if os.path.isfile(os.path.join(path, f))]\n", + " psd_path = np.array(files_file, dtype=object)\n", + " path = PSD_ICO_PATH\n", + " files = os.listdir(path)\n", + " files_file = [os.path.join(path, f) for f in files if os.path.isfile(os.path.join(path, f))]\n", + " files_file = np.array(files_file, dtype=object)\n", + " self.psd_paths = np.append(psd_path, files_file)\n", + " # load psd\n", + " psd_list = [PSDImage.open(p) for p in self.psd_paths]\n", + " #self.psd_arr = np.array(psd_list, dtype=object)\n", + " self.psd_arr = psd_list\n", + " return self.psd_arr\n", + " \n", + " def convert(self):\n", + " self.load_psd()\n", + " self.create_folder()\n", + " print(\"ゆっくり素材用のフォルダを作成します。\")\n", + " self.psd2png()\n", + " print(\"完了!\")\n", + " \n", + " def psd2png(self):\n", + " for psd, name in zip(self.psd_arr, self.psd_names):\n", + " for layer, ver in itertools.product(psd, Y_VER_ARR):\n", + " folder_name = name+ver\n", + " # 体\n", + " if ( not layer.is_group() ) and ( layer.name.find(\"体\") != -1 ):\n", + " print(\"creating [{}]...\".format(folder_name))\n", + " change_dir(psd_name=folder_name, parts_name=\"体\")\n", + " save_psd_img(psd=psd, layer=layer)\n", + " #layer.topil().save('./00.png')\n", + " # 感情マーク\n", + " elif ( layer.is_group() ) and ( layer.name.find(\"感情マーク\") != -1 ):\n", + " change_dir(psd_name=folder_name, parts_name=DH_DICT[\"感情マーク\"])\n", + " save_psd_img(psd=psd, layer=layer)\n", + " # 汗、涙\n", + " elif ( layer.is_group() ) and ( layer.name.find(\"汗、涙\") != -1 ):\n", + " change_dir(psd_name=folder_name, parts_name=DH_DICT[\"汗、涙\"])\n", + " save_psd_img(psd=psd, layer=layer)\n", + " \n", + " # 顔色\n", + " elif ( layer.is_group() ) and ( layer.name.find(\"顔色\") != -1 ):\n", + " change_dir(psd_name=folder_name, parts_name=DH_DICT[\"顔色\"])\n", + " save_psd_img(psd=psd, layer=layer)\n", + " # その他\n", + " elif ( not layer.is_group() ):\n", + " change_dir(psd_name=folder_name, parts_name=DH_DICT[\"その他\"])\n", + " save_psd_img(psd=psd, layer=layer)\n", + " # 表情\n", + " elif ( layer.is_group() ) and ( layer.name.find(\"表情\") != -1 ):\n", + " for group in layer:\n", + " # 表情サンプル\n", + " if ( group.is_group() ) and ( group.name.find(\"表情サンプル\") != -1 ):\n", + " change_dir(psd_name=folder_name, parts_name=DH_DICT[\"表情サンプル\"])\n", + " save_psd_img(psd=psd, layer=group)\n", + " else:\n", + " for g in group:\n", + " # 眉\n", + " if ( g.is_group() ) and ( g.name.find(\"眉\") != -1 ):\n", + " change_dir(psd_name=folder_name, parts_name=DH_DICT[\"眉\"])\n", + " save_psd_img(psd=psd, layer=g, ver=ver)\n", + " # 目\n", + " elif ( g.is_group() ) and ( g.name.find(\"目\") != -1 ):\n", + " change_dir(psd_name=folder_name, parts_name=DH_DICT[\"目\"])\n", + " save_psd_img(psd=psd, layer=g, ver=ver)\n", + " # 口\n", + " elif ( g.is_group() ) and ( g.name.find(\"口\") != -1 ):\n", + " change_dir(psd_name=folder_name, parts_name=DH_DICT[\"口\"])\n", + " save_psd_img(psd=psd, layer=g, ver=ver)\n", + " \n", + " def create_folder(self):\n", + " psd_names = [os.path.splitext(os.path.basename(p))[0] for p in self.psd_paths]\n", + " psd_names = np.array(psd_names, dtype=object)\n", + " self.psd_names = psd_names\n", + " for folder_name, y_ver, sub_name in itertools.product(psd_names, Y_VER_ARR, Y_FOLDER_ARR):\n", + " output_path = os.path.join(OUTPUT_PATH, folder_name)\n", + " output_path = output_path + y_ver\n", + " output_path = os.path.join(output_path, sub_name)\n", + " if os.path.isdir(output_path):\n", + " shutil.rmtree(output_path) # ディレクトリを中身ごと削除\n", + " os.makedirs(output_path, exist_ok=True)\n", + " self.output_path_arr = np.append(self.output_path_arr, output_path)\n", + " return self.output_path_arr" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "しんみょうまる-YMM3\n", + "しんみょうまる-YMM4\n", + "しんみょうまる-YMM3\n", + "しんみょうまる-YMM4\n", + "しんみょうまる-YMM3\n", + "しんみょうまる-YMM4\n", + "しんみょうまる-YMM3\n", + "しんみょうまる-YMM4\n", + "しんみょうまる-YMM3\n", + "しんみょうまる-YMM4\n", + "しんみょうまる-YMM3\n", + "しんみょうまる-YMM4\n" + ] + } + ], + "source": [ + "converter = Converter()\n", + "psd_arr = converter.load_psd()\n", + "output_path_arr = converter.create_folder()\n", + "converter.psd2png()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for psd in psd_arr:\n", + " for layer in psd:\n", + " print(layer)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "psd = PSDImage.open(r\"D:\\GitHub-Home\\00-JupyterHome\\2021\\dh-psd-ymm-converter\\00-full-psd\\しんみょうまる.psd\")\n", + "psd\n", + "img = Image.new('RGBA', psd[0].size)\n", + "layers = [psd[0], psd[3]]\n", + "image = psd_tools.compose(\n", + " layers,\n", + " #bbox=psd[0].bbox,\n", + " #layer_filter=lambda x: x.name == \"お椀\"\n", + ")\n", + "image" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "psd.bbox" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "psd.viewbox" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "psd_arr[0][0].composite().save(\"./fafa.png\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if \"!体\".find(\"体\") == -1:\n", + " print(\"fff\")\n", + "else:\n", + " print(\"faffa\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for layer in list(psd_arr[0][1].descendants()):\n", + " print(layer)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "list(itertools.product(\"01\", \"AB\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'aaa@xxx.com bbb@yyy.com ccc@zzz.com'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s = 'aaa@xxx.com !bbb@yyy.com ccc@zzz.com'\n", + "re.sub('!|\\*', '', s)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fafa\n" + ] + } + ], + "source": [ + "a = \"fafa\"\n", + "print(\"{}\".format(a))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "interpreter": { + "hash": "f2ce98a56186678ca4724a575a08b41b14b1738a768c686c9527ac3cbc156c60" + }, + "kernelspec": { + "display_name": "Python 3.9.7 64-bit ('pyexe-pip': conda)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/dh-psd-ymm-convert.bat b/dh-psd-ymm-convert.bat new file mode 100644 index 0000000..7dccd77 --- /dev/null +++ b/dh-psd-ymm-convert.bat @@ -0,0 +1,19 @@ +@rem 文字コード Shift-JIS -> UTF-8 変更 +chcp 65001 + +@rem 参照するファイルを更新 +copy "./00-full-psd" "./dist/dh-psd-ymm-convert/00-full-psd" +copy "./00-icon-psd" "./dist/dh-psd-ymm-convert/00-icon-psd" + +@rem Touhou-LW-Farm-Quest-RPA.exe 起動 +cd ./dist/dh-psd-ymm-convert +dh-psd-ymm-convert.exe + +@rem 参照するファイルを更新 +@rem copy "./00-result" "../../00-result" +cd ../.. +xcopy /e "./dist/dh-psd-ymm-convert/00-result" "./00-result" + +echo 終了するには何かキーを押してください... +pause > nul +exit \ No newline at end of file diff --git a/dh-psd-ymm-convert.py b/dh-psd-ymm-convert.py new file mode 100644 index 0000000..bccb218 --- /dev/null +++ b/dh-psd-ymm-convert.py @@ -0,0 +1,220 @@ +# /* Import library */ +from psd_tools import PSDImage +from PIL import Image +import psd_tools +import numpy as np +import os +import shutil +import itertools +import re + +# /*===================================================================================================*/ + +# /* Constant */ +PATH = os.getcwd() +PSD_PATH = os.path.join(PATH, "00-full-psd") +PSD_ICO_PATH = os.path.join(PATH, "00-icon-psd") +OUTPUT_PATH = os.path.join(PATH, "00-result") +YMM3 = "-YMM3" +YMM4 = "-YMM4" + +# Array +Y_VER_ARR = np.array( + [YMM3, YMM4], dtype=object +) +Y_FOLDER_ARR = np.array( + ["顔", "後", "口", "全", "他", "体", "髪", "眉", "目"], + dtype=object +) + +# Dictionary +DH_DICT = { + "感情マーク": "他", + "汗、涙": "顔", + "表情サンプル": "顔", + "眉": "眉", + "目": "目", + "口": "口", + "顔色": "顔", + "体": "体", + "その他": "他" +} +EYE_DICT_Y3 = { + "閉じ目(下)": "00b", + "ジト目": "00a", + "普通目": "00" +} +EYE_DICT_Y4 = { + "閉じ目(下)": "00.0", + "ジト目": "00.1", + "普通目": "00" +} +MOUTH_DICT_00_Y3 = { + "口閉じ": "00b", + "小口開け": "00a", + "大口開け": "00", +} +MOUTH_DICT_00_Y4 = { + "口閉じ": "00.0", + "小口開け": "00.1", + "大口開け": "00", +} +MOUTH_DICT_01_Y3 = { + "口閉じ笑い": "01b", + "小口笑い": "01a", + "大口笑い": "01", +} +MOUTH_DICT_01_Y4 = { + "口閉じ笑い": "01.0", + "小口笑い": "01.1", + "大口笑い": "01", +} + +# /*===================================================================================================*/ + +# /* Def */ +def change_dir(psd_name, parts_name): + p = os.path.join(OUTPUT_PATH, psd_name) + p = os.path.join(p, parts_name) + os.chdir(p) + +def save_psd_img(psd, layer, ver = 0): + if layer.is_group() and ( ("目" in layer.name) or ("口" in layer.name) ): + for l in layer: + save_psd_layer_img(psd=psd, layer=l) + save_psd_layer_em_img(psd=psd, layer=l, ver=ver) + elif layer.is_group(): + for l in layer: + save_psd_layer_img(psd=psd, layer=l) + elif not layer.is_group(): + save_psd_layer_img(psd=psd, layer=layer) + +def save_psd_layer_img(psd, layer): + file_name = layer.name + file_name = re.sub(r'[\\/:*?"<>|]+', '', file_name) # ファイル名に使えないものは置換 + img = Image.new('RGBA', psd.size) + img.paste(layer.topil(), (layer.left, layer.top)) + img = img.crop(psd.bbox) + img.save("./"+file_name+".png", quality=95) + +def save_psd_layer_em_img(psd, layer, ver): + file_name = layer.name + file_name = re.sub(r'[\\/:*?"<>|]+', '', file_name) # ファイル名に使えないものは置換 + img = Image.new('RGBA', psd.size) + img.paste(layer.topil(), (layer.left, layer.top)) + img = img.crop(psd.bbox) + layer_name = re.sub('!|\*', '', layer.name) + if ver == YMM3: + # eye + if layer_name in EYE_DICT_Y3: + img.save("./"+EYE_DICT_Y3[layer_name]+".png", quality=95) + elif layer_name in MOUTH_DICT_00_Y3: + img.save("./"+MOUTH_DICT_00_Y3[layer_name]+".png", quality=95) + elif layer_name in MOUTH_DICT_01_Y3: + img.save("./"+MOUTH_DICT_01_Y3[layer_name]+".png", quality=95) + elif ver == YMM4: + # mouth + if layer_name in EYE_DICT_Y4: + img.save("./"+EYE_DICT_Y4[layer_name]+".png", quality=95) + elif layer_name in MOUTH_DICT_00_Y4: + img.save("./"+MOUTH_DICT_00_Y4[layer_name]+".png", quality=95) + elif layer_name in MOUTH_DICT_01_Y4: + img.save("./"+MOUTH_DICT_01_Y4[layer_name]+".png", quality=95) + +# /* Class */ +class Converter: + def __init__(self) -> None: + self.output_path_arr = np.array([], dtype=object) + + def load_psd(self): + # Get a list of file names only + path = PSD_PATH + files = os.listdir(path) + files_file = [os.path.join(path, f) for f in files if os.path.isfile(os.path.join(path, f))] + psd_path = np.array(files_file, dtype=object) + path = PSD_ICO_PATH + files = os.listdir(path) + files_file = [os.path.join(path, f) for f in files if os.path.isfile(os.path.join(path, f))] + files_file = np.array(files_file, dtype=object) + self.psd_paths = np.append(psd_path, files_file) + # load psd + psd_list = [PSDImage.open(p) for p in self.psd_paths] + #self.psd_arr = np.array(psd_list, dtype=object) + self.psd_arr = psd_list + return self.psd_arr + + def convert(self): + self.load_psd() + self.create_folder() + print("ゆっくり素材用のフォルダを作成します。") + self.psd2png() + print("完了!") + + def psd2png(self): + for psd, name in zip(self.psd_arr, self.psd_names): + for layer, ver in itertools.product(psd, Y_VER_ARR): + folder_name = name+ver + # 体 + if ( not layer.is_group() ) and ( layer.name.find("体") != -1 ): + print("creating [{}]...".format(folder_name)) + change_dir(psd_name=folder_name, parts_name="体") + save_psd_img(psd=psd, layer=layer) + #layer.topil().save('./00.png') + # 感情マーク + elif ( layer.is_group() ) and ( layer.name.find("感情マーク") != -1 ): + change_dir(psd_name=folder_name, parts_name=DH_DICT["感情マーク"]) + save_psd_img(psd=psd, layer=layer) + # 汗、涙 + elif ( layer.is_group() ) and ( layer.name.find("汗、涙") != -1 ): + change_dir(psd_name=folder_name, parts_name=DH_DICT["汗、涙"]) + save_psd_img(psd=psd, layer=layer) + + # 顔色 + elif ( layer.is_group() ) and ( layer.name.find("顔色") != -1 ): + change_dir(psd_name=folder_name, parts_name=DH_DICT["顔色"]) + save_psd_img(psd=psd, layer=layer) + # その他 + elif ( not layer.is_group() ): + change_dir(psd_name=folder_name, parts_name=DH_DICT["その他"]) + save_psd_img(psd=psd, layer=layer) + # 表情 + elif ( layer.is_group() ) and ( layer.name.find("表情") != -1 ): + for group in layer: + # 表情サンプル + if ( group.is_group() ) and ( group.name.find("表情サンプル") != -1 ): + change_dir(psd_name=folder_name, parts_name=DH_DICT["表情サンプル"]) + save_psd_img(psd=psd, layer=group) + else: + for g in group: + # 眉 + if ( g.is_group() ) and ( g.name.find("眉") != -1 ): + change_dir(psd_name=folder_name, parts_name=DH_DICT["眉"]) + save_psd_img(psd=psd, layer=g, ver=ver) + # 目 + elif ( g.is_group() ) and ( g.name.find("目") != -1 ): + change_dir(psd_name=folder_name, parts_name=DH_DICT["目"]) + save_psd_img(psd=psd, layer=g, ver=ver) + # 口 + elif ( g.is_group() ) and ( g.name.find("口") != -1 ): + change_dir(psd_name=folder_name, parts_name=DH_DICT["口"]) + save_psd_img(psd=psd, layer=g, ver=ver) + + def create_folder(self): + psd_names = [os.path.splitext(os.path.basename(p))[0] for p in self.psd_paths] + psd_names = np.array(psd_names, dtype=object) + self.psd_names = psd_names + for folder_name, y_ver, sub_name in itertools.product(psd_names, Y_VER_ARR, Y_FOLDER_ARR): + output_path = os.path.join(OUTPUT_PATH, folder_name) + output_path = output_path + y_ver + output_path = os.path.join(output_path, sub_name) + if os.path.isdir(output_path): + shutil.rmtree(output_path) # ディレクトリを中身ごと削除 + os.makedirs(output_path, exist_ok=True) + self.output_path_arr = np.append(self.output_path_arr, output_path) + return self.output_path_arr + +# /*===================================================================================================*/ + +if __name__ == '__main__': + converter = Converter() + converter.convert() \ No newline at end of file