diff --git a/cropper.py b/cropper.py index b7ae113..7ec6901 100644 --- a/cropper.py +++ b/cropper.py @@ -16,6 +16,12 @@ def clip(value, min_value, max_value): value = max_value return value +def parse_workdir(filepath): + workdir = '/'.join('/'.join(filepath.split('\\')).split('/')[:-1]) + if workdir == '': + workdir = '.' + return workdir + def crop(args): infile = args.input # process filepath @@ -31,9 +37,8 @@ def crop(args): thresh = args.thresh # parse working dir. - workdir = '/'.join('/'.join(infile.split('\\')).split('/')[:-1]) - if workdir == '': - workdir = '.' + inworkdir = parse_workdir(infile) + outworkdir = parse_workdir(outfile) if infile.split('.')[-1].lower() in ['ppt', 'pptx']: # lets process pptx. @@ -119,7 +124,7 @@ def crop(args): names = ['{0}_{1}.pdf'.format(outbase, i+1) for i in range(len(pdf))] if args.names is not None: names = args.names - namesfile = os.path.join(workdir, names) + namesfile = os.path.join(inworkdir, names) if os.path.isfile(namesfile) and names.split('.')[-1] == 'txt': with open(namesfile, 'r', encoding='utf-8') as f: names = f.read() @@ -131,7 +136,7 @@ def crop(args): names = [n + '.pdf' if n[:-4] != '.pdf' else n for n in names] if len(names) < len(pdf): names += ['{0}_{1}.pdf'.format(outbase, i+1) for i in range(len(names), len(pdf))] - names = [os.path.join(workdir, name) for name in names] + names = [os.path.join(outworkdir, name) for name in names] for i, (name, page) in enumerate(zip(names, pdf)): page_pdf = fitz.Document() page_pdf.insertPDF(pdf, from_page=i, to_page=i) diff --git a/main.py b/main.py index f4b59d7..c571065 100644 --- a/main.py +++ b/main.py @@ -85,13 +85,15 @@ def parse_and_crop(conf): # parser.add_argument('--visual', '-v', default=False, action='store_true', help='display cropbox.') # parser.add_argument('--mute', '-m', default=False, action='store_true', help='do not display output file path.') # args = parser.parse_args() + + import os import json from ui import Loader defaults = { "input": "", "output": "", - "background_color": "", + "background_color": "255,255,255", "border": "0.0", "zoom": "1.0", "thresh": "1.0", @@ -111,7 +113,7 @@ else: conf = { "input": {"name": "源文件", "type": "readfile", "extension": ("PDF & PPT", ".pdf .pptx")}, - "output": {"name": "保存路径", "type": "savefile"}, + "output": {"name": "保存路径", "type": "savefile", "initial": "output.pdf"}, "background_color": {"name": "背景颜色", "type": "color", "default": "255,255,255"}, "border": {"name": "留白", "type": "str", "default": "0.0"}, "zoom": {"name": "缩放等级", "type": "str", "default": "1.0"}, @@ -122,9 +124,27 @@ conf = { "mute": {"name": "显示保存文件", "type": "str", "default": "false"}, } +introduction = [ +"==== 使用说明 ====", +"- 源文件:输入的文件,可以为PDF或者PPT,如果是PPT,会首先自动调用PowerPoint将给定的PPT转变为PDF然后进行裁剪(PPT裁剪第一次需要调用COM对象因此速度稍慢,建议耐心等待,裁切一次后速度会恢复到正常水平", +"- 保存路径:保存的文件名,仅适用于非拆分模式。如果留空,则保存路径为源文件所在目录,保存的文件名为\"源文件名_crop.pdf\"", +"- 背景颜色:哪一种颜色会被认为是背景", +"- 留白:不紧贴有效内容裁切,预留一个给定大小的白边。", +"- 缩放等级:裁切是基于视觉裁切的,因此裁切过程中会首先渲染PDF,采用默认值即可,更高的缩放会将PDF渲染为更高分辨率的图片从而提高裁剪精度,但计算时间也会相应增加。", +"- 阈值:像素值差异多少会被认为是前景。", +"- 拆分:是否将源文件自动拆分为每页一个的单个文件。默认文件名采取下划线+数字命名。如果源文件是PPT且PPT备注不为空,则首先采用PPT的备注作为当前页保存的文件名。", +"- 页名称:手动指定拆分模式下每一页的名称,具有最高优先级,用逗号分隔。留空则使用默认的文件名或者PPT中备注的文件名。", +"- 显示裁切框:在右侧的日志区域输出裁切框坐标", +"- 显示保存文件:显示保存的文件名。", +] +help_msg = '\n'.join(introduction) + # write defaults. for key in defaults: conf[key]['default'] = defaults[key] root = tk.Tk() -Loader(master=root, conf=conf, execution=parse_and_crop, title="PDF/PPT自动裁边") +Loader(master=root, conf=conf, execution=parse_and_crop, title="PDF/PPT自动裁边", help_msg=help_msg) + + +print(help_msg) root.mainloop() \ No newline at end of file diff --git a/ui.py b/ui.py index 3ac113f..20835ee 100644 --- a/ui.py +++ b/ui.py @@ -29,7 +29,7 @@ def text_on_image(img, text, pos, size=16, color='#000000'): return img class Loader(tk.Frame): - def __init__(self, master=None, conf={}, execution=None, title=None): + def __init__(self, master=None, conf={}, execution=None, title=None, help_msg=None): super().__init__(master) self.master = master self.conf = conf @@ -44,7 +44,7 @@ class Loader(tk.Frame): # self.font = tk.Font(family='', size=40,weight='',slant='',underline='',overstrike='') if self.title is not None: self.master.title(self.title) - + self.help_msg = help_msg def add_resource(self, obj, name): if name in self.resources: print('Name [{0}] Repeated.'.format(name)) @@ -137,6 +137,12 @@ class Loader(tk.Frame): conf[name] = self.resources[key].get() self.execution(conf) + def clear(self): + self.resources['textbox_log'].delete("1.0", 'end') + + def showhelp(self): + print(self.help_msg) + def create_widgets(self): self.rowcount = 0 for key, value in self.conf.items(): @@ -153,7 +159,7 @@ class Loader(tk.Frame): destination = 'entry_' + key if dtype in ['readfile', 'savefile', 'directory']: extension = value.get('extension', None) - initialfile = default + initialfile = value.get('initial', None) args = { "dst": destination, "choose_type": dtype, @@ -161,7 +167,7 @@ class Loader(tk.Frame): "initial_file": initialfile } self.add_button( - text="选择文件", + text="<选择文件", command=lambda args=args:self.choose_file(**args), size=(16, 16), layout={"row":self.rowcount, "column": 2, "padx": 5}, @@ -171,7 +177,7 @@ class Loader(tk.Frame): self.conf[key]['type'] = 'str' elif dtype == 'color': self.add_button( - text="选择颜色", + text="<选择颜色", command=lambda dst=destination:self.choose_color(dst), size=(16, 16), layout={"row":self.rowcount, "column": 2, "padx": 5}, @@ -181,15 +187,29 @@ class Loader(tk.Frame): self.rowcount += 1 self.add_button( - text=" 裁剪 ", + text="清空输出>", + command=self.clear, + size=(16, 16), + layout={"row":self.rowcount-2, "column": 2, "pady": 5, "sticky": "e"}, + name='clear_output' + ) + self.add_button( + text="显示帮助>", + command=self.showhelp, + size=(16, 16), + layout={"row":self.rowcount-1, "column": 2, "pady": 5, "sticky": "e"}, + name='show_help' + ) + self.add_button( + text=" 开始裁剪 ", command=self.execute, size=(16, 16), - layout={"row":self.rowcount, "column": 0, "columnspan": 2, "pady": 5}, + layout={"row":self.rowcount, "column": 0, "columnspan": "3", "pady": 5}, name='execute_final' ) self.add_textbox( width=40, - layout={"row":0, "column": 3, "rowspan": self.rowcount, "padx": 5, "pady": 0}, + layout={"row":0, "column": 3, "rowspan": self.rowcount + 1, "padx": 5, "pady": 5, "sticky": "ns"}, name="textbox_log" ) sys.stdout = StdSimulator(self.resources['textbox_log'])