py-img-processor 1.0.3__py3-none-any.whl → 1.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- imgprocessor/__init__.py +1 -1
- imgprocessor/enums.py +2 -2
- imgprocessor/parsers/base.py +4 -4
- imgprocessor/parsers/crop.py +2 -2
- imgprocessor/parsers/merge.py +1 -1
- imgprocessor/parsers/resize.py +14 -13
- imgprocessor/parsers/watermark.py +6 -6
- {py_img_processor-1.0.3.dist-info → py_img_processor-1.1.0.dist-info}/METADATA +2 -2
- py_img_processor-1.1.0.dist-info/RECORD +23 -0
- py_img_processor-1.0.3.dist-info/RECORD +0 -23
- {py_img_processor-1.0.3.dist-info → py_img_processor-1.1.0.dist-info}/LICENSE +0 -0
- {py_img_processor-1.0.3.dist-info → py_img_processor-1.1.0.dist-info}/WHEEL +0 -0
- {py_img_processor-1.0.3.dist-info → py_img_processor-1.1.0.dist-info}/entry_points.txt +0 -0
- {py_img_processor-1.0.3.dist-info → py_img_processor-1.1.0.dist-info}/top_level.txt +0 -0
imgprocessor/__init__.py
CHANGED
imgprocessor/enums.py
CHANGED
|
@@ -51,8 +51,8 @@ class OpAction(ChoiceEnum):
|
|
|
51
51
|
class ResizeMode(ChoiceEnum):
|
|
52
52
|
"""图像缩放的模式"""
|
|
53
53
|
|
|
54
|
-
LFIT = ("lfit", "等比缩放,缩放图限制为指定w与h的矩形内的最大图片") # 类似ImageOps.contain
|
|
55
|
-
MFIT = ("mfit", "等比缩放,缩放图为延伸出指定w与h的矩形框外的最小图片") # 类似ImageOps.cover
|
|
54
|
+
LFIT = ("lfit", "等比缩放,缩放图限制为指定w与h的矩形内的最大图片") # 类似 ImageOps.contain
|
|
55
|
+
MFIT = ("mfit", "等比缩放,缩放图为延伸出指定w与h的矩形框外的最小图片") # 类似 ImageOps.cover
|
|
56
56
|
FIT = ("fit", "将原图等比缩放为延伸出指定w与h的矩形框外的最小图片,然后将超出的部分进行居中裁剪") # ImageOps.fit
|
|
57
57
|
PAD = ("pad", "将原图缩放为指定w与h的矩形内的最大图片,然后使用指定颜色居中填充空白部分") # ImageOps.pad
|
|
58
58
|
FIXED = ("fixed", "固定宽高,强制缩放")
|
imgprocessor/parsers/base.py
CHANGED
|
@@ -208,11 +208,11 @@ def compute_by_geography(
|
|
|
208
208
|
if "x" in pf:
|
|
209
209
|
if x < 0 or x > 100:
|
|
210
210
|
raise ParamValidateException(f"pf={pf}包含了x,所以x作为百分比取值范围为[0,100]")
|
|
211
|
-
x =
|
|
211
|
+
x = round(src_w * x / 100)
|
|
212
212
|
if "y" in pf:
|
|
213
213
|
if y < 0 or y > 100:
|
|
214
214
|
raise ParamValidateException(f"pf={pf}包含了y,所以y作为百分比取值范围为[0,100]")
|
|
215
|
-
y =
|
|
215
|
+
y = round(src_h * y / 100)
|
|
216
216
|
return x, y
|
|
217
217
|
|
|
218
218
|
|
|
@@ -231,11 +231,11 @@ def compute_by_ratio(src_w: int, src_h: int, ratio: str) -> tuple[int, int]:
|
|
|
231
231
|
wr, hr = int(w_r), int(h_r)
|
|
232
232
|
if src_w * hr > src_h * wr:
|
|
233
233
|
# 相对于目标比例,宽长了
|
|
234
|
-
w =
|
|
234
|
+
w = round(src_h * wr / hr)
|
|
235
235
|
h = src_h
|
|
236
236
|
elif src_w * hr < src_h * wr:
|
|
237
237
|
w = src_w
|
|
238
|
-
h =
|
|
238
|
+
h = round(src_w * hr / wr)
|
|
239
239
|
else:
|
|
240
240
|
# 刚好符合比例
|
|
241
241
|
w, h = src_w, src_h
|
imgprocessor/parsers/crop.py
CHANGED
|
@@ -64,14 +64,14 @@ class CropParser(BaseParser):
|
|
|
64
64
|
if "w" in pf:
|
|
65
65
|
if w < 0 or w > 100:
|
|
66
66
|
raise ParamValidateException(f"pf={pf}包含了w,所以w作为百分比取值范围为[0,100]")
|
|
67
|
-
w =
|
|
67
|
+
w = round(src_w * w / 100)
|
|
68
68
|
elif not w:
|
|
69
69
|
w = src_w
|
|
70
70
|
|
|
71
71
|
if "h" in pf:
|
|
72
72
|
if h < 0 or h > 100:
|
|
73
73
|
raise ParamValidateException(f"pf={pf}包含了h,所以h作为百分比取值范围为[0,100]")
|
|
74
|
-
h =
|
|
74
|
+
h = round(src_h * h / 100)
|
|
75
75
|
elif not h:
|
|
76
76
|
h = src_h
|
|
77
77
|
|
imgprocessor/parsers/merge.py
CHANGED
|
@@ -100,7 +100,7 @@ class MergeParser(BaseParser):
|
|
|
100
100
|
params = ProcessParams.parse_str(self.action)
|
|
101
101
|
im2 = handle_img_actions(im2, params.actions)
|
|
102
102
|
if self.p:
|
|
103
|
-
w2, h2 =
|
|
103
|
+
w2, h2 = round(src_w * self.p / 100), round(src_h * self.p / 100)
|
|
104
104
|
im2 = im2.resize((w2, h2), resample=Image.LANCZOS)
|
|
105
105
|
w2, h2 = im2.size
|
|
106
106
|
|
imgprocessor/parsers/resize.py
CHANGED
|
@@ -57,45 +57,46 @@ class ResizeParser(BaseParser):
|
|
|
57
57
|
# w,h按指定的即可,无需计算
|
|
58
58
|
w, h = self.w, self.h
|
|
59
59
|
elif self.m == enums.ResizeMode.MFIT:
|
|
60
|
+
# 低版本Pillow未实现 ImageOps.cover 方法,自行处理
|
|
60
61
|
# 等比缩放
|
|
61
62
|
if self.w and self.h:
|
|
62
63
|
# 指定w与h的矩形外的最小图像
|
|
63
64
|
if self.w / self.h > src_w / src_h:
|
|
64
|
-
w, h = self.w,
|
|
65
|
+
w, h = self.w, round(self.w * src_h / src_w)
|
|
65
66
|
else:
|
|
66
|
-
w, h =
|
|
67
|
+
w, h = round(self.h * src_w / src_h), self.h
|
|
67
68
|
elif self.w:
|
|
68
|
-
w, h = self.w,
|
|
69
|
+
w, h = self.w, round(self.w * src_h / src_w)
|
|
69
70
|
else:
|
|
70
|
-
w, h =
|
|
71
|
+
w, h = round(self.h * src_w / src_h), self.h
|
|
71
72
|
else:
|
|
72
73
|
# 默认 enums.ResizeMode.LFIT
|
|
73
74
|
# 等比缩放
|
|
74
75
|
if self.w and self.h:
|
|
75
76
|
# 指定w与h的矩形内的最大图像
|
|
76
77
|
if self.w / self.h > src_w / src_h:
|
|
77
|
-
w, h =
|
|
78
|
+
w, h = round(self.h * src_w / src_h), self.h
|
|
78
79
|
else:
|
|
79
|
-
w, h = self.w,
|
|
80
|
+
w, h = self.w, round(self.w * src_h / src_w)
|
|
80
81
|
elif self.w:
|
|
81
|
-
w, h = self.w,
|
|
82
|
+
w, h = self.w, round(self.w * src_h / src_w)
|
|
82
83
|
else:
|
|
83
|
-
w, h =
|
|
84
|
+
w, h = round(self.h * src_w / src_h), self.h
|
|
84
85
|
elif self.l:
|
|
85
86
|
# 按最长边缩放
|
|
86
87
|
if src_w > src_h:
|
|
87
|
-
w, h = self.l,
|
|
88
|
+
w, h = self.l, round(src_h * self.l / src_w)
|
|
88
89
|
else:
|
|
89
|
-
w, h =
|
|
90
|
+
w, h = round(src_w * self.l / src_h), self.l
|
|
90
91
|
elif self.s:
|
|
91
92
|
# 按最短边缩放
|
|
92
93
|
if src_w > src_h:
|
|
93
|
-
w, h =
|
|
94
|
+
w, h = round(src_w * self.s / src_h), self.s
|
|
94
95
|
else:
|
|
95
|
-
w, h = self.s,
|
|
96
|
+
w, h = self.s, round(src_h * self.s / src_w)
|
|
96
97
|
elif self.p:
|
|
97
98
|
# 按照比例缩放
|
|
98
|
-
w, h =
|
|
99
|
+
w, h = round(src_w * self.p / 100), round(src_h * self.p / 100)
|
|
99
100
|
else:
|
|
100
101
|
# 缺少参数
|
|
101
102
|
raise ParamValidateException("resize操作缺少合法参数")
|
|
@@ -132,7 +132,7 @@ class WatermarkParser(BaseParser):
|
|
|
132
132
|
|
|
133
133
|
# 阴影要单独处理透明度,放在文字之前处理
|
|
134
134
|
if self.shadow:
|
|
135
|
-
offset = max(
|
|
135
|
+
offset = max(round(self.size / 20), 2)
|
|
136
136
|
shadow_color = "#000000"
|
|
137
137
|
# 左上到右下的阴影,只保留这一个
|
|
138
138
|
draw.text((x2 + offset, y2 + offset), self.text, font=font, fill=shadow_color)
|
|
@@ -140,7 +140,7 @@ class WatermarkParser(BaseParser):
|
|
|
140
140
|
# draw.text((x2 + offset, y2 - offset), self.text, font=font, fill=shadow_color)
|
|
141
141
|
# draw.text((x2 - offset, y2 - offset), self.text, font=font, fill=shadow_color)
|
|
142
142
|
_, _, _, alpha_channel = mark.split()
|
|
143
|
-
alpha_channel = alpha_channel.point(lambda i: min(
|
|
143
|
+
alpha_channel = alpha_channel.point(lambda i: min(round(255 * self.shadow / 100), i))
|
|
144
144
|
mark.putalpha(alpha_channel)
|
|
145
145
|
|
|
146
146
|
# 处理文字
|
|
@@ -168,7 +168,7 @@ class WatermarkParser(BaseParser):
|
|
|
168
168
|
# 处理缩放
|
|
169
169
|
rate = min(src_w, src_h) / self.design
|
|
170
170
|
if rate != 1:
|
|
171
|
-
w, h =
|
|
171
|
+
w, h = round(w * rate), round(h * rate)
|
|
172
172
|
mark = mark.resize((w, h), resample=Image.LANCZOS)
|
|
173
173
|
|
|
174
174
|
if 0 < self.rotate < 360:
|
|
@@ -180,17 +180,17 @@ class WatermarkParser(BaseParser):
|
|
|
180
180
|
if w > src_w or h > src_h:
|
|
181
181
|
# 水印大小超过原图了, 原图矩形内的最大图像
|
|
182
182
|
if w / h > src_w / src_h:
|
|
183
|
-
w, h = src_w,
|
|
183
|
+
w, h = src_w, round(src_w * h / w)
|
|
184
184
|
self.x = 0
|
|
185
185
|
else:
|
|
186
|
-
w, h =
|
|
186
|
+
w, h = round(src_h * w / h), src_h
|
|
187
187
|
self.y = 0
|
|
188
188
|
mark = mark.resize((w, h), resample=Image.LANCZOS)
|
|
189
189
|
|
|
190
190
|
if self.t < 100:
|
|
191
191
|
# 处理透明度
|
|
192
192
|
_, _, _, alpha_channel = mark.split()
|
|
193
|
-
alpha_channel = alpha_channel.point(lambda i: min(
|
|
193
|
+
alpha_channel = alpha_channel.point(lambda i: min(round(255 * self.t / 100), i))
|
|
194
194
|
mark.putalpha(alpha_channel)
|
|
195
195
|
|
|
196
196
|
# 计算位置,粘贴水印
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: py-img-processor
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: Image editor using Python and Pillow.
|
|
5
5
|
Home-page: https://github.com/SkylerHu/py-img-processor.git
|
|
6
6
|
Author: SkylerHu
|
|
@@ -54,7 +54,7 @@ Image editor using Python and Pillow.
|
|
|
54
54
|
|
|
55
55
|
## 2. 使用(Usage)
|
|
56
56
|
|
|
57
|
-
具体使用说明查看 [readthedocs](https://py-img-processor.readthedocs.io) 。
|
|
57
|
+
具体使用说明查看 [readthedocs](https://py-img-processor.readthedocs.io/) 。
|
|
58
58
|
|
|
59
59
|
## 2.1 运行配置
|
|
60
60
|
可以通过指定环境变量`PY_SETTINGS_MODULE`加载配置文件:
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
imgprocessor/__init__.py,sha256=2ebw4pYHInmKQKQEbkwQ-fHx0uM7ED026wgR04y7EYo,2243
|
|
2
|
+
imgprocessor/enums.py,sha256=-eA9pv5g-0Xm23jrHv5aJf2g56t95-hUgzSz4xlx5Go,3042
|
|
3
|
+
imgprocessor/exceptions.py,sha256=kj9win_XjCbZnXr93sYs4Cfg1hAJX2fn5hgr1YMNoHQ,384
|
|
4
|
+
imgprocessor/main.py,sha256=QDkz__RJ_iIjrb1p56bhPzZ7yLbtzhXvvKpLmvkJEkI,4133
|
|
5
|
+
imgprocessor/processor.py,sha256=4f6DTNeIRMTAlvtEn7UQQFuNUxMQJSB_dfkzERjvUQ4,4388
|
|
6
|
+
imgprocessor/utils.py,sha256=KBRQJaN8FuuRD2QQPYuuHQ7S-2ML-ctz4rstQTrEdog,1202
|
|
7
|
+
imgprocessor/parsers/__init__.py,sha256=3aSxKTflK2hZxaiYtaX3HsFvLwg9QE7YLIp4gdTf7T8,3004
|
|
8
|
+
imgprocessor/parsers/alpha.py,sha256=grOnmZSYhO0wI2pJfGz6CfTwOTc8kfcxspmfM0nzAzA,865
|
|
9
|
+
imgprocessor/parsers/base.py,sha256=80VTehgA8LwwVety3_IGSJ_vsX01mWAZNb-c6v3AT2o,11832
|
|
10
|
+
imgprocessor/parsers/blur.py,sha256=Y9BeTK7e-y8HPNeLQxgtqiquOVf2cVLXhXn1bv9072g,661
|
|
11
|
+
imgprocessor/parsers/circle.py,sha256=z0IZZSv_zuY2jzB6kN01sB1jGhBure33DPt7JAEeNsk,1653
|
|
12
|
+
imgprocessor/parsers/crop.py,sha256=P2kqNVn9tiorq_kgBXLxygthL2EKulNkP6aRh1FrmVw,3464
|
|
13
|
+
imgprocessor/parsers/gray.py,sha256=ZDBHZlBfI91TePWWBU0feSHmtD1ekre5-uV2BDLFTKA,396
|
|
14
|
+
imgprocessor/parsers/merge.py,sha256=JwJKIVlmeKxEQIeuYBKT_i5E6jBBOM2m4fqKWpPfuhs,4049
|
|
15
|
+
imgprocessor/parsers/resize.py,sha256=Zeh9LDLQVaEqijcOsljKGDNTQ2rUmijzQ0ziAgYsSoI,5020
|
|
16
|
+
imgprocessor/parsers/rotate.py,sha256=EDKvlxTgZZu7vAkSS9cuZ296dbAhe5Aq6huH9Hjtvy0,722
|
|
17
|
+
imgprocessor/parsers/watermark.py,sha256=y5ddCw9lRS1fwMjHtI0lIGpWcCIFSQA6Q0l7gpcNS7g,8488
|
|
18
|
+
py_img_processor-1.1.0.dist-info/LICENSE,sha256=Sr4UxtHWGmoO_enyTUeAN276LkBqJpse0guCcb6f9BQ,1066
|
|
19
|
+
py_img_processor-1.1.0.dist-info/METADATA,sha256=bEzbYrVLFqjJBP6pbvt-55Tq789Yo6e_L3Pgyi--RCY,7286
|
|
20
|
+
py_img_processor-1.1.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
21
|
+
py_img_processor-1.1.0.dist-info/entry_points.txt,sha256=MLeLjzpkH7DkDMgICWCQ99D9ElqAvTBVBGA8yjg4dhQ,57
|
|
22
|
+
py_img_processor-1.1.0.dist-info/top_level.txt,sha256=5Pm26oHcqZoihGGxc5N6qQJ2LuVa2i4au_uqHBMqehI,13
|
|
23
|
+
py_img_processor-1.1.0.dist-info/RECORD,,
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
imgprocessor/__init__.py,sha256=tq1x_qEidPWZdqdHZVvzOyMycI_yOa2dCqHVnaAhrnQ,2243
|
|
2
|
-
imgprocessor/enums.py,sha256=PgV1KCzdyfOk6VrxmiHZg8mjpYZJ9YG-O-35wtFPah0,3040
|
|
3
|
-
imgprocessor/exceptions.py,sha256=kj9win_XjCbZnXr93sYs4Cfg1hAJX2fn5hgr1YMNoHQ,384
|
|
4
|
-
imgprocessor/main.py,sha256=QDkz__RJ_iIjrb1p56bhPzZ7yLbtzhXvvKpLmvkJEkI,4133
|
|
5
|
-
imgprocessor/processor.py,sha256=4f6DTNeIRMTAlvtEn7UQQFuNUxMQJSB_dfkzERjvUQ4,4388
|
|
6
|
-
imgprocessor/utils.py,sha256=KBRQJaN8FuuRD2QQPYuuHQ7S-2ML-ctz4rstQTrEdog,1202
|
|
7
|
-
imgprocessor/parsers/__init__.py,sha256=3aSxKTflK2hZxaiYtaX3HsFvLwg9QE7YLIp4gdTf7T8,3004
|
|
8
|
-
imgprocessor/parsers/alpha.py,sha256=grOnmZSYhO0wI2pJfGz6CfTwOTc8kfcxspmfM0nzAzA,865
|
|
9
|
-
imgprocessor/parsers/base.py,sha256=xOLBF4w_o5_lzPf7Fzmsqdp1_Ljju9P4CZCMHfyfBZM,11824
|
|
10
|
-
imgprocessor/parsers/blur.py,sha256=Y9BeTK7e-y8HPNeLQxgtqiquOVf2cVLXhXn1bv9072g,661
|
|
11
|
-
imgprocessor/parsers/circle.py,sha256=z0IZZSv_zuY2jzB6kN01sB1jGhBure33DPt7JAEeNsk,1653
|
|
12
|
-
imgprocessor/parsers/crop.py,sha256=5Zg_TaAOa-JCZSDEpZqTX0T3sUDoHGJZzXQdOTinbTI,3460
|
|
13
|
-
imgprocessor/parsers/gray.py,sha256=ZDBHZlBfI91TePWWBU0feSHmtD1ekre5-uV2BDLFTKA,396
|
|
14
|
-
imgprocessor/parsers/merge.py,sha256=qKXK9ZUEYvPPBuR-pRvGG-JAuV4Z3aLYbmTjZWkwvNI,4045
|
|
15
|
-
imgprocessor/parsers/resize.py,sha256=Kgayf-VQH9BuLCA77yOoGUTI8NPo9qOK4RitPPXk7I8,4912
|
|
16
|
-
imgprocessor/parsers/rotate.py,sha256=EDKvlxTgZZu7vAkSS9cuZ296dbAhe5Aq6huH9Hjtvy0,722
|
|
17
|
-
imgprocessor/parsers/watermark.py,sha256=HSUnsyyCnG6F6pKSj3NHo8xT2-PC2BpBNve_PQ4cISg,8474
|
|
18
|
-
py_img_processor-1.0.3.dist-info/LICENSE,sha256=Sr4UxtHWGmoO_enyTUeAN276LkBqJpse0guCcb6f9BQ,1066
|
|
19
|
-
py_img_processor-1.0.3.dist-info/METADATA,sha256=TdgvvJiI9SKMaOooqPOP0zmAAq2cmLFhWEOdwjmfbiU,7285
|
|
20
|
-
py_img_processor-1.0.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
21
|
-
py_img_processor-1.0.3.dist-info/entry_points.txt,sha256=MLeLjzpkH7DkDMgICWCQ99D9ElqAvTBVBGA8yjg4dhQ,57
|
|
22
|
-
py_img_processor-1.0.3.dist-info/top_level.txt,sha256=5Pm26oHcqZoihGGxc5N6qQJ2LuVa2i4au_uqHBMqehI,13
|
|
23
|
-
py_img_processor-1.0.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|