-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
321 lines (267 loc) · 11.5 KB
/
main.py
File metadata and controls
321 lines (267 loc) · 11.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
import time
from PIL import Image, ImageFilter
import numpy as np
import os
import requests as rq
def download_image(platform, mod_id):
print("\n正在下载图片")
photoName = rsp = photoUrl = ""
try:
if platform == "Curseforge":
k = rq.get(r'https://api.cfwidget.com/{0}'.format(mod_id), params={'param': '1'}).json()
photoUrl = k["thumbnail"]
elif platform == "Modrinth":
k = rq.get(r'https://api.modrinth.com/v2/project/{0}'.format(mod_id), params={'param': '1'}).json()
photoUrl = k["icon_url"]
photoName = "修改前图.png"
rsp = rq.get(photoUrl, timeout=10)
rsp.raise_for_status()
except Exception as e:
end("下载图片失败,{0}".format(e))
with open("./{0}".format(photoName), "wb") as f:
f.write(rsp.content)
return photoName
def resize_image(img, size):
"""Resize the image to the specified size using nearest-neighbor interpolation."""
if size == 2:
img = img.resize((150, 150), Image.NEAREST)
elif size == 3:
img = img.resize((300, 300), Image.NEAREST)
elif size == 4:
img = img.resize((450, 450), Image.NEAREST)
else:
pass
save_path = os.path.join(os.getcwd(), f"放大后图.png")
img.save(save_path)
return img
def load_image(img, size=1):
"""Load, validate that the image is 1:1 aspect ratio, and resize while preserving transparency."""
try:
# Resize to specified size using nearest-neighbor interpolation
img = resize_image(img, size)
width, height = img.size
if width != height:
print(f"Warning: Image is not square (1:1). Current dimensions: {width}x{height}")
return None
# Convert to RGBA to ensure transparency is preserved
if img.mode != 'RGBA':
img = img.convert('RGBA')
return img
except Exception as e:
print(f"Error loading image: {e}")
return None
def method_1_blurred_duplicates(img, output_width, output_height):
"""Method 1: Place blurred copies on left and right, original in center."""
# Create result with RGBA mode to handle transparency properly
result = Image.new('RGBA', (output_width, output_height))
original_size = img.size[0]
# Center position for the original image
center_pos = (output_width - original_size) // 2
# Create blurred version
blurred_img = img.copy().filter(ImageFilter.GaussianBlur(radius=3))
# Paste the blurred copy aligned with the left edge of the cover
result.paste(blurred_img, (0, 0))
# Paste the blurred copy aligned with the right edge of the cover
result.paste(blurred_img, (output_width - original_size, 0))
# Create a temporary image with the original at center position
temp = Image.new('RGBA', (output_width, output_height), (0, 0, 0, 0))
temp.paste(img, (center_pos, 0))
# Use alpha_composite instead of paste to preserve transparency
result = Image.alpha_composite(result, temp)
return result
def method_2_main_color_background(img, output_width, output_height):
"""Method 2: Extract the main color from the image and use it as background, fill transparent areas with the main
color."""
img_array = np.array(img)
pixels = img_array.reshape(-1, 4) if img.mode == 'RGBA' else img_array.reshape(-1, 3)
# Find dominant color using a simple approach
color_counts = {}
color = (0, 0, 0, 0) # Default color
for pixel in pixels:
if pixel[3] != 0:
color = tuple(pixel[:3])
if color in color_counts:
color_counts[color] += 1
else:
color_counts[color] = 1
dominant_color = max(color_counts, key=color_counts.get)
# Create background with dominant color
result = Image.new('RGBA', (output_width, output_height), dominant_color)
# Fill transparent areas with the dominant color
if img.mode == 'RGBA':
img = img.convert('RGBA')
background = Image.new('RGBA', img.size, dominant_color + (255,))
img = Image.alpha_composite(background, img).convert('RGB')
# Calculate position for the original image (centered)
original_size = img.size[0]
center_pos = (output_width - original_size) // 2
# Paste the original image in the center
result.paste(img, (center_pos, 0))
return result
def method_3_edge_pixel_tiling(img, output_width, output_height):
"""Method 3: Extract 1-pixel wide strips from edges and tile them."""
result = Image.new('RGBA', (output_width, output_height))
original_size = img.size[0]
center_pos = (output_width - original_size) // 2
left_width = center_pos
right_width = center_pos
# Extract 1-pixel strips from the edges
left_strip = img.crop((0, 0, 1, original_size))
right_strip = img.crop((original_size - 1, 0, original_size, original_size))
# Create tiled backgrounds for left and right sides
left_tiled = Image.new('RGBA', (left_width, original_size))
right_tiled = Image.new('RGBA', (right_width, original_size))
# Fill the backgrounds with the strips
for x in range(0, left_width, 1):
left_tiled.paste(left_strip, (x, 0))
for x in range(0, right_width, 1):
right_tiled.paste(right_strip, (x, 0))
# Paste the tiled backgrounds and original image
result.paste(left_tiled, (0, 0))
result.paste(img, (center_pos, 0))
result.paste(right_tiled, (center_pos + original_size, 0))
return result
def method_4_custom_color_background(img, output_width, output_height):
"""Method 4: Use a custom color background."""
color = input("请输入背景色(十六进制颜色值,如#FFFFFF,输入0默认为白色):")
if color == "0" or color == "":
color = "#FFFFFF"
if color.startswith("#"):
color = color[1:]
if len(color) != 6:
print("无效的颜色值,将使用默认白色为背景。")
color = "#FFFFFF"
try:
color = tuple(int(color[i:i + 2], 16) for i in (0, 2, 4)) + (255,)
except ValueError:
print("无效的颜色值,将使用默认白色为背景。")
color = (255, 255, 255)
result = Image.new('RGBA', (output_width, output_height), color)
original_size = img.size[0]
center_pos = (output_width - original_size) // 2
temp = Image.new('RGBA', (output_width, output_height), (0, 0, 0, 0))
temp.paste(img, (center_pos, 0))
result = Image.alpha_composite(result, temp)
return result
def main():
print("Cover Image Creator")
print("-------------------")
print("请向程序传入尺寸为1:1的图片,你可选择以下三种方式传入:")
print("1. 输入Curseforge模组ID联网下载封面图(大小为256x256)")
print("2. 输入Modrinth模组ID联网下载封面图(大小不定)")
print("3. 输入本地图片路径")
choice = int(input("请输入你的选择(1-3):"))
if choice == 1:
mod_id = input("请输入模组ID:")
photoName = download_image("Curseforge", mod_id)
input_path = os.path.basename(photoName)
elif choice == 2:
mod_id = input("请输入模组ID:")
photoName = download_image("Modrinth", mod_id)
input_path = os.path.basename(photoName)
elif choice == 3:
input_path = input("请输入本地图片路径:").strip('"')
if not os.path.exists(input_path):
end("文件不存在,请检查路径。")
return
else:
end("无效的选择。退出程序。")
return
if os.path.exists(input_path) is None:
end("文件不存在,请检查路径。")
return
choice = 1
img = load_image(Image.open(input_path))
print("\n原图尺寸为:{0}".format(img.size))
if img.size[1] < 150:
print(f"图片尺寸过小(宽度 {img.size} < 150),可能需要缩放处理")
print("是否以邻近方式缩放图片?")
print("1. 否,直接以原大小修改比例到16:9")
print("2. 是,缩放到240x150")
print("3. 是,缩放到480x300")
print("4. 是,缩放到720x450")
print("0. 默认1")
choice = input("请输入你的选择(0-4):")
if choice == "":
choice = 1
else:
choice = int(choice)
if choice not in [0, 1, 2, 3, 4]:
end("无效的选择。退出程序。")
return
if choice == 0:
choice = 1
img = load_image(Image.open(input_path), size=choice)
original_size = img.size[0]
output_height = original_size
output_width = int(original_size * 1.6) # 16:10 aspect ratio
print("\n选择封面图处理方法:")
print("1. 在图片背后复制图层并高斯模糊")
print("2. 提取主色调作为背景")
print("3. 提取两侧边缘像素并平铺")
print("4. 自定义背景色作为背景")
print("5. 一次性产出以上四种处理后的图片")
print("0. 默认5")
choice = input("\n请输入你的选择(0-5):")
if choice == "":
choice = 5
else:
choice = int(choice)
if choice == 0:
choice = 5
if choice == 1:
result = method_1_blurred_duplicates(img, output_width, output_height)
output_path = os.path.join(
os.getcwd(), f"修改后图_模糊.png")
result.save(output_path)
print(f"图片处理完毕:{output_path}")
elif choice == 2:
result = method_2_main_color_background(img, output_width, output_height)
output_path = os.path.join(
os.getcwd(), f"修改后图_主色调.png")
result.save(output_path)
print(f"图片处理完毕:{output_path}")
elif choice == 3:
result = method_3_edge_pixel_tiling(img, output_width, output_height)
output_path = os.path.join(
os.getcwd(), f"修改后图_边缘.png")
result.save(output_path)
print(f"图片处理完毕:{output_path}")
elif choice == 4:
result = method_4_custom_color_background(img, output_width, output_height)
output_path = os.path.join(
os.getcwd(), f"修改后图_自定背景色.png")
result.save(output_path)
print(f"图片处理完毕:{output_path}")
elif choice == 5 or choice == "":
result1 = method_1_blurred_duplicates(img, output_width, output_height)
result2 = method_2_main_color_background(img, output_width, output_height)
result3 = method_3_edge_pixel_tiling(img, output_width, output_height)
result4 = method_4_custom_color_background(img, output_width, output_height)
output_path = os.path.join(
os.getcwd(), f"修改后图_模糊.png")
result1.save(output_path)
output_path = os.path.join(
os.getcwd(), f"修改后图_主色调.png")
result2.save(output_path)
output_path = os.path.join(
os.getcwd(), f"修改后图_边缘.png")
result3.save(output_path)
output_path = os.path.join(
os.getcwd(), f"修改后图_自定背景色.png")
result4.save(output_path)
print("图片处理完毕:")
print(f"修改后图_模糊.png")
print(f"修改后图_主色调.png")
print(f"修改后图_边缘.png")
print(f"修改后图_自定背景色.png")
end("所有图片已处理完毕")
else:
end("无效的选择。退出程序。")
return
def end(reason):
print("程序终止,原因:", reason, "\n三秒后退出")
time.sleep(3)
exit()
if __name__ == "__main__":
main()