manifest.py
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"python.pythonPath": "C:\\Users\\Mashiro\\AppData\\Local\\Programs\\Python\\Python38\\python.exe"
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
封面图生成工具
|
||||||
|
===
|
||||||
|
|
||||||
|
### 依赖
|
||||||
|
Python3
|
||||||
|
PIL (Pillow)
|
||||||
|
|
||||||
|
### 安装依赖
|
||||||
|
安装 Python: <https://docs.python.org/zh-cn/3.7/using/index.html>
|
||||||
|
安装 PIL:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Linix/Mac Terminal
|
||||||
|
pip install Pillow
|
||||||
|
# 如果也安装了 Python 2,需要指定 pip 版本:
|
||||||
|
pip3 install Pillow
|
||||||
|
|
||||||
|
# Windows Powershell 或者 CMD
|
||||||
|
pip install Pillow
|
||||||
|
# 如果也安装了 Python 2,需要指定 pip 版本:
|
||||||
|
pip3 install Pillow
|
||||||
|
# 如果提示权限不足([WinError 5] Access is denied),请运行:
|
||||||
|
pip install Pillow --user
|
||||||
|
```
|
||||||
|
|
||||||
|
### 运行
|
||||||
|
把图片文件放到 `gallary` 目录,Windows 可直接双击 main.py,或者和其他操作系统一样,在 Terminal、Powershell、CMD 中运行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 切换到 main.py 所在目录:
|
||||||
|
cd /path/to/manifest/
|
||||||
|
python main.py
|
||||||
|
# 如果也安装了 Python 2,需要指定 pip 版本:
|
||||||
|
python3 main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### TODO
|
||||||
|
自动删除过期文件、压缩图片、GitHub API push、release
|
After Width: | Height: | Size: 194 KiB |
After Width: | Height: | Size: 164 KiB |
After Width: | Height: | Size: 1.0 MiB |
After Width: | Height: | Size: 308 KiB |
After Width: | Height: | Size: 111 KiB |
After Width: | Height: | Size: 134 KiB |
After Width: | Height: | Size: 169 KiB |
After Width: | Height: | Size: 892 KiB |
After Width: | Height: | Size: 312 KiB |
After Width: | Height: | Size: 116 KiB |
|
@ -0,0 +1,63 @@
|
||||||
|
#coding=utf-8
|
||||||
|
'''
|
||||||
|
Created on Apr 23, 2018
|
||||||
|
Desc: Webp convertor
|
||||||
|
@author: Mashiro https://2heng.xin
|
||||||
|
'''
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
class Single(object):
|
||||||
|
def __init__(self, file, manifest):
|
||||||
|
self.file = file
|
||||||
|
self.mani = manifest
|
||||||
|
|
||||||
|
def hash(self):
|
||||||
|
hasher = hashlib.md5()
|
||||||
|
with open('gallary/' + self.file, 'rb') as afile:
|
||||||
|
buf = afile.read()
|
||||||
|
hasher.update(buf)
|
||||||
|
self.hash = hasher.hexdigest()
|
||||||
|
self.jpeg = 'jpeg/' + self.hash + '.jpeg'
|
||||||
|
self.webp = 'webp/' + self.hash + '.webp'
|
||||||
|
|
||||||
|
def optimize(self):
|
||||||
|
im = Image.open('gallary/' + self.file).convert('RGB')
|
||||||
|
im.save(self.jpeg, 'JPEG') # todo: TinyPNG API
|
||||||
|
im.save(self.webp, 'WEBP')
|
||||||
|
|
||||||
|
def manifest(self):
|
||||||
|
self.mani[self.hash] = {
|
||||||
|
'source': self.file,
|
||||||
|
'jpeg': 'jpeg/' + self.hash + '.jpeg',
|
||||||
|
'webp': 'webp/' + self.hash + '.webp'
|
||||||
|
}
|
||||||
|
|
||||||
|
def main(self):
|
||||||
|
self.hash()
|
||||||
|
# if os.path.exists(self.jpeg) and os.path.exists(self.webp):
|
||||||
|
self.optimize()
|
||||||
|
self.manifest()
|
||||||
|
return self.mani
|
||||||
|
|
||||||
|
def main():
|
||||||
|
onlyfiles = [f for f in os.listdir('gallary') if os.path.isfile(os.path.join('gallary', f))]
|
||||||
|
id = 1
|
||||||
|
Manifest = {}
|
||||||
|
|
||||||
|
for f in onlyfiles:
|
||||||
|
worker = Single(f, Manifest)
|
||||||
|
Manifest = worker.main()
|
||||||
|
print(str(id) + '/' + str(len(onlyfiles)))
|
||||||
|
id += 1
|
||||||
|
|
||||||
|
with open('manifest.json', 'w+') as json_file:
|
||||||
|
json.dump(Manifest, json_file)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
key = input('`manifest.json` saved. Press any key to quit.')
|
||||||
|
quit()
|
|
@ -0,0 +1 @@
|
||||||
|
{"070a095cf72042b8eebe78124f8225bb": {"source": "AK-01.jpg", "jpeg": "jpeg/070a095cf72042b8eebe78124f8225bb.jpeg", "webp": "webp/070a095cf72042b8eebe78124f8225bb.webp"}, "015a11a57f73ec3887bdf77f8f8a02f9": {"source": "AK-02.jpg", "jpeg": "jpeg/015a11a57f73ec3887bdf77f8f8a02f9.jpeg", "webp": "webp/015a11a57f73ec3887bdf77f8f8a02f9.webp"}, "fb7ab0a3878d821fffa8c1f06ec5e8d2": {"source": "AK-03.jpg", "jpeg": "jpeg/fb7ab0a3878d821fffa8c1f06ec5e8d2.jpeg", "webp": "webp/fb7ab0a3878d821fffa8c1f06ec5e8d2.webp"}, "fbefd92059006090601cb6dafdce544c": {"source": "AK-04.jpg", "jpeg": "jpeg/fbefd92059006090601cb6dafdce544c.jpeg", "webp": "webp/fbefd92059006090601cb6dafdce544c.webp"}, "fcff045964e4ac6fffd84a8192a0a393": {"source": "AK-05.jpg", "jpeg": "jpeg/fcff045964e4ac6fffd84a8192a0a393.jpeg", "webp": "webp/fcff045964e4ac6fffd84a8192a0a393.webp"}}
|
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 131 KiB |
After Width: | Height: | Size: 660 KiB |
After Width: | Height: | Size: 237 KiB |
After Width: | Height: | Size: 75 KiB |