py-img-processor 1.0.2__tar.gz → 1.1.0__tar.gz

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.

Potentially problematic release.


This version of py-img-processor might be problematic. Click here for more details.

Files changed (30) hide show
  1. {py_img_processor-1.0.2/py_img_processor.egg-info → py_img_processor-1.1.0}/PKG-INFO +2 -3
  2. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/README.md +1 -1
  3. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/imgprocessor/__init__.py +1 -1
  4. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/imgprocessor/enums.py +2 -2
  5. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/imgprocessor/parsers/__init__.py +1 -1
  6. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/imgprocessor/parsers/base.py +6 -12
  7. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/imgprocessor/parsers/crop.py +2 -2
  8. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/imgprocessor/parsers/merge.py +1 -1
  9. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/imgprocessor/parsers/resize.py +14 -13
  10. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/imgprocessor/parsers/watermark.py +6 -6
  11. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/imgprocessor/processor.py +1 -1
  12. {py_img_processor-1.0.2 → py_img_processor-1.1.0/py_img_processor.egg-info}/PKG-INFO +2 -3
  13. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/py_img_processor.egg-info/requires.txt +0 -1
  14. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/setup.py +0 -1
  15. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/LICENSE +0 -0
  16. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/MANIFEST.in +0 -0
  17. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/imgprocessor/exceptions.py +0 -0
  18. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/imgprocessor/main.py +0 -0
  19. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/imgprocessor/parsers/alpha.py +0 -0
  20. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/imgprocessor/parsers/blur.py +0 -0
  21. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/imgprocessor/parsers/circle.py +0 -0
  22. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/imgprocessor/parsers/gray.py +0 -0
  23. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/imgprocessor/parsers/rotate.py +0 -0
  24. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/imgprocessor/utils.py +0 -0
  25. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/py_img_processor.egg-info/SOURCES.txt +0 -0
  26. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/py_img_processor.egg-info/dependency_links.txt +0 -0
  27. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/py_img_processor.egg-info/entry_points.txt +0 -0
  28. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/py_img_processor.egg-info/not-zip-safe +0 -0
  29. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/py_img_processor.egg-info/top_level.txt +0 -0
  30. {py_img_processor-1.0.2 → py_img_processor-1.1.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: py-img-processor
3
- Version: 1.0.2
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
@@ -23,7 +23,6 @@ Description-Content-Type: text/markdown
23
23
  License-File: LICENSE
24
24
  Requires-Dist: py-enum>=1.1.1
25
25
  Requires-Dist: Pillow>=8
26
- Requires-Dist: typing_extensions
27
26
 
28
27
  # py-img-processor
29
28
 
@@ -55,7 +54,7 @@ Image editor using Python and Pillow.
55
54
 
56
55
  ## 2. 使用(Usage)
57
56
 
58
- 具体使用说明查看 [readthedocs](https://py-img-processor.readthedocs.io) 。
57
+ 具体使用说明查看 [readthedocs](https://py-img-processor.readthedocs.io/) 。
59
58
 
60
59
  ## 2.1 运行配置
61
60
  可以通过指定环境变量`PY_SETTINGS_MODULE`加载配置文件:
@@ -28,7 +28,7 @@ Image editor using Python and Pillow.
28
28
 
29
29
  ## 2. 使用(Usage)
30
30
 
31
- 具体使用说明查看 [readthedocs](https://py-img-processor.readthedocs.io) 。
31
+ 具体使用说明查看 [readthedocs](https://py-img-processor.readthedocs.io/) 。
32
32
 
33
33
  ## 2.1 运行配置
34
34
  可以通过指定环境变量`PY_SETTINGS_MODULE`加载配置文件:
@@ -5,7 +5,7 @@ import importlib
5
5
 
6
6
 
7
7
  __all__ = ["settings", "VERSION"]
8
- __version__ = "1.0.2"
8
+ __version__ = "1.1.0"
9
9
 
10
10
 
11
11
  VERSION = __version__
@@ -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", "固定宽高,强制缩放")
@@ -38,7 +38,7 @@ class ProcessParams(object):
38
38
  actions: typing.Optional[list] = None,
39
39
  **kwargs: typing.Any,
40
40
  ) -> None:
41
- self.save_parser: ImgSaveParser = ImgSaveParser.init(kwargs, enable_base64=enable_base64)
41
+ self.save_parser: ImgSaveParser = ImgSaveParser.init(kwargs, enable_base64=enable_base64) # type: ignore
42
42
 
43
43
  _actions = []
44
44
  for i in actions or []:
@@ -1,11 +1,5 @@
1
1
  import typing
2
2
 
3
- try:
4
- # python3.11只后
5
- from typing import Self # type: ignore
6
- except Exception:
7
- from typing_extensions import Self
8
-
9
3
  import re
10
4
 
11
5
  from PIL import Image, ImageOps
@@ -23,14 +17,14 @@ class BaseParser(object):
23
17
  pass
24
18
 
25
19
  @classmethod
26
- def init(cls, data: dict, enable_base64: bool = False) -> Self:
20
+ def init(cls, data: dict, enable_base64: bool = False) -> "BaseParser":
27
21
  params = cls.validate_args(enable_base64=enable_base64, **data)
28
22
  ins = cls(**params)
29
23
  ins.validate()
30
24
  return ins
31
25
 
32
26
  @classmethod
33
- def init_by_str(cls, param_str: str) -> Self:
27
+ def init_by_str(cls, param_str: str) -> "BaseParser":
34
28
  data = cls.parse_str(param_str)
35
29
  return cls.init(data, enable_base64=True)
36
30
 
@@ -214,11 +208,11 @@ def compute_by_geography(
214
208
  if "x" in pf:
215
209
  if x < 0 or x > 100:
216
210
  raise ParamValidateException(f"pf={pf}包含了x,所以x作为百分比取值范围为[0,100]")
217
- x = int(src_w * x / 100)
211
+ x = round(src_w * x / 100)
218
212
  if "y" in pf:
219
213
  if y < 0 or y > 100:
220
214
  raise ParamValidateException(f"pf={pf}包含了y,所以y作为百分比取值范围为[0,100]")
221
- y = int(src_h * y / 100)
215
+ y = round(src_h * y / 100)
222
216
  return x, y
223
217
 
224
218
 
@@ -237,11 +231,11 @@ def compute_by_ratio(src_w: int, src_h: int, ratio: str) -> tuple[int, int]:
237
231
  wr, hr = int(w_r), int(h_r)
238
232
  if src_w * hr > src_h * wr:
239
233
  # 相对于目标比例,宽长了
240
- w = int(src_h * wr / hr)
234
+ w = round(src_h * wr / hr)
241
235
  h = src_h
242
236
  elif src_w * hr < src_h * wr:
243
237
  w = src_w
244
- h = int(src_w * hr / wr)
238
+ h = round(src_w * hr / wr)
245
239
  else:
246
240
  # 刚好符合比例
247
241
  w, h = src_w, src_h
@@ -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 = int(src_w * w / 100)
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 = int(src_h * h / 100)
74
+ h = round(src_h * h / 100)
75
75
  elif not h:
76
76
  h = src_h
77
77
 
@@ -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 = int(src_w * self.p / 100), int(src_h * self.p / 100)
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
 
@@ -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, int(self.w * src_h / src_w)
65
+ w, h = self.w, round(self.w * src_h / src_w)
65
66
  else:
66
- w, h = int(self.h * src_w / src_h), self.h
67
+ w, h = round(self.h * src_w / src_h), self.h
67
68
  elif self.w:
68
- w, h = self.w, int(self.w * src_h / src_w)
69
+ w, h = self.w, round(self.w * src_h / src_w)
69
70
  else:
70
- w, h = int(self.h * src_w / src_h), self.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 = int(self.h * src_w / src_h), self.h
78
+ w, h = round(self.h * src_w / src_h), self.h
78
79
  else:
79
- w, h = self.w, int(self.w * src_h / src_w)
80
+ w, h = self.w, round(self.w * src_h / src_w)
80
81
  elif self.w:
81
- w, h = self.w, int(self.w * src_h / src_w)
82
+ w, h = self.w, round(self.w * src_h / src_w)
82
83
  else:
83
- w, h = int(self.h * src_w / src_h), self.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, int(src_h * self.l / src_w)
88
+ w, h = self.l, round(src_h * self.l / src_w)
88
89
  else:
89
- w, h = int(src_w * self.l / src_h), self.l
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 = int(src_w * self.s / src_h), self.s
94
+ w, h = round(src_w * self.s / src_h), self.s
94
95
  else:
95
- w, h = self.s, int(src_h * self.s / src_w)
96
+ w, h = self.s, round(src_h * self.s / src_w)
96
97
  elif self.p:
97
98
  # 按照比例缩放
98
- w, h = int(src_w * self.p / 100), int(src_h * self.p / 100)
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(int(self.size / 20), 2)
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(int(255 * self.shadow / 100), i))
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 = int(w * rate), int(h * rate)
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, int(src_w * h / w)
183
+ w, h = src_w, round(src_w * h / w)
184
184
  self.x = 0
185
185
  else:
186
- w, h = int(src_h * w / h), src_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(int(255 * self.t / 100), i))
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
  # 计算位置,粘贴水印
@@ -99,7 +99,7 @@ def extract_main_color(img_path: str, delta_h: float = 0.3) -> str:
99
99
 
100
100
  Args:
101
101
  img_path: 输入图像的路径
102
- delta_h: 像素色相和平均色相做减法的绝对值小于改值,才用于计算主色调,取值范围[0,1]
102
+ delta_h: 像素色相和平均色相做减法的绝对值小于该值,才用于计算主色调,取值范围[0,1]
103
103
 
104
104
  Returns:
105
105
  颜色值,eg: FFFFFF
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: py-img-processor
3
- Version: 1.0.2
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
@@ -23,7 +23,6 @@ Description-Content-Type: text/markdown
23
23
  License-File: LICENSE
24
24
  Requires-Dist: py-enum>=1.1.1
25
25
  Requires-Dist: Pillow>=8
26
- Requires-Dist: typing_extensions
27
26
 
28
27
  # py-img-processor
29
28
 
@@ -55,7 +54,7 @@ Image editor using Python and Pillow.
55
54
 
56
55
  ## 2. 使用(Usage)
57
56
 
58
- 具体使用说明查看 [readthedocs](https://py-img-processor.readthedocs.io) 。
57
+ 具体使用说明查看 [readthedocs](https://py-img-processor.readthedocs.io/) 。
59
58
 
60
59
  ## 2.1 运行配置
61
60
  可以通过指定环境变量`PY_SETTINGS_MODULE`加载配置文件:
@@ -1,3 +1,2 @@
1
1
  py-enum>=1.1.1
2
2
  Pillow>=8
3
- typing_extensions
@@ -41,7 +41,6 @@ setup(
41
41
  install_requires=[
42
42
  "py-enum>=1.1.1",
43
43
  "Pillow>=8",
44
- "typing_extensions",
45
44
  ],
46
45
  python_requires=">=3.9",
47
46
  classifiers=[