Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
H
hh_ccs
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
贺阳
hh_ccs
Commits
4cd82dd3
提交
4cd82dd3
authored
10月 31, 2025
作者:
贺阳
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ai识别优化
上级
18e31d9e
显示空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
145 行增加
和
117 行删除
+145
-117
timer.xml
ccs_base/data/timer.xml
+1
-1
ai_image_edit_service.py
ccs_base/wizard/ai_image_edit_service.py
+12
-12
batch_get_pod_info_wizard.py
ccs_base/wizard/batch_get_pod_info_wizard.py
+76
-51
batch_get_pod_info_wizard_views.xml
ccs_base/wizard/batch_get_pod_info_wizard_views.xml
+3
-3
image-to-coordinate.py
ccs_base/wizard/image-to-coordinate.py
+50
-47
cleaned.pdf
ccs_base/wizard/output/cleaned.pdf
+0
-0
cleaned_page_1.png
ccs_base/wizard/output/cleaned_page_1.png
+0
-0
debug_page_1.png
ccs_base/wizard/output/debug_page_1.png
+0
-0
page_1.png
ccs_base/wizard/pdf_pages/page_1.png
+0
-0
page_2.png
ccs_base/wizard/pdf_pages/page_2.png
+0
-0
page_3.png
ccs_base/wizard/pdf_pages/page_3.png
+0
-0
cc_bl_view.xml
ccs_connect_tiktok/views/cc_bl_view.xml
+3
-3
没有找到文件。
ccs_base/data/timer.xml
浏览文件 @
4cd82dd3
...
...
@@ -22,7 +22,7 @@
<field
name=
'interval_type'
>
hours
</field>
<field
name=
"nextcall"
eval=
"(DateTime.now().replace(hour=0, minute=0) + timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S')"
/>
<field
name=
"numbercall"
>
-1
</field>
<field
name=
"active"
eval=
"
Tru
e"
/>
<field
name=
"active"
eval=
"
Fals
e"
/>
</record>
<!-- 清理向导生成的临时附件-->
...
...
ccs_base/wizard/ai_image_edit_service.py
浏览文件 @
4cd82dd3
...
...
@@ -43,18 +43,18 @@ class AIImageEditService:
# 构建坐标检测提示词(按照image-to-coordinate.py的格式)
prompt_text
=
f
"""(仅归一化坐标,严格 JSON)
你是一名版面定位助手。请在下图中定位并分别框出以下四个单词:AGN、UCLINK、LOGISITICS、LTD。
坐标系与输出要求:
- 图像尺寸:宽 {img_w} 像素,高 {img_h} 像素
。
- 原点位于图像左上角;x 向右增大,y 向下增大
。
- 为每个目标词返回它的最小外接矩形框,边界紧贴字形,不要添加额外边距
。
- 返回坐标为相对宽高的归一化浮点数,范围 [0,1],保留 4 位小数;保证 0 ≤ x1 < x2 ≤ 1,0 ≤ y1 < y2 ≤ 1
。
- 禁止任何图片预处理(裁剪、缩放、加边距、重采样);坐标必须对应原始图像
。
- 严格只输出下面的压缩的 JSON,不要附加解释或其他文本。
- JSON中不要出现不在实例中的参数,例如bbox_2d,确保bbox_norm中有且仅有x1,y1,x2,y2四个参
数。
输出 JSON 格式(示例为格式演示
,实际数值请识别后填充):"""
你是一名版面定位助手。请在下图中定位并分别框出以下四个单词:AGN、UCLINK、LOGISITICS、LTD。
坐标系与输出要求:
- 图像尺寸:宽 {img_w} 像素,高 {img_h} 像素。
- 原点位于图像左上角;x 向右增大,y 向下增大
。
- 为每个目标词返回它的最小外接矩形框,边界紧贴字形,不要添加额外边距
。
- 返回坐标为相对宽高的归一化浮点数,范围 [0,1],保留 4 位小数;保证 0 ≤ x1 < x2 ≤ 1,0 ≤ y1 < y2 ≤ 1
。
- 禁止任何图片预处理(裁剪、缩放、加边距、重采样);坐标必须对应原始图像
。
- 目标文字有可能因为被遮挡而无法被准确识别,那么请根据可见部分的位置进行定位
。
- 严格只输出下面的压缩的 JSON,不要附加解释或其他文本。
- JSON中不要出现不在实例中的参数,例如bbox_2d。确保bbox_norm中有且仅有x1,y1,x2,y2四个参数,且每个参数都是浮点数,范围[0,1],保留4位小
数。
输出 JSON 格式(严格按照示例的格式
,实际数值请识别后填充):"""
prompt_text
+=
'[{"text":"AGN","bbox_norm":{"x1":0.0000,"y1":0.0000,"x2":0.0000,"y2":0.0000}},{"text":"UCLINK","bbox_norm":{"x1":0.0000,"y1":0.0000,"x2":0.0000,"y2":0.0000}},{"text":"LOGISITICS","bbox_norm":{"x1":0.0000,"y1":0.0000,"x2":0.0000,"y2":0.0000}},{"text":"LTD","bbox_norm":{"x1":0.0000,"y1":0.0000,"x2":0.0000,"y2":0.0000}}]'
...
...
ccs_base/wizard/batch_get_pod_info_wizard.py
浏览文件 @
4cd82dd3
...
...
@@ -843,13 +843,14 @@ class BatchGetPodInfoWizard(models.TransientModel):
def
_process_pdf_with_ai_image_edit
(
self
,
pdf_data
,
bl_no
):
"""
使用AI图片编辑处理PDF:PDF转图片 -> AI抹除文字 -> 图片转回PDF
使用AI图片编辑处理PDF:PDF转图片 -> AI抹除文字 -> 图片转回PDF
(按照image-to-coordinate.py的逻辑)
:param pdf_data: PDF二进制数据
:param bl_no: 提单号(用于日志)
:return: 处理后的PDF二进制数据
"""
import
fitz
# PyMuPDF
import
base64
import
mimetypes
from
PIL
import
Image
import
time
...
...
@@ -861,83 +862,107 @@ class BatchGetPodInfoWizard(models.TransientModel):
# 打开PDF文档
pdf_document
=
fitz
.
open
(
stream
=
pdf_data
,
filetype
=
"pdf"
)
processed_
pages
=
[]
processed_
images
=
[]
# 存储处理后的PIL图片对象
total_pages
=
len
(
pdf_document
)
total_ai_time
=
0.0
# 累计AI总耗时
# 遍历每一页
_logger
.
info
(
f
"PDF总页数: {total_pages}"
)
# 遍历每一页(按照image-to-coordinate.py的逻辑)
for
page_num
in
range
(
total_pages
):
page_start_time
=
time
.
time
()
page
=
pdf_document
[
page_num
]
_logger
.
info
(
f
"正在处理第{page_num + 1}页"
)
# 将页面转换为图像,使用更高分辨率确保清晰度
mat
=
fitz
.
Matrix
(
3.0
,
3.0
)
# 进一步提高分辨率,从2.0提升到3.0
# 将页面转换为图像(按照image-to-coordinate.py的pdf_to_images函数,使用dpi=150)
dpi
=
150
mat
=
fitz
.
Matrix
(
dpi
/
72
,
dpi
/
72
)
pix
=
page
.
get_pixmap
(
matrix
=
mat
)
img_data
=
pix
.
tobytes
(
"png"
)
# 转换为base64
img_base64
=
base64
.
b64encode
(
img_data
)
.
decode
(
'utf-8'
)
# 使用AI编辑图片,移除指定文字
# 将pixmap转换为PIL Image对象
img_data
=
pix
.
tobytes
(
"png"
)
img
=
Image
.
open
(
io
.
BytesIO
(
img_data
))
# 获取图片尺寸(按照image-to-coordinate.py的逻辑)
img_w
,
img_h
=
img
.
size
_logger
.
info
(
f
"第{page_num + 1}页页面尺寸: {img_w}x{img_h} 像素"
)
# 将图片编码为base64(按照image-to-coordinate.py的encode_file函数逻辑)
img_bytes_io
=
io
.
BytesIO
()
img
.
save
(
img_bytes_io
,
format
=
'PNG'
)
img_bytes_io
.
seek
(
0
)
encoded_string
=
base64
.
b64encode
(
img_bytes_io
.
read
())
.
decode
(
'utf-8'
)
mime_type
=
'image/png'
img_base64
=
f
"data:{mime_type};base64,{encoded_string}"
# 使用AI编辑图片,移除指定文字(带重试机制)
edited_img_base64
=
None
ai_processing_time
=
0.0
max_retries
=
2
# 最多尝试2次(首次+1次重试)
for
attempt
in
range
(
1
,
max_retries
+
1
):
ai_start_time
=
time
.
time
()
edited_img_base64
=
ai_service
.
edit_image_remove_text
(
img_base64
,
try
:
# 调用AI服务(使用base64编码的图片数据,不带data:前缀)
edited_img_base64_raw
=
ai_service
.
edit_image_remove_text
(
encoded_string
,
# 传入不带data:前缀的base64字符串
text_to_remove
=
"AGN UCLINK LOGISITICS LTD"
)
ai_end_time
=
time
.
time
()
ai_processing_time
=
ai_end_time
-
ai_start_time
total_ai_time
+=
ai_processing_time
# 累计AI耗时
attempt_time
=
ai_end_time
-
ai_start_time
ai_processing_time
+=
attempt_time
# 累计AI耗时
total_ai_time
+=
attempt_time
# 累计总AI耗时
if
edited_img_base64_raw
:
edited_img_base64
=
edited_img_base64_raw
_logger
.
info
(
f
"第{page_num + 1}页AI处理成功(第{attempt}次尝试),耗时: {attempt_time:.2f}秒"
)
break
else
:
if
attempt
<
max_retries
:
_logger
.
warning
(
f
"第{page_num + 1}页AI处理失败(第{attempt}次尝试),将重试,耗时: {attempt_time:.2f}秒"
)
else
:
_logger
.
warning
(
f
"第{page_num + 1}页AI处理失败(第{attempt}次尝试,已用尽重试),耗时: {attempt_time:.2f}秒"
)
except
Exception
as
e
:
ai_end_time
=
time
.
time
()
attempt_time
=
ai_end_time
-
ai_start_time
ai_processing_time
+=
attempt_time
total_ai_time
+=
attempt_time
_logger
.
error
(
f
"第{page_num + 1}页AI处理异常(第{attempt}次尝试): {str(e)},耗时: {attempt_time:.2f}秒"
)
if
attempt
<
max_retries
:
_logger
.
info
(
f
"第{page_num + 1}页将进行第{attempt + 1}次重试"
)
edited_img_base64
=
None
if
edited_img_base64
:
# 解码base64图片数据
# 解码base64图片数据
并转换为PIL Image对象(按照image-to-coordinate.py的逻辑)
edited_img_data
=
base64
.
b64decode
(
edited_img_base64
)
# 保存处理后的图片数据
processed_pages
.
append
({
'img_data'
:
edited_img_data
,
'is_edited'
:
True
})
_logger
.
info
(
f
"第{page_num + 1}页AI处理成功,耗时: {ai_processing_time:.2f}秒"
)
edited_img
=
Image
.
open
(
io
.
BytesIO
(
edited_img_data
))
.
convert
(
'RGB'
)
processed_images
.
append
(
edited_img
)
_logger
.
info
(
f
"第{page_num + 1}页AI处理最终成功,总耗时: {ai_processing_time:.2f}秒"
)
else
:
_logger
.
warning
(
f
"第{page_num + 1}页AI处理
失败,使用原始页面,
耗时: {ai_processing_time:.2f}秒"
)
_logger
.
warning
(
f
"第{page_num + 1}页AI处理
最终失败(已重试),使用原始页面,总
耗时: {ai_processing_time:.2f}秒"
)
# 如果AI处理失败,使用原始图片
processed_pages
.
append
({
'img_data'
:
img_data
,
'is_edited'
:
False
})
processed_images
.
append
(
img
.
convert
(
'RGB'
))
page_end_time
=
time
.
time
()
page_processing_time
=
page_end_time
-
page_start_time
_logger
.
info
(
f
"第{page_num + 1}页总处理时间: {page_processing_time:.2f}秒"
)
# 创建新的PDF文档
pdf_creation_start
=
time
.
time
()
output_doc
=
fitz
.
open
()
for
page_info
in
processed_pages
:
img_data
=
page_info
[
'img_data'
]
is_edited
=
page_info
[
'is_edited'
]
# 将图片加载到内存
img_bytes_io
=
io
.
BytesIO
(
img_data
)
img
=
Image
.
open
(
img_bytes_io
)
# 创建新页面
page
=
output_doc
.
new_page
(
width
=
img
.
width
,
height
=
img
.
height
)
pdf_document
.
close
()
# 将图片插入PDF页面
page
.
insert_image
(
fitz
.
Rect
(
0
,
0
,
img
.
width
,
img
.
height
),
stream
=
img_data
,
)
# 将处理后的图片转换为PDF(按照image-to-coordinate.py的images_to_pdf函数逻辑)
pdf_creation_start
=
time
.
time
()
if
not
processed_images
:
_logger
.
error
(
"没有需要写入PDF的图片"
)
return
None
#
保存处理后的PDF
#
使用PIL的save方法将图片保存为PDF(按照image-to-coordinate.py的逻辑)
output_buffer
=
io
.
BytesIO
()
output_doc
.
save
(
output_buffer
,
garbage
=
4
,
deflate
=
True
)
output_doc
.
close
()
pdf_document
.
close
()
first
=
processed_images
[
0
]
rest
=
processed_images
[
1
:]
# 按照image-to-coordinate.py的逻辑,直接使用切片
# 按照image-to-coordinate.py的images_to_pdf函数:first.save(output_pdf, save_all=True, append_images=rest)
# 即使rest是空列表,也直接传入(PIL会正确处理)
first
.
save
(
output_buffer
,
format
=
'PDF'
,
save_all
=
True
,
append_images
=
rest
)
output_buffer
.
seek
(
0
)
pdf_creation_end
=
time
.
time
()
result_data
=
output_buffer
.
getvalue
()
...
...
ccs_base/wizard/batch_get_pod_info_wizard_views.xml
浏览文件 @
4cd82dd3
...
...
@@ -11,8 +11,8 @@
<sheet>
<!-- <group> -->
<group>
<
field
name=
"remove_specified_text"
readonly=
"1"
widget=
"boolean_toggle"
attrs=
"{'invisible': [('pdf_file', '!=', False)]}
"
/>
<
!-- attrs="{'invisible': [('pdf_file', '!=', False)]}" -->
<field
name=
"remove_specified_text"
readonly=
"1"
widget=
"boolean_toggle
"
/>
<field
name=
"skip_ocr_direct_ai"
readonly=
"0"
widget=
"boolean_toggle"
attrs=
"{'invisible': [('pdf_file', '!=', False)]}"
/>
</group>
...
...
@@ -30,7 +30,7 @@
<div
class=
"alert alert-info"
role=
"alert"
>
<strong>
Description:
</strong>
<!-- 说明: -->
<ul>
<li
attrs=
"{'invisible': [('pdf_file', '!=', False)]}"
>
<li>
<strong>
Remove Specified Text:
</strong>
Remove specified text (AGN, UCLINK LOGISITICS LTD) from PDF files
</li>
<!-- 涂抹指定文字:对PDF文件中的指定文字进行涂抹处理 -->
...
...
ccs_base/wizard/image-to-coordinate.py
浏览文件 @
4cd82dd3
...
...
@@ -16,7 +16,7 @@ client = OpenAI(
base_url
=
"https://dashscope.aliyuncs.com/compatible-mode/v1"
,
)
pdf_path
=
"
C:/Users/Administrator/Desktop/43610281036
.pdf"
pdf_path
=
"
./43610236590 (3)
.pdf"
def
pdf_to_images
(
pdf_path
,
output_dir
=
'./pdf_pages'
,
dpi
=
150
):
"""
...
...
@@ -28,7 +28,9 @@ def pdf_to_images(pdf_path, output_dir='./pdf_pages', dpi=150):
"""
os
.
makedirs
(
output_dir
,
exist_ok
=
True
)
doc
=
fitz
.
open
(
pdf_path
)
image_paths
=
[]
print
(
f
"PDF总页数: {len(doc)}"
)
for
page_num
in
range
(
len
(
doc
)):
page
=
doc
.
load_page
(
page_num
)
mat
=
fitz
.
Matrix
(
dpi
/
72
,
dpi
/
72
)
...
...
@@ -60,12 +62,6 @@ def encode_file(file_path):
encoded_string
=
base64
.
b64encode
(
image_file
.
read
())
.
decode
(
'utf-8'
)
return
f
"data:{mime_type};base64,{encoded_string}"
image_paths
=
pdf_to_images
(
pdf_path
)
image_base64
=
encode_file
(
image_paths
[
0
])
# 获取图片分辨率,并在提示中要求模型按比例(相对宽高的0-1浮点数)返回坐标
img_w
,
img_h
=
Image
.
open
(
image_paths
[
0
])
.
size
print
(
f
"页面尺寸: {img_w}x{img_h} 像素"
)
def
safe_extract_json
(
text
:
str
):
"""从模型返回文本中尽可能鲁棒地提取JSON对象。"""
# 直接尝试解析
...
...
@@ -268,25 +264,35 @@ def images_to_pdf(image_paths, output_pdf):
first
.
save
(
output_pdf
,
save_all
=
True
,
append_images
=
rest
)
print
(
f
"已生成PDF: {output_pdf}"
)
text
=
f
"""(仅归一化坐标,严格 JSON)
你是一名版面定位助手。请在下图中定位并分别框出以下四个单词:AGN、UCLINK、LOGISITICS、LTD。
坐标系与输出要求:
image_paths
=
pdf_to_images
(
pdf_path
)
final_images
=
[]
location_map
=
''
for
index
,
image_path
in
enumerate
(
image_paths
):
image_base64
=
encode_file
(
image_path
)
# 获取图片分辨率,并在提示中要求模型按比例(相对宽高的0-1浮点数)返回坐标
img_w
,
img_h
=
Image
.
open
(
image_path
)
.
size
print
(
f
"页面尺寸: {img_w}x{img_h} 像素"
)
- 图像尺寸:宽 {img_w} 像素,高 {img_h} 像素。
- 原点位于图像左上角;x 向右增大,y 向下增大。
- 为每个目标词返回它的最小外接矩形框,边界紧贴字形,不要添加额外边距。
- 返回坐标为相对宽高的归一化浮点数,范围 [0,1],保留 4 位小数;保证 0 ≤ x1 < x2 ≤ 1,0 ≤ y1 < y2 ≤ 1。
- 禁止任何图片预处理(裁剪、缩放、加边距、重采样);坐标必须对应原始图像。
- 严格只输出下面的压缩的 JSON,不要附加解释或其他文本。
- JSON中不要出现不在实例中的参数,例如bbox_2d,确保bbox_norm中有且仅有x1,y1,x2,y2四个参数。
输出 JSON 格式(示例为格式演示,实际数值请识别后填充):"""
text
=
f
"""(仅归一化坐标,严格 JSON)
你是一名版面定位助手。请在下图中定位并分别框出以下四个单词:AGN、UCLINK、LOGISITICS、LTD。
坐标系与输出要求:
text
+=
'[{"text":"AGN","bbox_norm":{"x1":0.0000,"y1":0.0000,"x2":0.0000,"y2":0.0000}},{"text":"UCLINK","bbox_norm":{"x1":0.0000,"y1":0.0000,"x2":0.0000,"y2":0.0000}},{"text":"LOGISITICS","bbox_norm":{"x1":0.0000,"y1":0.0000,"x2":0.0000,"y2":0.0000}},{"text":"LTD","bbox_norm":{"x1":0.0000,"y1":0.0000,"x2":0.0000,"y2":0.0000}}]'
- 图像尺寸:宽 {img_w} 像素,高 {img_h} 像素。
- 原点位于图像左上角;x 向右增大,y 向下增大。
- 为每个目标词返回它的最小外接矩形框,边界紧贴字形,不要添加额外边距。
- 返回坐标为相对宽高的归一化浮点数,范围 [0,1],保留 4 位小数;保证 0 ≤ x1 < x2 ≤ 1,0 ≤ y1 < y2 ≤ 1。
- 禁止任何图片预处理(裁剪、缩放、加边距、重采样);坐标必须对应原始图像。
- 目标文字有可能因为被遮挡而无法被准确识别,那么请根据可见部分的位置进行定位。
- 严格只输出下面的压缩的 JSON,不要附加解释或其他文本。
- JSON中不要出现不在实例中的参数,例如bbox_2d。确保bbox_norm中有且仅有x1,y1,x2,y2四个参数,且每个参数都是浮点数,范围[0,1],保留4位小数。
输出 JSON 格式(严格按照示例的格式):"""
# 记录AI处理开始时间
ai_start_time
=
time
.
time
()
completion
=
client
.
chat
.
completions
.
create
(
text
+=
'[{"text":"AGN","bbox_norm":{"x1":0.0000,"y1":0.0000,"x2":0.0000,"y2":0.0000}},{"text":"UCLINK","bbox_norm":{"x1":0.0000,"y1":0.0000,"x2":0.0000,"y2":0.0000}},{"text":"LOGISITICS","bbox_norm":{"x1":0.0000,"y1":0.0000,"x2":0.0000,"y2":0.0000}},{"text":"LTD","bbox_norm":{"x1":0.0000,"y1":0.0000,"x2":0.0000,"y2":0.0000}}]'
completion
=
client
.
chat
.
completions
.
create
(
model
=
"qwen3-vl-plus"
,
# 此处以qwen3-vl-plus为例,可按需更换模型名称。模型列表:https://help.aliyun.com/zh/model-studio/models
messages
=
[
{
...
...
@@ -303,34 +309,31 @@ completion = client.chat.completions.create(
},
],
temperature
=
0.1
,
)
# 记录AI处理结束时间
ai_end_time
=
time
.
time
()
ai_processing_time
=
ai_end_time
-
ai_start_time
raw_text
=
completion
.
choices
[
0
]
.
message
.
content
# raw_text = '```json[{"bbox_norm": {"x1": 0.1028, "y1": 0.1934, "x2": 0.1325, "y2": 0.2006}, "text": "AGN", "occurrence_index": 0},{"bbox_norm": {"x1": 0.1028, "y1": 0.2057, "x2": 0.1608, "y2": 0.2165}, "text": "UCLINK", "occurrence_index": 0},{"bbox_norm": {"x1": 0.1677, "y1": 0.2057, "x2": 0.2657, "y2": 0.2165}, "text": "LOGISITICS", "occurrence_index": 0},{"bbox_norm": {"x1": 0.2726, "y1": 0.2057, "x2": 0.3023, "y2": 0.2165}, "text": "LTD", "occurrence_index": 0}]```'
print
(
raw_text
)
result
=
safe_extract_json
(
raw_text
)
if
result
is
None
or
not
isinstance
(
result
,
dict
):
)
raw_text
=
completion
.
choices
[
0
]
.
message
.
content
# raw_text = '```json[{"bbox_norm": {"x1": 0.1028, "y1": 0.1934, "x2": 0.1325, "y2": 0.2006}, "text": "AGN", "occurrence_index": 0},{"bbox_norm": {"x1": 0.1028, "y1": 0.2057, "x2": 0.1608, "y2": 0.2165}, "text": "UCLINK", "occurrence_index": 0},{"bbox_norm": {"x1": 0.1677, "y1": 0.2057, "x2": 0.2657, "y2": 0.2165}, "text": "LOGISITICS", "occurrence_index": 0},{"bbox_norm": {"x1": 0.2726, "y1": 0.2057, "x2": 0.3023, "y2": 0.2165}, "text": "LTD", "occurrence_index": 0}]```'
print
(
raw_text
)
result
=
safe_extract_json
(
raw_text
)
if
not
location_map
:
location_map
=
json
.
dumps
(
result
[
'rects'
],
ensure_ascii
=
False
)
if
result
is
None
or
not
isinstance
(
result
,
dict
):
raise
RuntimeError
(
"模型返回内容无法解析为JSON坐标,请检查返回格式。"
)
# 只处理第一页:将抹除后的图片写入 output/cleaned_page_1.png,然后重新生成PDF
cleaned_dir
=
os
.
path
.
join
(
"./output"
)
cleaned_first
=
os
.
path
.
join
(
cleaned_dir
,
"cleaned_page_1
.png"
)
debug_first
=
os
.
path
.
join
(
cleaned_dir
,
"debug_page_1
.png"
)
coords_map
=
convert_ai_json_to_coords_map
(
result
,
img_w
,
img_h
)
if
not
coords_map
:
# 只处理第一页:将抹除后的图片写入 output/cleaned_page_1.png,然后重新生成PDF
cleaned_dir
=
os
.
path
.
join
(
"./output"
)
cleaned_first
=
os
.
path
.
join
(
cleaned_dir
,
f
"cleaned_page_{index}
.png"
)
debug_first
=
os
.
path
.
join
(
cleaned_dir
,
f
"debug_page_{index}
.png"
)
coords_map
=
convert_ai_json_to_coords_map
(
result
,
img_w
,
img_h
)
if
not
coords_map
:
raise
RuntimeError
(
"无法从AI返回中提取矩形框坐标,请检查输出格式或提示词。"
)
print
(
f
"解析并统一后的坐标字典: {coords_map}"
)
draw_debug_boxes
(
image_paths
[
0
]
,
coords_map
,
debug_first
)
erase_regions_on_image
(
image_paths
[
0
]
,
coords_map
,
cleaned_first
)
print
(
f
"解析并统一后的坐标字典: {coords_map}"
)
draw_debug_boxes
(
image_path
,
coords_map
,
debug_first
)
erase_regions_on_image
(
image_path
,
coords_map
,
cleaned_first
)
# 合成PDF:第一页使用清理后的图片,其余页沿用原图
final_images
=
[
cleaned_first
]
+
image_paths
[
1
:]
images_to_pdf
(
final_images
,
os
.
path
.
join
(
cleaned_dir
,
"cleaned
.pdf"
))
# 合成PDF:第一页使用清理后的图片,其余页沿用原图
final_images
.
append
(
cleaned_first
)
images_to_pdf
(
final_images
,
os
.
path
.
join
(
cleaned_dir
,
f
"cleaned_page
.pdf"
))
end_time
=
time
.
time
()
total_time
=
end_time
-
begin_time
print
(
f
"总耗时: {total_time:.2f} 秒"
)
print
(
f
"AI处理耗时: {ai_processing_time:.2f} 秒(AI API调用时间)"
)
print
(
f
"耗时: {end_time - begin_time} 秒"
)
ccs_base/wizard/output/cleaned.pdf
deleted
100644 → 0
浏览文件 @
18e31d9e
File deleted
ccs_base/wizard/output/cleaned_page_1.png
deleted
100644 → 0
浏览文件 @
18e31d9e
171.4 KB
ccs_base/wizard/output/debug_page_1.png
deleted
100644 → 0
浏览文件 @
18e31d9e
176.5 KB
ccs_base/wizard/pdf_pages/page_1.png
deleted
100644 → 0
浏览文件 @
18e31d9e
124.7 KB
ccs_base/wizard/pdf_pages/page_2.png
deleted
100644 → 0
浏览文件 @
18e31d9e
151.5 KB
ccs_base/wizard/pdf_pages/page_3.png
deleted
100644 → 0
浏览文件 @
18e31d9e
167.9 KB
ccs_connect_tiktok/views/cc_bl_view.xml
浏览文件 @
4cd82dd3
...
...
@@ -53,6 +53,9 @@
</div>
</button>
</button>
<field
name=
"process_time"
position=
"after"
>
<field
name=
"push_remark"
readonly=
"1"
attrs=
"{'invisible': [('push_remark', '=', '')]}"
/>
</field>
<notebook
position=
"inside"
>
<page
string=
"Sync Log"
>
<field
name=
"bl_sync_log_ids"
widget=
"one2many_list"
/>
...
...
@@ -60,9 +63,6 @@
<field
name=
"is_bl_sync"
string=
"Is Sync"
readonly=
"1"
/>
<field
name=
"state_explain"
string=
"State Explain"
/>
</group>
<group
attrs=
"{'invisible': [('push_remark', '=', '')]}"
>
<field
name=
"push_remark"
readonly=
"1"
/>
</group>
</page>
</notebook>
</field>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论