Skip to content

Commit

Permalink
重构Cropper (#380)
Browse files Browse the repository at this point in the history
* refactor cropper interface; remove baidu aip; add libfacedetect face recognition
  • Loading branch information
glyh authored Sep 27, 2024
1 parent d103767 commit c092b2d
Show file tree
Hide file tree
Showing 50 changed files with 340 additions and 503 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

参见[Package javsp](https://github.com/Yuukiy/JavSP/pkgs/container/javsp)
- 添加新的爬虫`arzon`, `arzon_iv` [#377](https://github.com/Yuukiy/JavSP/pull/377)
- Slimeface人脸识别 [#380](https://github.com/Yuukiy/JavSP/pull/380)

### Changed
- 使用 Poetry 作为构建系统 [134b279](https://github.com/Yuukiy/JavSP/commit/134b279151aead587db0b12d1a30781f2e1be5b1)
Expand All @@ -33,8 +34,11 @@
```
- 为了引入对类型注释的支持,最低Python版本现在为3.10

- 重构封面剪裁逻辑 [#380](https://github.com/Yuukiy/JavSP/pull/380)

### Removed
- Pyinstaller 打包描述文件 [134b279](https://github.com/Yuukiy/JavSP/commit/134b279151aead587db0b12d1a30781f2e1be5b1)
- requirements.txt [134b279](https://github.com/Yuukiy/JavSP/commit/134b279151aead587db0b12d1a30781f2e1be5b1)
- MovieID.ignore_whole_word 功能和ignore_regex重复 [e096d83](https://github.com/Yuukiy/JavSP/commit/e096d8394a4db29bb4a1123b3d05021de201207d)
- NamingRule.media_servers:由于不常用删除,之后会出更general的解决方案 [#353](https://github.com/Yuukiy/JavSP/issues/353)
- Baidu AIP人脸识别,请使用Slimeface替代。
14 changes: 4 additions & 10 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,16 +130,10 @@ summarizer:
- '^HHL'
# 要使用的图像识别引擎,详细配置见文档 https://github.com/Yuukiy/JavSP/wiki/AI-%7C-%E4%BA%BA%E8%84%B8%E8%AF%86%E5%88%AB
# NOTE: 此处无法直接对应,请参照注释手动填入
engine: null #null表示禁用图像剪裁
## 使用百度人体分析应用: {{{
engine: null # null表示禁用图像剪裁
## 使用Slimeface: {{{
# engine:
# name: baidu_aip
# # 百度人体分析应用的AppID
# app_id: ''
# # 百度人体分析应用的API Key
# api_key: ''
# # 百度人体分析应用的Secret Key
# secret_key: ''
# name: slimeface
## }}}

fanart:
Expand All @@ -150,7 +144,7 @@ summarizer:
# 是否下载剧照?
enabled: true
# 间隔的两次封面爬取请求之间应该间隔多久
scrap_interval: PT2S
scrap_interval: PT1.5S

################################
translator:
Expand Down
76 changes: 34 additions & 42 deletions javsp/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import json
import time
import logging
from PIL import Image
from pydantic import ValidationError
from pydantic_extra_types.pendulum_dt import Duration
import requests
Expand All @@ -21,8 +22,8 @@
pretty_errors.configure(display_link=True)


from javsp.core.print import TqdmOut
from javsp.core.baidu_aip import aip_crop_poster
from javsp.print import TqdmOut
from javsp.cropper import Cropper, get_cropper


# 将StreamHandler的stream修改为TqdmOut,以与Tqdm协同工作
Expand All @@ -34,17 +35,17 @@
logger = logging.getLogger('main')


from javsp.core.lib import resource_path
from javsp.core.nfo import write_nfo
from javsp.core.file import *
from javsp.core.func import *
from javsp.core.image import *
from javsp.core.datatype import Movie, MovieInfo
from javsp.lib import resource_path
from javsp.nfo import write_nfo
from javsp.file import *
from javsp.func import *
from javsp.image import *
from javsp.datatype import Movie, MovieInfo
from javsp.web.base import download
from javsp.web.exceptions import *
from javsp.web.translate import translate_movie_info

from javsp.core.config import BaiduAipEngine, Cfg, CrawlerID
from javsp.config import Cfg, CrawlerID

actressAliasMap = {}

Expand Down Expand Up @@ -376,25 +377,30 @@ def reviewMovieID(all_movies, root):
print()


SUBTITLE_MARK_FILE = os.path.abspath(resource_path('image/sub_mark.png'))
UNCENSORED_MARK_FILE = os.path.abspath(resource_path('image/unc_mark.png'))
def crop_poster_wrapper(fanart_file, poster_file, engine: BaiduAipEngine | None, hard_sub=False, uncensored=False):
"""包装各种海报裁剪方法,提供统一的调用"""
if engine is BaiduAipEngine:
try:
aip_crop_poster(fanart_file, engine.app_id, engine.api_key, poster=poster_file)
except Exception as e:
logger.debug('人脸识别失败,回退到常规裁剪方法')
logger.debug(e, exc_info=True)
crop_poster(fanart_file, poster_file)
else:
crop_poster(fanart_file, poster_file)
if Cfg().summarizer.cover.add_label:
if hard_sub == True:
add_label_to_poster(poster_file, SUBTITLE_MARK_FILE, LabelPostion.BOTTOM_RIGHT)
if uncensored == True:
add_label_to_poster(poster_file, UNCENSORED_MARK_FILE, LabelPostion.BOTTOM_LEFT)
SUBTITLE_MARK_FILE = Image.open(os.path.abspath(resource_path('image/sub_mark.png')))
UNCENSORED_MARK_FILE = Image.open(os.path.abspath(resource_path('image/unc_mark.png')))

def process_poster(movie: Movie):
def should_use_ai_crop_match(label):
for r in Cfg().summarizer.cover.crop.on_id_pattern:
re.match(r, label)
return True
return False
crop_engine = None
if (movie.info.uncensored or
movie.data_src == 'fc2' or
should_use_ai_crop_match(movie.info.label.upper())):
crop_engine = Cfg().summarizer.cover.crop.engine
cropper = get_cropper(crop_engine)
fanart_image = Image.open(movie.fanart_file)
fanart_cropped = cropper.crop(fanart_image)

if Cfg().summarizer.cover.add_label:
if movie.hard_sub:
fanart_cropped = add_label_to_poster(fanart_cropped, SUBTITLE_MARK_FILE, LabelPostion.BOTTOM_RIGHT)
if movie.uncensored:
fanart_cropped = add_label_to_poster(fanart_cropped, UNCENSORED_MARK_FILE, LabelPostion.BOTTOM_LEFT)
fanart_cropped.save(movie.poster_file)

def RunNormalMode(all_movies):
"""普通整理模式"""
Expand Down Expand Up @@ -455,22 +461,8 @@ def check_step(result, msg='步骤错误'):
actual_ext = os.path.splitext(pic_path)[1]
movie.poster_file = os.path.splitext(movie.poster_file)[0] + actual_ext

def should_use_ai_crop_match(label):
for r in Cfg().summarizer.cover.crop.on_id_pattern:
re.match(r, label)
return True
return False

crop_engine = None
process_poster(movie)

if (movie.info.uncensored or
movie.data_src == 'fc2' or
should_use_ai_crop_match(movie.info.label.upper())):
crop_engine = Cfg().summarizer.cover.crop.engine
inner_bar.set_description('使用AI裁剪海报封面')
else:
inner_bar.set_description('裁剪海报封面')
crop_poster_wrapper(movie.fanart_file, movie.poster_file, crop_engine, movie.hard_sub, movie.uncensored)
check_step(True)

if Cfg().summarizer.extra_fanarts.enabled:
Expand Down
4 changes: 1 addition & 3 deletions javsp/core/avid.py → javsp/avid.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
__all__ = ['get_id', 'get_cid', 'guess_av_type']


from javsp.core.config import Cfg

Path('1.png').stem
from javsp.config import Cfg

def get_id(filepath_str: str) -> str:
"""从给定的文件路径中提取番号(DVD ID)"""
Expand Down
File renamed without changes.
15 changes: 6 additions & 9 deletions javsp/core/config.py → javsp/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
from enum import Enum
from typing import Dict, List, Literal, TypeAlias, Union
from confz import BaseConfig, CLArgSource, EnvSource, FileSource
from pydantic import ByteSize, Discriminator, Field, NonNegativeInt, PositiveInt, field_validator
from pydantic import ByteSize, Field, NonNegativeInt, PositiveInt
from pydantic_extra_types.pendulum_dt import Duration
from pydantic_core import Url
from pathlib import Path

from javsp.core.lib import resource_path
from javsp.lib import resource_path

class Scanner(BaseConfig):
ignored_id_pattern: List[str]
Expand Down Expand Up @@ -143,15 +143,12 @@ class ExtraFanartSummarize(BaseConfig):
enabled: bool
scrap_interval: Duration

class BaiduAipEngine(BaseConfig):
name: Literal['baidu_aip']
app_id: str
api_key: str
secret_key: str
class SlimefaceEngine(BaseConfig):
name: Literal['slimeface']

class CoverCrop(BaseConfig):
engine: BaiduAipEngine | None
on_id_pattern: list[str]
engine: SlimefaceEngine | None
on_id_pattern: list[str]

class CoverSummarize(BaseConfig):
basename_pattern: str
Expand Down
Loading

0 comments on commit c092b2d

Please sign in to comment.