mirror of
https://github.com/hect0x7/JMComic-Crawler-Python.git
synced 2025-09-26 22:31:30 +08:00
v2.5.22: 新增long_img插件,将本子合并为长图 (#299)
This commit is contained in:
parent
b0cd90468e
commit
8482e4dc77
@ -121,10 +121,11 @@ jmcomic.download_album(422866, option)
|
||||
- `压缩文件插件`
|
||||
- `下载特定后缀图片插件`
|
||||
- `发送QQ邮件插件`
|
||||
- `日志主题过滤插件`
|
||||
- `自动使用浏览器cookies插件`
|
||||
- `jpg图片合成为一个pdf插件`
|
||||
- `导出收藏夹为csv文件插件`
|
||||
- `合并所有图片为pdf文件插件`
|
||||
- `合并所有图片为长图插件`
|
||||
|
||||
## 使用小说明
|
||||
|
||||
|
@ -244,6 +244,13 @@ plugins:
|
||||
pdf_dir: D:/pdf/ # pdf存放文件夹
|
||||
filename_rule: Aname # pdf命名规则,A代表album, name代表使用album.name也就是本子名称
|
||||
|
||||
# 插件来源:https://github.com/hect0x7/JMComic-Crawler-Python/pull/294
|
||||
# long_img插件是把所有图片合并为一个png长图,效果和img2pdf类似
|
||||
- plugin: long_img
|
||||
kwargs:
|
||||
img_dir: D:/pdf/ # 长图存放文件夹
|
||||
filename_rule: Aname # 长图命名规则,同上
|
||||
|
||||
# 请注意⚠
|
||||
# 下方的j2p插件的功能不如img2pdf插件,不建议使用。
|
||||
# 如有图片转pdf的需求,直接使用img2pdf即可,下面的内容请忽略。
|
||||
|
@ -2,7 +2,7 @@
|
||||
# 被依赖方 <--- 使用方
|
||||
# config <--- entity <--- toolkit <--- client <--- option <--- downloader
|
||||
|
||||
__version__ = '2.5.21'
|
||||
__version__ = '2.5.22'
|
||||
|
||||
from .api import *
|
||||
from .jm_plugin import *
|
||||
|
@ -799,6 +799,101 @@ class Img2pdfPlugin(JmOptionPlugin):
|
||||
return pdf_dir
|
||||
|
||||
|
||||
class LongImgPlugin(JmOptionPlugin):
|
||||
plugin_key = 'long_img'
|
||||
|
||||
def invoke(self,
|
||||
photo: JmPhotoDetail = None,
|
||||
album: JmAlbumDetail = None,
|
||||
downloader=None,
|
||||
img_dir=None,
|
||||
filename_rule='Pid',
|
||||
delete_original_file=False,
|
||||
**kwargs,
|
||||
):
|
||||
if photo is None and album is None:
|
||||
jm_log('wrong_usage', 'long_img必须运行在after_photo或after_album时')
|
||||
|
||||
try:
|
||||
from PIL import Image
|
||||
except ImportError:
|
||||
self.warning_lib_not_install('PIL')
|
||||
return
|
||||
|
||||
self.delete_original_file = delete_original_file
|
||||
|
||||
# 处理文件夹配置
|
||||
img_dir = self.get_img_dir(img_dir)
|
||||
|
||||
# 处理生成的长图文件的路径
|
||||
filename = DirRule.apply_rule_directly(album, photo, filename_rule)
|
||||
|
||||
# 长图路径
|
||||
long_img_path = os.path.join(img_dir, f'{filename}.png')
|
||||
|
||||
# 调用 PIL 把 photo_dir 下的所有图片合并为长图
|
||||
img_path_ls = self.write_img_2_long_img(long_img_path, album, photo)
|
||||
self.log(f'Convert Successfully: JM{album or photo} → {long_img_path}')
|
||||
|
||||
# 执行删除
|
||||
self.execute_deletion(img_path_ls)
|
||||
|
||||
def write_img_2_long_img(self, long_img_path, album: JmAlbumDetail, photo: JmPhotoDetail) -> List[str]:
|
||||
import itertools
|
||||
from PIL import Image
|
||||
|
||||
if album is None:
|
||||
img_dir_items = [self.option.decide_image_save_dir(photo)]
|
||||
else:
|
||||
img_dir_items = [self.option.decide_image_save_dir(photo) for photo in album]
|
||||
|
||||
img_paths = itertools.chain(*map(files_of_dir, img_dir_items))
|
||||
img_paths = filter(lambda x: not x.startswith('.'), img_paths) # 过滤系统文件
|
||||
|
||||
images = self.open_images(img_paths)
|
||||
|
||||
try:
|
||||
resample_method = Image.Resampling.LANCZOS
|
||||
except AttributeError:
|
||||
resample_method = Image.LANCZOS
|
||||
|
||||
min_img_width = min(img.width for img in images)
|
||||
total_height = 0
|
||||
for i, img in enumerate(images):
|
||||
if img.width > min_img_width:
|
||||
images[i] = img.resize((min_img_width, int(img.height * min_img_width / img.width)),
|
||||
resample=resample_method)
|
||||
total_height += images[i].height
|
||||
|
||||
long_img = Image.new('RGB', (min_img_width, total_height))
|
||||
y_offset = 0
|
||||
for img in images:
|
||||
long_img.paste(img, (0, y_offset))
|
||||
y_offset += img.height
|
||||
|
||||
long_img.save(long_img_path)
|
||||
for img in images:
|
||||
img.close()
|
||||
|
||||
return img_paths
|
||||
|
||||
def open_images(self, img_paths: List[str]):
|
||||
images = []
|
||||
for img_path in img_paths:
|
||||
try:
|
||||
img = Image.open(img_path)
|
||||
images.append(img)
|
||||
except IOError as e:
|
||||
self.log(f"Failed to open image {img_path}: {e}", 'error')
|
||||
return images
|
||||
|
||||
@staticmethod
|
||||
def get_img_dir(img_dir: Optional[str]) -> str:
|
||||
img_dir = fix_filepath(img_dir or os.getcwd())
|
||||
mkdir_if_not_exists(img_dir)
|
||||
return img_dir
|
||||
|
||||
|
||||
class JmServerPlugin(JmOptionPlugin):
|
||||
plugin_key = 'jm_server'
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user