正在查看 34 个帖子:1-34 (共 34 个帖子)
  • 作者
    帖子
  • @215712 回复 ⚑举报 

    赤霄
    游客

    界面移植到pyside6,配色一致,整体比下面的视觉更佳。

    c408f5080b88f1f1cf3a289657dbaed342a97aab88f16b1f

    @215713 回复 ⚑举报 

    赤霄
    游客

    功能如下:

    1、读取pdf拼合

    2、读取图片文件夹拼接

    3、读取双页扫描件

    4、读取拆分单页

    5、读取整版筒子页

    6、视图为拼接预览图

    7、键盘与鼠标移动图像

    8、设置画布边距

    9、设置缩放

    10、设置横缩

    11、设置旋转

    12、设置版框参考

    13、导出分割单页pdf

    14、导出拼接整页pdf

    @215714 回复 ⚑举报 

    书格AI
    参与者

    看到您的古籍拼合工具界面已成功移植到 PySide6,并且配色一致,视觉效果更佳,这真是个好消息。感谢您的持续改进!期待看到新版本。

    (以上内容由Gemini AI自动答复,仅供参考!)

    @215715 回复 ⚑举报 

    赤霄
    游客
    @215716 回复 ⚑举报 

    赤霄
    游客

    分合之道:古籍数字拼合的本体论与方法论

    ——自“画布分离式拼合工具”而悟入

    卷一·道枢

    万物并作,吾以观复。夫物芸芸,各复归其根。

    一部古籍的流传,是跨越千载的“分”:书页离散于岁月,边角残损于虫蠹,版框错位于流转。而我们的数字拼合,便是逆流而上的“合”——将离散之碎片,在数字世界中重聚其形,复归其神。

    然合非强加。强合者,貌合而神离。真正的合,必以分为基。以分为法,以合为宗;因分而能合,因合而见分。 分与合,非互斥之两端,而是同一过程中互为表里的两种节律——如呼吸之吐纳,如阴阳之消长,如昼夜之交替。

    由此,我们建立了一套完整的古籍数字拼合方法体系。其要义不在繁复之技,而在简约之道——通过对“分”的精妙运用,达成“合”的至高境界。此心法非为炫技,实乃求道。

    卷二·本体

    欲明分合之道,必先识古籍之本。

    一部古籍,从本体论观之,乃是三层结构的统一体:形制为体,意象为魂,修用为衣。

    形制者,载体也。 纸墨之质,页序之列,装帧之式。此为古籍的物质存在,是“分”的首要对象——如何将一部书拆解为可独立处理的单元,又如何将这些单元重新组合为新的阅读形态。形制为体,体之不存,书将焉附?

    意象者,精神也。 非徒像素之堆砌,乃文字所承载之思想、版式所蕴含之气韵、墨色所传递之情感。此乃古籍的灵魂所在,是“合”的终极追求——如何让离散的页面意象完整呈现,让读者得以直面古人精神。意象为魂,魂之不彰,书何以传?

    修用者,补益也。 水渍之痕,虫蛀之洞,印章之迹。此为古籍的时间印记,亦是阅读之障。修用的智慧,在于如何处理这些痕迹——既不能损伤意象之真性,又需为阅读提供便利。修用为衣,衣之不整,书何以观?

    形制为体,以立其骨;意象为魂,以充其神;修用为衣,以美其容。 体立则书可存,魂充则书可传,衣整则书可观。三者和合,方成一部完整之书。分合之道,便是贯通此三者、使之和谐统一的根本心法。

    卷三·三轴九维

    形制为体,意象为魂,修用为衣。此三者之所以能够成立、能够流传、能够为人所用,全赖三层关系之维系。我们将其归纳为三轴九维。

    一曰“融”——本体之轴。 形制、意象、修用三者相融,构成古籍的完整存在。

    · 形制为体:纸墨之质,页序之列,装帧之式。体之不存,书将焉附?
    · 意象为魂:文字之思想,版式之气韵,墨色之情感。魂之不彰,书何以传?
    · 修用为衣:水渍之痕,虫蛀之洞,印章之迹。衣之不整,书何以观?

    体立则骨正,魂充则神全,衣整则容美。三者和合,方成一部完整之书。

    二曰“传”——流传之轴。 原本、修改、复本,是古籍在时间中存在的三种形态。

    · 原本为真:未经改动的原始扫描,承载着全部的历史信息,是我们操作的“实”之根基。
    · 修改为用:在原本之上进行的变换——位移、缩放、旋转、裁切。皆是数学层面的坐标映射,不触及原图意象本身。
    · 复本为果:标准化后的输出,可以是单页、双页对开、类蝶装册,随需赋形,各尽其用。

    真而不改,改而不损,复而不离其宗。 此乃流传之道。

    三曰“会”——意义之轴。 阅读、领会、传播,是古籍在人类精神世界中实现其价值的过程。

    · 阅读为入:文字入眼,版式入心。拼合后的古籍,首先要便于阅读,中缝不偏,版框齐整。
    · 领会为通:贯通文义,领悟精神。当意象得以完整呈现,读者方能穿越时空,与古人精神相接。
    · 传播为出:化一为多,流布四方。单页、对开、分册,不同的输出形制服务于不同的传播场景。

    入而通之,通而出之,出而复入。 此乃会通之道。

    三三得九,九九归一。 融、传、会三轴,将形制之体、意象之魂、修用之衣三者贯通,形成了古籍从“存在”到“流传”再到“意义”的完整生命链条。而我们的分合之道,正是这一生命链条的数字实现。

    卷四·法门

    三轴已立,九维已明,今当以八重分合之法,逐一贯通三轴九维。此八重法门,按操作之层次,可分为三境:操作空间之“分”,对应“融”轴,奠定形制之体、意象之魂、修用之衣的独立;工作流程之“分”,对应“传”轴,贯通原本、修改、复本之过程;目标形制之“分”,对应“会”轴,实现单页、双页、错页之产出。

    第一重:虚实之判(融轴·意象之魂)

    此为八重法门之根基,亦是对“融”轴中意象之魂与形制之体关系之解决。

    拼合之始,将混沌一体之“操作”进行最根本的剖分。

    · 意象为“实”:它是古籍的灵魂所在——文字的思想、版式的气韵、墨色的情感。我们对它持绝对敬意——永不修改其分毫像素。缩放、位移、旋转,皆是数学层面的坐标映射,不触及意象本身的分辨率与质量。真性不二,本来面目。
    · 画布为“虚”:它是纯粹的精神框架,界定边界、承载标尺的虚空。不存储意象内容,却为意象的呈现提供全部法则。

    道之所在:意象因其“实”而永葆真性;画布因其“虚”而获得定义一切的无限自由。虚以御实,实以填虚。虚实相生,各安其守。 此“分”直接对应“传”轴中“原本”之地位——原本不可动,动者唯虚。一切操作皆在画布层完成,意象始终如如不动。魂之守真,乃全书之命脉。

    技术实现:

    · “虚”之构建:画布被定义为一个纯净的 tk.Canvas 控件,其上可叠加任意 Tkinter 图形元素。参考框线(绿色虚线)通过 canvas.create_rectangle 以 dash 参数绘制,遮盖层(纯色矩形块)以 fill 参数填充。此等元素皆为画布层的原生对象,拥有独立的 tags,可随时删除或重绘,与图像毫无牵连。
    · “实”之守护:原始页面(PDF或图片)仅通过 fitz.Matrix(PyMuPDF)或 Image.resize(Pillow)进行数学变换。核心在于,我们从不将变换结果写回原始文件,而是实时渲染到一个独立的 PIL.Image 对象上。此对象是临时的、内存中的,每次参数改变即重新生成,原始图像始终只读。
    · 虚实相生:最终显示时,将渲染好的图像 PIL.Image 转换为 ImageTk.PhotoImage,贴到画布上。画布上的框线和遮盖层便自然浮于图像之上。操作图像时,只改变其变换矩阵参数,触发 refresh_display 重新生成预览图像并刷新画布,而画布层元素不受任何影响。虚以御实,实以填虚,在此得到最直观的技术呈现。

    第二重:单双之变(会轴·单页→双页)

    此为“会”轴中“阅读”形态的关键实现,亦是我们反直觉思维的精髓所在。

    面对“将两个独立单页拼为一开”的任务,常人之思是先将双页分割开再左右对置。我们反其道而行之。

    · 先合:将原始文档复制一份,使意象成双。复制序列之首位插入空白页。孤立的意象一,有了空白意象零与之相配;意象二与意象一相配,以此类推。
    · 后分:将整体画布中分,左页裁其半,右页裁其半。左页于左半区内示其右侧,右页于右半区内示其左侧。二部在中线自然对接,中缝立现。

    道之所在:合为分之本,分为合之形。不增一物,不损一毫,仅凭一套算法,便实现了从单页到双页的完美跃迁。化繁为简,不在于切割问题,而在于重新定义问题。此乃分合之道在算法设计上最为精妙的体现。体之重构,乃魂之重现。

    技术实现:

    · “先合”之技:我们不物理复制PDF页面,而是在内存中构建一个逻辑页面序列。开启“滚动拼接”时,程序在原始页面列表 base 前插入一个索引 -1(代表空白页),然后构建映射对:seq = [-1] + base,pairs = [(seq[i], seq[i-1]) for i in range(1, len(seq))]。于是,原本孤立的页面1在复制序列中有了页面0(空白)与之相配;页面2与页面1相配。此一举,内存占用为零,却使每一“对”都蕴含了相邻两页的完整信息。
    · “后分”之技:在渲染双页对开时,左右页各自由一个独立的 fitz.Rect 裁剪区域限定。左页的裁剪区为 fitz.Rect(lw * l_crop_pct, 0, lw, lh),右页为 fitz.Rect(0, 0, rw * (1 - r_crop_pct), rh)。当用户在界面上将边距设为50%时,l_crop_pct = 0.5, r_crop_pct = 0.5,左右页便各自只显示其一半内容,在中线自然对接,中缝立现。

    第三重:逆向之用(会轴·双页→单页)

    此为“单双之变”的逆向运用,亦是算法统一性的最佳证明。

    常有已影印之筒子页整版,需分割为左右单页以便独立处理或重新拼合。常规做法是编写专门的分割工具。而我们发现,分割即是拼接的逆向,完全复用同一套算法。

    · 自为配:将筒子页整版输入后,令其与自身配对——左页取原图,右页亦取原图。画面虽同,但裁切各异。
    · 序从常:配对顺序采用普通顺序(先右后左),即 pairs = [(base[i+1], base[i])]。此保证右页在左,左页在右,与正常拼接的视觉一致。
    · 中分裁:将画布中分,左页裁其半,右页裁其半。左子画布裁去原图左半,保留右半;右子画布裁去原图右半,保留左半。
    · 分而出:输出时选择“单页输出”模式,左右子画布各自独立输出为一个单页。于是,筒子页整版一分为二,左半成右单页,右半成左单页。

    道之所在:此法的精妙,在于以合为分,以分为合。拼接的算法未改,裁切的逻辑未变,所变者唯输入之源与输出之形。一套算法,正向可合二为一,逆向可一分为二,正反相通,体用不二。分合之道,本无定向,顺势而用,则为分;逆势而行,则为合。 这正是算法统一性所能达到的最高境界——不增一法,而能双向用功。

    技术实现:

    · 自配逻辑:用户加载筒子页整版PDF后,程序在构建页面对时检测到仅有一页,自动将其索引同时填入左页和右页位置:pairs = [(page_idx, page_idx)]。内存中,左右页指向同一个原始页面对象,但拥有独立的变换参数。
    · 裁切分离:左页的裁剪区域为 fitz.Rect(lw * 0.5, 0, lw, lh)——裁去左半,保留右半;右页的裁剪区域为 fitz.Rect(0, 0, rw * 0.5, rh)——裁去右半,保留左半。这两个裁剪矩形互不重叠,分别提取出原筒子页的左右两半内容。
    · 单页输出:在“分割输出”模式下,左子画布的内容(原右半)作为一个独立PDF页面输出,右子画布的内容(原左半)作为另一个独立PDF页面输出。两个输出页面皆可后续独立处理,与普通单页无异。合时裁半以拼接,分时裁半以割离——同一把刀,正反两用。

    第四重:时空之剖(融轴·形制之体)

    此为对“融”轴中形制之体层面之解决。双页之“合”已成,然需为左右意象划定各自的“封地”。我们将大画布从中轴线一分为二,创生左、右两个子画布。

    · 左页入左界,右页入右界。二者拥有独立的坐标系与裁剪边界。
    · 左页意象随位移溢过中线,则被左子画布之右边界自然裁剪;右页同理。

    道之所在:此一“分”,为左右意象划定了疆域。二部在各自治下可自由移动,互不侵扰。中缝之严丝合缝,非费心对齐之果,乃各自守界之自然产物。分疆而治,方能无缝相合。 体之正位,乃阅读之基。

    技术实现:

    · 子画布构建:在合成预览图 compose_preview 时,我们创建两个独立的 PIL.Image 对象 left_section 和 right_section,尺寸严格等于 (left_margin_pix + left_canvas_pix) 和 (right_canvas_pix + right_margin_pix)。这两个子画布是物理隔离的,各自拥有独立的白底。
    · 独立变换:左页的缩放、旋转、位移参数(ldx, ldy, ls, lst, la)仅应用于左子画布内的图像粘贴位置计算。其粘贴坐标为 paste_x = left_margin_pix + left_canvas_pix + (ldx + l_ov) * ps - left_disp_w,paste_y = total_h_pix - left_disp_h - ldy * ps。右页同理,其粘贴坐标为 paste_x = (rdx - r_ov) * ps,paste_y = total_h_pix - right_disp_h - rdy * ps。注意此处 l_ov 与 r_ov 为中缝重叠参数,允许左右页向中线方向微调。
    · 自动裁剪:由于 PIL 的 paste 操作本身受限于目标图像的尺寸,任何超出左子画布右边界或右子画布左边界的内容,都会被 PIL 自动丢弃。这无需任何额外计算,便实现了中缝的像素级精确裁剪。这正是子画布分割的精妙之处——边界即裁剪。
    · 最终拼合:两个子画布通过 comp.paste(left_section, (0, 0)) 和 comp.paste(right_section, (left_section_w, 0)) 无缝拼接为最终的大画布 comp。左子画布占据左侧,右子画布占据右侧,中线处天然严丝合缝。

    第五重:坐标之衡(交互层)

    此为交互设计中最隐秘、也最见功力的心法。

    我们的工具涉及三套截然不同的坐标系:PDF坐标(原点左下,y向上)、PIL图像坐标(原点左上,y向下)、屏幕画布坐标(原点左上,且随缩放漂移)。若强求统一,必有一方扭曲。我们的解法,是不统一坐标系,而统一“意图”。

    · 反向映射:当用户在屏幕上拖拽图像时,系统并不直接按屏幕坐标移动图像。而是实时捕捉鼠标指针的视觉位移,将其反向映射到图像所在的实际坐标系中,再计算出图像应当移动的精确数值。
    · 意图统一:无论内核是何种坐标系,用户眼中所见、手下所感,始终是同一方向:向上拖,图像向上;向左移,图像向左。此“跟手感”的达成,非因坐标之统一,而因操作指向与视觉反馈达至完美一致。

    道之所在:不动而动,以静制动。我们不改变任何坐标系的本性(静),却以一层巧妙的映射(动),让所有坐标系皆服从于用户的直觉。乱生于内而统一于外。 此乃分合之道在交互层面最为精微的运用。

    技术实现:

    · 多重坐标的挑战:屏幕坐标(鼠标事件的 event.x, event.y)、画布坐标(图像缩放后居中偏移 x0, y0)、图像像素坐标(PIL.Image)、PDF点坐标(pypdf/fitz,原点左下,y向上)。此四者方向、原点各异。
    · 反向映射管道:交互时,通过以下管道层层转化,最终统一为一致的视觉效果:
    1. canvas_to_image_coords(cx, cy):将屏幕坐标 (cx, cy) 转换为当前预览图像的像素坐标 (ix, iy)。此函数包含了画布缩放(disp_scale)、居中偏移(x0, y0)、超尺寸限制(ratio)等全部转换逻辑,是坐标统一的枢纽。
    2. 像素坐标转PDF点:pdf_x = ix / preview_scale,pdf_y = total_h_pdf - iy / preview_scale。这一翻转,解决了PIL(y向下)与PDF(y向上)的矛盾。
    · 跟手感实现:鼠标拖拽时,计算起始与当前位置在图像像素坐标上的差值 (ix1-ix0, iy1-iy0),再转为PDF点位移 dx = (ix1-ix0) / ps,dy = -(iy1-iy0) / ps。注意 dy 取反,这便是“向上拖拽,图像向上”的根本所在。键盘移动直接使用 dy = -step,逻辑一致。

    第六重:标准之绳(传轴·修改→复本)

    此为“传”轴中从“修改”到“复本”的关键环节,解决“复本”如何统一的问题。我们在画布之上,再立一独立、浮于万物之上的参考框线。

    · 此绿色虚线,不与任何意象绑定,唯代表心中之“标准版框”。
    · 可自由调整其尺寸与位置(水平、垂直偏移),然后将各自独立的左右意象,通过缩放与横缩,分别向此标准对齐。

    道之所在:框线为“一”,悬而不动之绝对标准;意象为“万”,千姿百态之变动之物。以“一”统“万”,以“虚”绳“实”。 正是这条虚拟的线,让所有离散之意象寻得了统一的归宿。体之统一,乃魂之归所。

    技术实现:

    · 相对坐标存储:参考框线的位置和尺寸不以绝对像素或PDF点存储,而是以相对于当前画布总宽高的比例(0~1 的浮点数)存储,记为 self.ref_rect_ratio = (rx0, ry0, rx1, ry1)。这使其与具体图像尺寸解耦,完全独立于画布之上。
    · 动态绘制:每次画布大小改变(窗口缩放、预览缩放),draw_reference_rect 方法都会用当前画布的实际宽高 (disp_dw, disp_dh) 乘以这些相对比例,计算出新的像素坐标进行绘制:px0 = disp_x0 + rx0 * disp_dw。这保证了框线永远随画布“智能缩放”。
    · 物理值反算:当用户拖拽绘制框线时,先用当前画布尺寸算出相对坐标,再乘以当前页面的物理尺寸(self.total_w_pdf, self.total_h_pdf),反算出物理宽高和水平/垂直偏移,填入输入框。手动修改输入框时,再通过 on_ref_dim_changed 反算出新的相对坐标。二者互为镜像,完美同步。
    · 层级管理:框线绘制后,通过 self.canvas.tag_raise("ref_rect") 将其置于所有遮盖层之上,确保虚线永远可见,不被色块遮挡。

    第七重:序次之散(传轴·原本→修改)

    前三重解决了单页内部之“融”——体已正、魂已守、衣已整。今当面对整部著作的庞大体量,解决“传”轴中从“原本”到“修改”的过程。我们的策略是化整为零,将一卷拆解为一对又一对独立之“页面对”。

    · 数百页之PDF或整个文件夹之图片,被分解为独立的单元。
    · 每对页面皆拥有独立的位移、缩放、裁切、遮盖数据,可按任意顺序处理,自由跳转。

    道之所在:此看似将整体拆散,实则为最高效之“合”铺路。可从中间任一页始,可单独调整任一对而不扰全局。最终,所有独立之操作数据汇入一个JSON项目文件,成统一之“合”集。流程上散为游击,数据上聚为整军。 分合之间,游刃有余。

    技术实现:

    · 状态分离:每一对页面的所有操作参数(位移、缩放、旋转、横缩、遮盖列表、框线位置、中线重叠等)都存储在以页面索引 pair_idx 为键的字典中,如 self.offsets[pair_idx] = {'left': (ldx, ldy), 'right': (rdx, rdy)}。这些字典彼此独立,互不干扰。
    · JSON序列化:点击“保存项目”时,auto_save_project 方法将这些字典进行深度拷贝,并序列化为一个 JSON 文件。所有值均转换为可读的纯文本格式(浮点数、列表),与 pdf_path、page_range 等全局配置一并存储。
    · 状态恢复:加载项目时,JSON被解析,所有字典被恢复。切换页面时,update_side_label 方法直接从当前页对的字典中读取位移、缩放等值,并刷新UI控件的显示。这实现了“独立处理每一对,但全局状态统一保存”的灵活工作流。

    第八重:形制之化(会轴·双页→错页)

    此为“会”轴中“传播”形态的最高实现。标准化完成之后,每一意象皆已成为独立、可自由组合之单元。它们不再受限于最初的卷册次序,而获得装帧的自由。

    · 单页独立:每页皆可单独输出为标准化的单页,尺寸统一,版框齐整。此为一切后续重组之原子基础。
    · 双页对开:相邻两页左右拼合,成完整筒子页对开。此为我们最为熟悉的古籍阅读形态。
    · 类蝶装错页拼合:更为精妙者,可将标准化后的意象,按照古籍锁线精装之配页法则重新组合。例如一十六页之小册,拼合顺序非1-2、3-4,而是1-16、2-15、3-14……8-9。首尾相衔,向心而合,每开两页之页码和恒为十七。凡四之倍数——十二、二十、二十四——皆循此法。如此拼成之小册,折页后中缝向外,书叶翻动如蝶翼展翅,既保护了珍贵的版心接缝,又实现了跨页的完整阅读。同时,将大部头古籍分为若干此类小册,以锁线装订,彻底解决厚册难翻、易损之千古难题。

    道之所在:标准化为“分”,将全书之意象拆解为等质之原子;装帧为“合”,让意象按任意次序重新组合,产生千姿百态之阅读形态。页码之序为分,装订之序为合,首尾相衔,向心而聚,使知识之载体本身也成为道的印证。体之万化,乃魂之远播。

    技术实现:

    · 标准化原子:通过“单页输出”模式(save_merged 中 output_mode == "split"),每一页经变换(缩放、旋转、横缩、框线对齐)后,被渲染为一个尺寸统一、版框齐整的独立PDF页面。此页面即为“原子”。
    · 配页算法:用户指定册子页数(如16页),程序按 (1,16), (2,15), (3,14)... 的规则,计算出一个新的页面对序列 new_pairs。此算法可概括为:对于总页数 N,第 i 对(从1开始)的左右页索引分别为 i 和 N - i + 1。
    · 重组渲染:程序遍历 new_pairs,将每对中的两个“原子”页面(已是标准化后的单页PDF),按照与普通双页拼接完全相同的子画布逻辑,粘贴到一个新的对开画布上。因为所有原子已标准化,此过程无需再调整,直接渲染即可。
    · 分册输出:循环以上过程,自动将一部巨著输出为多个连续的锁线小册子PDF。此一举,将“分合之道”从单页内部的形制处理,拓展到了整部著作的装帧重构,使工具的能力从“修复”提升到了“创造”。

    卷五·归元

    八重分合已毕,三轴九维已贯通。今当归于一心,统摄万法。

    操作空间之“分”,以虚实之判、时空之剖、补益之慈三重法门,将意象之魂、形制之体、修用之衣三者各自独立,奠定了“融”轴之基。此为体之分。

    工作流程之“分”,以序次之散、标准之绳二重法门,将整卷化整为零,又将零散归于统一,贯通了原本、修改、复本之过程。此为传之分。

    目标形制之“分”,以单双之变、逆向之用、形制之化三重法门,将单一页码序列转化为多种阅读形态,实现了单页、双页、错页的自由组合,更以一法而通正反——合可拼双页,分可割整版。此为会之分。

    体分则各正其位,传分则各安其序,会分则各尽其用。

    然而,分之尽头,恰是合之峰顶:

    · 体之合:虚实相融于画布,左右相合于中线,瑕瑜相安于图层。形制为体,意象为魂,修用为衣,三者和合。
    · 传之合:操作数据汇于一文,标准框线统于一线。原本、修改、复本,一脉相承。
    · 会之合:单页、双页、错页,同出一源,随需化现。阅读、领会、传播,三用圆成。

    三而一,一而三。分之毕也,合之至也。

    卷六·心印

    此一套心法,非为炫技,实乃求道。

    古籍拼合,形而下者,是意象之拼接;形而上者,是文化之延续。我们的工具之所以能化繁为简、以简驭繁,不在于掌握了多少复杂算法,而在于悟透了“分”与“合”这一对根本范畴。

    能分,故能守其真;能合,故能归其全。能逆,故能通其变。

    以此心法驾驭工具,则无论面对何种古籍、何种残损、何种形制,皆可应对自如。从流程之始——读取文件,到操作之中——拼合修改,再到产出之终——保存文档;从画布之虚,到意象之实,再到遮盖之慈;从单页之基,到双页之观,再到错页之妙;从合二为一之拼接,到一分为二之分割——无一不是分合之道的生动演绎。

    分合之道,是这件工具的灵魂。它不仅是功能的总纲,更是一种方法论:任何复杂的拼合,皆可通过巧妙地“分”,来达成更高层次的“合”;任何既成的合体,亦可循此道而“分”,归于本来面目。 分合之间,正反相成,这便是我们能够超越凡品,成为“神兵利器”的最深层奥秘。

    观其分,则层层拆解,脉络清晰,各有所司;
    观其合,则浑然一体,天衣无缝。形制以立骨,意象以充神,修用以美形。三者和合,真性不失,精神永存。

    此分合之道,愿与天下同道共参。

    @215718 回复 ⚑举报 

    赤霄
    游客

    由于界面和使用库均进行替换,以下修订技术实现部分为当前版本。

    第一重:虚实之判(融轴·意象之魂)

    技术实现:

    · “虚”之构建:画布被定义为一个独立的 QGraphicsScene 场景,其坐标原点为左上角,向右为 X 轴正方向,向下为 Y 轴正方向。参考框线(红色虚线)通过 QGraphicsRectItem 创建,并设置 setZValue(100) 使其浮于顶层。遮盖层(纯色矩形块)由 QPainter 在合成预览图像时直接绘制,而非独立控件。图像层以 QGraphicsPixmapItem 承载,多层元素在同一场景中自然分层,互不干扰。
    · “实”之守护:原始页面(PDF 或图片)仅通过数学变换进行显示,核心在于只读原则。PDF 页面通过 pypdfium2 渲染为 QImage,在渲染过程中即可设定缩放比例(scale=2.0),然后对该图像进行裁剪、缩放、旋转等操作,生成临时 QImage 对象。这些操作完全不触及原始 PDF 文件或原始图像像素,参数改变时仅重新生成临时图像并刷新显示。
    · 虚实相生:最终显示时,将处理后的左右页图像绘制到固定尺寸的总画布 QImage 上,再转换为 QPixmap 赋予 QGraphicsPixmapItem。参考框线作为独立图形项叠加在场景中,遮盖则在绘制总画布时以 fillRect 方式嵌入。两者层次分明:框线位于场景顶层,遮盖位于图像层之上,但都在画布空间内协同工作。

    第二重:单双之变(会轴·单页→双页)

    技术实现:

    · “先合”之技:程序在内存中维护一个 original_pages 列表,保存用户选定范围内的页面索引(包括 -1 表示缺失,-2 表示手动插入的空白页)。开启“滚动拼接”时,rebuild_pairs 方法生成配对序列:seq = [-1] + base,pairs = [(seq[i], seq[i-1]) for i in range(1, len(seq))]。这就实现了 1-0, 2-1, 3-2 … 的错位配对,无需物理复制任何页面。
    · “后分”之技:图像边距(当前对)控制着每一页自身的裁剪。双拼模式下,通过 get_effective_image_margins 自动返回 50.0, 50.0, 0.0, 0.0,意味着左页左边裁去 50%,右页右边裁去 50%。在 try_compose 中,裁剪通过 QRect 区域复制实现,裁后的左页只保留右半内容,右页只保留左半内容,二者在中线处自然对接。

    第三重:逆向之用(会轴·双页→单页)

    技术实现:

    · 自配逻辑:用户勾选“整版分单”后,rebuild_pairs 生成 pairs = [(idx, idx) for idx in base]。左右页指向同一个原始页面索引,但各自拥有独立的变换参数(缩放、偏移等),且图像边距和重叠值独立设置。
    · 裁切分离:整版分单时,on_split_single_toggled 自动将画布左边距和右边距设为 -50%(在 canvas_left_spin 和 canvas_right_spin 中),同时将中缝重叠设为左右各 50%。这意味着左页内容向右移动半个基准宽度,右页内容向左移动半个基准宽度。画布的总宽度固定为基准宽度的两倍加边距,因此左半画布显示的是页面的右半部分,右半画布显示的是页面的左半部分,实现了筒子页的分割。
    · 单页输出:在 basic_assemble_pages 的分割模式下,先生成左右子画布的临时 PDF 页面,然后分别添加到输出文档中。每个子画布页面的尺寸等于 canvas_left + base_w + canvas_right,内容位置与预览完全一致。

    第四重:时空之剖(融轴·形制之体)

    技术实现:

    · 子画布构建:在 try_compose 中,我们创建两个独立的 QImage 对象 left_section 和 right_section。左子画布宽度为 canvas_left_px + base_w * scale,右子画布宽度为 base_w * scale + canvas_right_px,高度均为 total_h_px。这两个子画布拥有纯白背景,是物理隔离的绘制区域。
    · 独立变换:左页的粘贴坐标 target_x = left_section_w - scaled_w + ldx + l_ov,确保其右边缘对齐子画布右边界;右页的粘贴坐标 target_x = rdx - r_ov,确保其左边缘对齐子画布左边界。垂直方向通过 (base_h_px - scaled_h) / 2.0 - ldy 实现居中。缩放、旋转等变换均在粘贴前对图像本身完成。
    · 自动裁剪:QPainter 的 drawImage 操作仅会在目标 QImage 的矩形范围内绘制,任何超出子画布边界的部分会自动被丢弃。这无需任何额外计算,便实现了中缝的像素级精确裁剪。
    · 最终拼合:将左右子画布通过 QPainter 绘制到总画布 composite 上:painter.drawImage(0, 0, left_section) 和 painter.drawImage(left_section_w, 0, right_section)。导出时采用相同的子画布策略:先创建左右临时 PDF 页面,再在 merge 模式下拼合,或在 split 模式下分别输出。

    第五重:坐标之衡(交互层)

    技术实现:

    · 多重坐标:视图坐标(event.position())、场景坐标(view.mapToScene())、画布像素坐标(QImage 的像素索引)、PDF 点坐标(pypdf 中的点,原点左下,Y 向上)。其中视图到场景的转换由 QGraphicsView 自动处理,场景到画布像素的转换由我们的代码显式管理。
    · 拖拽映射:鼠标按下时记录起始点 drag_start_point(视图坐标)和当前偏移量 drag_start_offsets(点坐标)。鼠标移动时计算视图坐标差值 delta,通过乘以一个经验系数 0.1 转换为 PDF 点位移,并更新 offsets 字典。垂直方向取反(- delta.y()),实现“向上拖拽,图像向上”的直觉操作。键盘方向键同样通过修改 offsets 实现,步长固定为 1.0 点。
    · 缩放中心:滚轮事件 wheel_event 中,先获取鼠标在视图中的位置 view_pos,映射为场景坐标 scene_pos;然后应用缩放因子 zoom_factor 到视图;最后调用 view.centerOn(scene_pos) 使鼠标所指的场景点保持在视口中央,实现以光标为中心的缩放。

    第六重:标准之绳(传轴·修改→复本)

    技术实现:

    · 场景坐标存储:参考框线以 QGraphicsRectItem 形式存在于 QGraphicsScene 中,其位置和尺寸直接使用场景像素坐标。拖拽绘制时,通过 view.mapToScene() 获取起始和结束场景坐标,计算出矩形宽高和中心点,并更新参数控件(ref_width_spin 等)。手动修改控件值会触发 ref_param_changed,进而调用 draw_ref_rect 重新创建矩形。
    · 动态绘制:draw_ref_rect 方法创建一个新的 QGraphicsRectItem,设置红色虚线画笔(QPen(QColor("red"), Qt.DashLine, 2)),并设置 setZValue(100) 将其置于所有图形元素之上。每次参数改变或启用状态切换时,旧矩形被移除,新矩形被添加。
    · 拖拽编辑:在 mouse_press 中,当启用参考框线且未锁定时,按下鼠标即开始绘制新矩形(以 rubber_band 临时矩形反馈)。在 mouse_release 中,若矩形足够大,则提取其尺寸和中心位置,更新控件并调用 draw_ref_rect 绘制正式框线。锁定状态下不响应拖拽,右键恢复视图功能不受影响。

    第七重:序次之散(传轴·原本→修改)

    技术实现:

    · 状态分离:所有页面级别的参数(偏移、缩放、横缩、旋转、图像边距、遮盖列表等)都组织为以 pair_idx 为键的字典,如 self.offsets、self.scales、self.stretches、self.rotations、self.image_margins 和 self.tapes。这些字典在 rebuild_pairs 时会清除无效条目,保证与当前配对列表一致。
    · JSON序列化:save_project 方法遍历上述字典,将所有值转换为可 JSON 序列化的格式(如将元组转为列表,整数键转为字符串键),与 pdf_path、canvas_base_w、global_left_overlap 等全局参数一同写入文件。
    · 状态恢复:load_project 方法读取 JSON 文件,恢复所有字典和全局参数,然后调用 rebuild_pairs 重新生成配对,update_controls 刷新 UI 显示,request_render_current 重新渲染当前对。切换页面时,update_controls 直接根据当前 pair_idx 从字典中读取对应值并设置到控件上,实现“独立处理每一对,但全局状态统一保存”。

    第八重:形制之化(会轴·双页→错页)

    技术实现:

    · 标准化原子:在分割输出模式(basic_assemble_pages 的 mode == "split")中,每页经变换(缩放、横缩、旋转)和边距裁剪后,被渲染为一个独立的临时 PDF 页面。这些页面尺寸统一(基于全局基准宽度 canvas_base_w 和画布边距),内容对齐方式固定(左页右对齐,右页左对齐),可作为“原子”用于后续重组。
    · 配页算法:rebuild_pairs_for_butterfly 方法根据用户指定的每册页数(如 16),生成错页配对序列。算法为:将原始页面按每 n 页一组分组,每组内左页取前半部分顺序(group[0]、group[1]…),右页取后半部分逆序(group[n-1]、group[n-2]…)。若最后一组不足,用 -1 补足。生成的对序列形如 (1,16), (2,15), (3,14)…。
    · 重组渲染:在蝶装模式下,程序复用标准的 basic_assemble_pages 逻辑,将生成的错页配对列表作为临时 pairs 传入。因为每个原子页面已经标准化,拼接过程无需再调整图像边距或变换,直接通过子画布拼合即可得到正确的对开页面。
    · 分册输出:整个蝶装输出在 show_save_dialog 的 do_save 函数中统一处理:临时替换 self.pairs 为蝶装配对,调用 basic_assemble_pages 完成输出,最后恢复原始配对。这样一部巨著可被自动拆分为多个连续的小册 PDF,每个小册均可用于锁线精装。

     

    @215734 回复 ⚑举报 

    鹦山读书人
    游客

    谢谢分享工具

    @215738 回复 ⚑举报 

    开开心心
    游客

    上手容易不手残党好学不

    @215739 回复 ⚑举报 

    开开心心
    游客

    彩图好修复不

    @215743 回复 ⚑举报 

    牧北斋
    游客

    @赤霄 #215715

    感谢先生分享,试用了一下和您提一点小建议,在放大预览页面后微调左侧面板数值时预览窗口又会缩放至100%,这样不利于边观察细节边微调参数,如果在放大浏览窗口微调操作面板时预览窗口不自动缩回百分之一百就方便多了

    @215758 回复 ⚑举报 

    赤霄
    游客

    @牧北斋 #215743

    你提出的这个确实是bug,如果还有别的问题欢迎反馈,我下周修复,预计周三之后才有时间,连中午都不得空。

    @215759 回复 ⚑举报 

    赤霄
    游客

    @开开心心 #215738

    没有任何难度,所见即所得。

    @215760 回复 ⚑举报 

    赤霄
    游客

    @牧北斋 #215743

    看了下,这个修复较为简单,只是预览中的恢复视图那一行代码。增加保持当前视图即可。

    @215845 回复 ⚑举报 

    一念斋
    游客

    请问序号4,边距裁剪怎么用?一直是预览,没有裁剪。

     

    @215846 回复 ⚑举报 

    赤霄
    游客

    @一念斋 #215845

    边距裁剪有两个,一个是图像的裁剪,是针对图像裁边的,值为裁边;一个是画布整体调边距的,是给页面增减边距的,正为加白边负为裁边。

    如果只预览导出时没裁到,我打包前测试正,说明出bug,我打包前测试正常,那需要修复。

    @215893 回复 ⚑举报 

    赤霄
    游客

    @牧北斋 #215743

    已修复

    @215894 回复 ⚑举报 

    赤霄
    游客

     

    软件界面如图

    ScreenShot_2026-07-06_163933_981ScreenShot_2026-07-06_163718_782

    @215895 回复 ⚑举报 

    赤霄
    游客

    已完成拼接书籍:道德经宋版麻沙本,提供单页和整页。

    我用夸克网盘给你分享了「音注河上公老子道德经.汉.河上公.章句.宋.吕祖谦.重校.南宋时期建阳麻沙刘通判宅仰高堂刊本.台北故宫博物院藏_out.pdf」,点击链接或复制整段内容,打开「夸克APP」即可获取。
    /~d4023ZQLAS~:/
    链接:

    pan.quark.cn/s/c7e9bec26ba2

    提取码:hc2G

    @215896 回复 ⚑举报 

    z
    游客

    感谢分享!

    @215897 回复 ⚑举报 

    赤霄
    游客

    我用夸克网盘给你分享了「古籍拼合工具2.0.exe」,点击链接或复制整段内容,打开「夸克APP」即可获取。
    /~806b3ZQM0Y~:/
    链接:

    pan.quark.cn/s/31b...d?pwd=f7nK

    提取码:f7nK

    @215899 回复 ⚑举报 

    赤霄
    游客

    阅读器阅读效果

    Screenshot_2026-07-06-20-11-06-313_com.pdf.readerScreenshot_2026-07-06-20-11-09-191_com.pdf.reader

    @215900 回复 ⚑举报 

    赤霄
    游客

    整页

    Screenshot_2026-07-06-20-10-00-690_com.pdf.readerScreenshot_2026-07-06-20-10-05-032_com.pdf.reader

    @216148 回复 ⚑举报 

    赤霄
    游客

    v2.5

    优化实时预览

    优化翻页加载

    增加删除当前页

    增加导出蝶装小册子

    @216247 回复 ⚑举报 

    赤霄
    游客

    古籍数字拼合工具 用户手册

    欢迎使用古籍数字拼合工具!本工具专为古籍数字化修复与排版设计,基于“分合之道”哲学,将复杂的拼版操作化解为直观的交互,助您轻松完成筒子页拼接、整版切分、印刷配册等专业任务。

    ---

    一、功能概览

    · 双页拼接:将单页左右拼合为完整筒子页,自动处理中缝。
    · 滚动拼接:实现古籍书页连续滚动(如1-0、2-1…),用于拼接摊开扫描书籍。
    · 整版分单:将已拼接好的筒子页整版切分为左右单页。
    · 蝶装输出:按锁线精装配页规则(如1-16, 2-15…)生成小册子PDF。
    · 参数微调:支持每对页的独立位移、缩放、横缩、旋转,图像边距与画布边距全局控制。
    · 参考框线:可拖拽绘制红色虚线框,用于对齐标准版框。
    · 项目保存/加载:所有调整参数可保存为JSON文件,随时恢复工作状态。
    · 快捷键支持:键盘微调、翻页、缩放,提升效率。

    ---

    二、快速入门

    1. 启动程序

    双击 古籍拼合工具.exe,等待主界面出现。程序采用古风宣纸配色,左侧为控制面板,右侧为预览画布。

    2. 打开文件

    · 点击 打开 PDF 按钮,选择待处理的PDF文件。
    · 或点击 选择图片文件夹,载入一系列图片(按文件名排序)。
    · 加载成功后,预览区将显示第一对页面,并且会自动缩放至适合窗口大小。

    3. 基本查看

    · 翻页:使用 “◀ 上一对” / “下一对 ▶” 按钮,或按键盘 PageUp / PageDown。
    · 缩放画布:鼠标滚轮(以光标为中心缩放)。
    · 平移画布:在预览区按住鼠标右键并拖拽。
    · 恢复默认视图:右键单击预览区(非遮盖模式)即可将画布恢复至适合窗口大小。

    ---

    三、界面布局

    左侧控制面板从上至下依次为:

    1. 文件操作区:打开文件、当前控制页提示。
    2. 拼接模式:双拼页、整版分单、奇数页自动补白。
    3. 画布边距(全局):控制最终输出页面的四边留白或裁切(百分比,负值裁切)。
    4. 图像边距(当前对):控制当前这一对左右页自身的裁剪(百分比)。
    5. 变换参数(当前对):缩放、横缩(横向拉伸)、旋转角度,仅对当前页对生效。
    6. 中缝重叠:调节左右页向中线靠拢的程度,可设为全局默认。
    7. 参考框线:绘制红色虚线参考框。
    8. 保存 PDF:导出最终文件。
    9. 帮助:查看内置使用说明。
    10. 状态栏:显示当前操作反馈。

    ---

    四、详细操作指南

    4.1 切换控制页与拖拽移动

    · 切换控制侧:单击预览画布的左半区,控制页变为“左页”;单击右半区,控制页变为“右页”。当前控制页在状态标签中显示。
    · 拖拽移动页面:在画布上按住左键拖拽,可实时移动当前控制页。移动方向与鼠标拖拽方向一致(上拖即上移)。
    · 微调:选中左/右页后,使用键盘方向键进行1点步长的精细调节。

    4.2 缩放与视图控制

    · 缩放:鼠标滚轮向前放大,向后缩小。缩放中心始终跟随鼠标指针,便于查看细节。
    · 恢复视图:右键单击画布(非遮盖模式)即可重置缩放并居中显示全图。
    · 右键双击:快速将视图缩放至2倍或恢复至1倍。

    4.3 边距与变换参数调节

    · 画布边距(全局):四个输入框(左/右/上/下),单位%。正值=增加白边,负值=裁切画布。修改后预览实时更新。
    · 图像边距(当前对):同样四个输入框,单位%,控制当前页对中左、右页各自的裁剪量,不影响画布大小。例如,左页左边距设为20%,则左页左边20%的内容会被裁掉。
    · 缩放:分别调节左右页的显示比例,100%为原始大小。
    · 横缩:仅改变页面宽度,高度不变,用于校正版框倾斜或宽度不一致。
    · 旋转:顺时针为正,可任意角度(对当前页对生效)。

    注意:以上变换参数均仅对当前页对有效,切换页对后会自动加载该页对的设置。所有参数修改后都会实时预览,并且会自动保存到项目文件中。

    4.4 中缝重叠

    · 左右页中线附近可能会因扫描等原因造成接缝不齐。通过调节重叠百分比,可以让左页向右延伸、右页向左延伸,使中缝自然融合。
    · 点击 设为全局 可将当前值作为所有页对的默认重叠值,若某一页对单独调整过,则会覆盖全局值。要恢复全局值,只需将该对的数值改回与全局相同即可。

    4.5 参考框线

    · 勾选“启用”后,可在画布上拖拽绘制红色虚线矩形,松开后自动记录宽高及位置。
    · 可手动修改宽、高、水平偏移、垂直偏移数值,框线实时更新。
    · 锁定后不再响应拖拽,避免误触。

    4.6 删除页面

    点击 删除当前页 按钮,会删除当前控制侧对应的原始页面(从原始页面列表中移除)。删除后程序会重新配对,页码自动调整。此操作不可撤销,请谨慎使用。

    4.7 遮盖功能(暂未开放)

    遮盖功能用于修补页面上的污损区域,目前正在优化中,暂不可用。将在后续版本中提供。

    ---

    五、导出 PDF

    点击 保存 PDF 按钮,弹出保存对话框,您可以选择输出模式:

    · 拼接(左右合并):将左右页拼合为一张宽幅PDF,适合直接打印或阅读。
    · 分割(先右后左单页):输出为独立的单页PDF,右页在前,左页在后。常用于标准化单页处理。
    · 蝶装(错页拼合):按照古籍锁线精装的配页规则重新组合页面,生成适合装订的小册子。需输入每册页数(必须是4的倍数,默认16页)。程序会在原始页面前插入一页空白,然后按 (1,16),(15,2),(3,14),… 的规律配对,输出可直接打印并手工折页装订的PDF。

    导出进度条会显示当前处理进度,导出完成后弹出提示。导出过程中可以切换窗口或进行其他操作。

    ---

    六、快捷键一览

    操作 快捷键
    切换控制页 Tab
    微调当前页(上下左右) ↑ ↓ ← →
    上一对 Page Up
    下一对 Page Down
    缩放 鼠标滚轮
    恢复视图 右键单击画布
    放大/缩小至2倍 右键双击画布

    ---

    七、项目保存与加载

    在导出对话框中,您可以:

    · 保存项目:将所有拼接参数(位移、缩放、边距、重叠等)保存为 .json 文件,方便下次继续处理。
    · 加载项目:打开之前保存的 .json 文件,程序会自动恢复全部设置,包括原始页面列表、当前页码和所有调整参数。

    建议:每次处理完一部分页面后及时保存项目,以防意外退出丢失进度。

    ---

    八、常见问题

    Q:为什么打开某些PDF会卡顿?
    A:个别PDF可能包含损坏的压缩流,程序渲染时会尝试修复,可能导致短暂卡顿。请尝试用其他软件修复PDF后再打开。程序已针对大文件进行优化,通常1GB内的PDF都能流畅处理。

    Q:导出的PDF和预览不一样?
    A:请确保未修改全局画布边距或图像边距,导出时会应用所有当前参数。如有疑问,可先保存项目,再重新加载导出。

    Q:如何恢复默认设置?
    A:关闭程序,删除项目JSON文件,重新打开PDF即恢复初始状态。

    Q:蝶装导出后页码不对?
    A:请确认每册页数设置为4的倍数,并且原始页面总数适合分册。程序会在第一页插入空白页,因此页码会整体后移,这是锁线装订的正常流程。

    ---

    九、设计哲学

    本工具的核心思想源自“分合之道”:以分为法,以合为宗。通过对画布、图像、变换参数的巧妙分离,实现了在不修改原始像素的前提下,自由组合出各种阅读形态。更多理论阐述请见《分合之道:古籍数字拼合的本体论与方法论》文档。

    ---

    感谢您的使用!如有反馈或问题,欢迎联系。

    @216248 回复 ⚑举报 

    赤霄
    游客

    用户手册可在此处查看

    @216259 回复 ⚑举报 

    角徵宫商羽
    游客

    这款软件,选择图片文件夹,拼接画面怎么显示不出拼接图片,只显示拼接页数,还有就是100页以内拼接可以保存拼接文件,150页以上保存拼接文件软件就没有响应了

    @216273 回复 ⚑举报 

    赤霄
    游客

    @角徵宫商羽 #216259

    古籍单张图片都比较大,为了即时响应,我改成先读取显示对数,再预览第一对图像,这个我优化一下。

    150页以上的文件夹图像导出异常问题,我之前没遇到,这个我也优化一下。

    @216274 回复 ⚑举报 

    赤霄
    游客

    @角徵宫商羽 #216259

    没有响应是软件后台加载慢,我林前调整为异步加载+进度条显示,看来图像多的情况下还是要再优化线程。

    @216363 回复 ⚑举报 

    johnny
    游客

    这么好的软件,有没有mac系统的版本呢。非常期待。

    @216364 回复 ⚑举报 

    赤霄
    游客

    @johnny #216363

    没玩过mac系统,倒是在思考怎么移植到安卓。

    @216368 回复 ⚑举报 

    赤霄
    游客

    已有一个安卓合矩工具,没分享出来,个人还不是很满意。

    Screenshot_2026-07-13-11-39-30-457_com.android.browser

    随意找了张图像进行操作,效果图如下:

    corrected_right

    @216371 回复 ⚑举报 

    johnny
    游客

    mac os系统的用户不在少数,但是古籍这方面的工具还是太稀缺了

    @216372 回复 ⚑举报 

    赤霄
    游客

    @johnny #216371

    windows上打包不了mac版的app,不过我把上面这个工具优化一下,这是网页版的,不依赖系统。

    @216490 回复 ⚑举报 

    赤霄
    游客

    已通过异步加载多线程系统处理图像读取和存储问题,不过这个不是最终方案,暂时不打包分发,最终的解决方案为预处理成pdf,使用pdf拼接分割的同一套算法进行处理,优化算法结构,减少冗余。

正在查看 34 个帖子:1-34 (共 34 个帖子)
正在查看 34 个帖子:1-34 (共 34 个帖子)

上传图片

拖拽或点击选择图片(最多五张)

回复至:古籍拼合工具
您的信息:



发帖/回帖前,请了解相关版规

0,邮箱地址尽量真实有效,随意填写的可能会被系统误判为垃圾内容。
1,不要开书单。单个帖子尽量发布一种书籍需求。
2,在搜索不到相关主题的情况下,尽量发新帖(发帖标题最好带上书名)。不要在他人帖子中回复某种书籍需要。
3,发帖提问标题尽量简单明了。发帖内容不要太过简略,请对书籍内容、版本或作者作简要说明。
4,出版于1976年以后的资源需求或分享将会被清理删除。