吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2156|回复: 33
收起左侧

[Python 原创] OCR图片英汉翻译工具及源码

[复制链接]
pythonfun 发表于 2025-11-3 14:41
本帖最后由 pythonfun 于 2025-11-3 14:50 编辑

一、软件名称:OCR图片识别翻译工具

二、软件简介:
本软件主要解决用户在阅读外文图片、截图或界面文字时遇到的语言障碍痛点。通过智能OCR文字识别和精准翻译技术,实现一键截图翻译,大幅提升跨语言阅读效率,让语言不再成为信息获取的障碍。

三、软件功能
本软件是一款基于AI技术的智能OCR识别翻译工具,主要功能包括:
1. 智能区域截图:支持自定义框选截图区域,精准捕获需要翻译的内容
2. AI文字识别:采用先进的AI OCR技术,准确提取图片中的文字信息
3. 智能翻译引擎:集成小牛翻译API,支持英汉互译
4. 自动语言检测:智能识别原文语种,自动选择翻译方向
5. 结果展示窗口:提供独立的悬浮窗口显示识别和翻译结果
6. 文本复制功能:支持一键复制原文和译文到剪贴板
7. 字体缩放:提供文本放大显示功能,便于阅读长文本内容

四、使用方法和操作步骤:
1. 运行程序后,桌面会出现一个悬浮翻译窗口
2. 按下快捷键 Ctrl+Alt+A 激活截图功能,或者点界面上的截图键开始截图
3. 用鼠标框选需要识别翻译的屏幕区域
4. 程序自动识别区域内的文字并显示"识别中..."提示
5. 识别完成后自动进行翻译并显示"翻译中..."提示
6. 在悬浮窗口中同时显示原文和译文结果
7. 可点击"复制"按钮将内容复制到剪贴板

五、运行环境
系统要求:Windows操作系统
Python环境:需要安装相关依赖库(PIL、tkinter、keyboard、mss等)
运行方式:直接运行Python脚本

六、技术特点说明
1. OCR识别技术:
   - 主方案:基于智谱AI的GLM-4V视觉模型,准确率高
   - 备用方案:集成Tesseract OCR引擎,确保服务稳定性
   - 精准提取:严格保持原文内容,不增删改写

2. 翻译服务:
   - 翻译引擎:小牛翻译API,专业翻译服务
   - 语言支持:支持中英文互译,可扩展其他语言
   - 自动检测:智能判断原文语种,自动选择翻译方向

3. 截图技术:
   - 使用mss库进行高效屏幕捕获
   - 支持高DPI屏幕显示
   - 区域选择精准,操作流畅

七、特色亮点
操作便捷:快捷键一键触发,简单易用
识别准确:AI OCR技术,文字识别精度高
翻译专业:专业翻译引擎,译文质量可靠
实时显示:独立悬浮窗口,结果展示清晰
双重保障:主备OCR方案,确保服务稳定
界面美观:深色主题设计,视觉效果舒适
代码开源:可自定义修改,满足个性化需求

八、注意事项
1. 使用前请确保网络连接正常,OCR和翻译服务需要联网
2. 首次使用可能需要配置相关API密钥
3. 截图时请确保目标区域文字清晰可见
4. 对于特殊字体或复杂背景的图片,识别准确率可能受影响
5. 本工具仅适用于一般图片翻译,专业领域翻译建议人工校对

九、界面展示
image.png
十、源码展示
[Python] 纯文本查看 复制代码
import os
import tkinter as tk
from urllib import parse, request
import json
import keyboard  # 监听快捷键
import base64
from io import BytesIO
from zai import ZhipuAiClient  # 取消注释
import ctypes
import mss
import mss.tools
from PIL import Image

# ================== 小牛翻译 ==================
apikey = "d99fc0600b16efa6e310f53579593c57"

def niutrans_translate(sentence, src_lan="auto", tgt_lan="zh"):
    try:
        url = 'http://api.niutrans.com/NiuTransServer/translation?'
        data = {"from": src_lan, "to": tgt_lan, "apikey": apikey, "src_text": sentence}
        data_en = parse.urlencode(data)
        req = url + "&" + data_en
        res = request.urlopen(req, timeout=5)
        res_dict = json.loads(res.read())
        if "tgt_text" in res_dict:
            return res_dict['tgt_text']
        else:
            return f"翻译失败: {res_dict}"
    except Exception as e:
        return f"翻译接口错误: {str(e)}"

# ================== 框选截图区域 ==================
def select_area():
    # 预初始化Tkinter,避免第一次创建窗口时的跳动
    root = tk.Tk()
    root.withdraw()  # 隐藏预初始化窗口
    root.update_idletasks()
    
    # 创建实际的全屏窗口
    root = tk.Tk()
    root.attributes("-fullscreen", True)
    root.attributes("-alpha", 0.3)
    # 设置窗口位置确保不会影响主界面
    root.geometry("0x0+0+0")
    root.update_idletasks()
    
    canvas = tk.Canvas(root, cursor="cross")
    canvas.pack(fill="both", expand=True)

    rect = None
    start_x = start_y = 0
    area = [0, 0, 0, 0]

    # 设置DPI感知
    try:
        ctypes.windll.user32.SetProcessDPIAware()
    except:
        pass

    def on_mouse_down(event):
        nonlocal start_x, start_y, rect
        start_x, start_y = event.x, event.y
        rect = canvas.create_rectangle(start_x, start_y, start_x, start_y, outline="red", width=3)

    def on_mouse_move(event):
        nonlocal rect
        if rect:
            canvas.coords(rect, start_x, start_y, event.x, event.y)

    def on_mouse_up(event):
        nonlocal area
        x1, y1, x2, y2 = start_x, start_y, event.x, event.y
        
        # 直接使用坐标,不进行缩放转换
        # MSS会自动处理DPI缩放
        area = [int(min(x1, x2)), int(min(y1, y2)),
                int(max(x1, x2)), int(max(y1, y2))]
        
        #print(f"Selected area: {area}")
        root.withdraw()
        root.quit()

    canvas.bind("<ButtonPress-1>", on_mouse_down)
    canvas.bind("<B1-Motion>", on_mouse_move)
    canvas.bind("<ButtonRelease-1>", on_mouse_up)

    root.mainloop()
    root.destroy()
    return tuple(area)

def capture_region(region):
    """用 mss 按区域截图,返回 PIL.Image"""
    with mss.mss() as sct:
        # 确保区域坐标正确
        left, top, right, bottom = region
        width = max(1, right - left)
        height = max(1, bottom - top)
        
        monitor = {
            "top": top, 
            "left": left,
            "width": width,
            "height": height
        }
        
        #print(f"Capturing region: {monitor}")
        sct_img = sct.grab(monitor)
        
        # 保存截图用于调试
        #mss.tools.to_png(sct_img.rgb, sct_img.size, output="debug_mss_screenshot.png")
        #print("MSS screenshot saved as debug_mss_screenshot.png")
        
        return Image.frombytes("RGB", sct_img.size, sct_img.bgra, "raw", "BGRX")

# ================== 主应用 ==================
class TranslationApp:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("OCR翻译器")
        self.root.overrideredirect(False)
        self.root.attributes('-topmost', True)
        self.root.geometry("400x200")
        self.font_size = 12
        self.is_zoomed = False
        self.frame = tk.Frame(self.root, bg='#2C3E50')
        self.frame.pack(padx=5, pady=5, fill="both", expand=True)

        self.label = tk.Label(self.frame, text="按 Ctrl+Alt+A 截图翻译",
                              font=('微软雅黑', 12),
                              bg='#2C3E50', fg='#ECF0F1',
                              wraplength=400, justify='left',
                              padx=10, pady=5)
        self.label.pack(fill="both", expand=True)

        self.running = True
        self.last_text = ""

        self.setup_ui()

        # 注册截图快捷键
        keyboard.add_hotkey("ctrl+alt+a", self.capture_and_translate)

    def translate_text(self, text):
        is_chinese = any('\u4e00' <= c <= '\u9fa5' for c in text)
        from_lang = "zh" if is_chinese else "en"
        to_lang = "en" if is_chinese else "zh"
        return niutrans_translate(text, from_lang, to_lang)

    def process_image_with_ai(self, pil_image):
        # 把 PIL 图片转为 base64
        buffered = BytesIO()
        pil_image.save(buffered, format="JPEG")
        encoded_string = base64.b64encode(buffered.getvalue()).decode('utf-8')

        try:
            client = ZhipuAiClient(api_key="101fb0dca2d148cc937a73dc61f73368.HfIMCncTJPNibjYl")

            response = client.chat.completions.create(
                model="glm-4.1v-thinking-flash",
                messages=[{
                    "role": "user",
                    "content": [
                        {
                            "type": "image_url",
                            "image_url": {
                                "url": f"data:image/jpeg;base64,{encoded_string}"
                            }
                        },
                        {
                            "type": "text",
                            "text": "请准确提取图片中的文字信息,不增加、删除或改写其它文本内容。"
                        }
                    ]
                }]
            )

            content = response.choices[0].message.content
            if content:
                content = content.replace("<|begin_of_box|>", "").replace("<|end_of_box|>", "")
                return content
            else:
                return "未识别到文字"
                
        except Exception as e:
            print(f"AI OCR错误: {str(e)}")
            # 如果AI OCR失败,尝试使用Tesseract作为备用方案
            return self.fallback_ocr(pil_image)

    def fallback_ocr(self, pil_image):
        """备用OCR方案(如果AI OCR失败)"""
        try:
            import pytesseract
            # 如果安装了Tesseract
            text = pytesseract.image_to_string(pil_image, lang='chi_sim+eng')
            return text.strip() if text.strip() else "未识别到文字(备用OCR)"
        except:
            return "OCR服务不可用,请检查网络连接或AI密钥"

    def capture_and_translate(self):
        try:
            #print("开始截图...")
            # 选择截图区域
            region = select_area()
            #print(f"选择的区域: {region}")
            
            if region[0] == region[2] or region[1] == region[3]:
                self.update_display("无效的截图区域")
                return

            # 使用 mss 截图
            screenshot = capture_region(region)

            # 保存截图用于调试
            #screenshot.save("debug_pil_screenshot.png")
            #print("PIL screenshot saved as debug_pil_screenshot.png")

            # 显示"识别中..."提示
            self.update_display("识别中...")

            # 调用 AI OCR,直接传 PIL.Image
            text = self.process_image_with_ai(screenshot).strip()
            #print(f"识别结果: {text}")

            if text and text != "未识别到文字":
                self.last_text = text
                # 显示"翻译中..."提示
                self.update_display(f"原文: {text}\n翻译中...")
                
                # 翻译文本
                translation = self.translate_text(text)
                #print(f"翻译结果: {translation}")
                
                self.update_display(f"原文: {text}\n\n译文: {translation}")
            else:
                self.update_display("未识别到文字")
                
        except Exception as e:
            import traceback
            error_msg = f"错误: {str(e)}\n{traceback.format_exc()}"
            print(error_msg)
            self.update_display(f"处理错误:\n{str(e)}")

    def update_display(self, text):
        self.label.config(text=text)
        self.root.update_idletasks()
    def copy_to_clipboard(self):
        """复制原文和译文到剪贴板"""
        if self.last_text:
            try:
                # 获取当前显示的文本
                current_text = self.label.cget("text")
                self.root.clipboard_clear()
                self.root.clipboard_append(current_text)
                # 临时显示复制成功提示
                original_text = self.label.cget("text")
                self.label.config(text="已复制到剪贴板!")
                self.root.after(1500, lambda: self.label.config(text=original_text))
            except Exception as e:
                print(f"复制失败: {e}")

    def zoom_text(self):
        """放大/恢复文本字体"""
        if not self.is_zoomed:
            # 放大字体
            self.font_size = 16
            self.label.config(font=('微软雅黑', self.font_size, 'bold'))
            self.is_zoomed = True
        else:
            # 恢复原字体
            self.font_size = 12
            self.label.config(font=('微软雅黑', self.font_size))
            self.is_zoomed = False
    def setup_ui(self):
        control_frame = tk.Frame(self.frame, bg='#2C3E50')
        control_frame.pack(fill='x', pady=(5,0))
        
        # 左上角放大按钮
        zoom_btn = tk.Button(control_frame, text="放大",
                            command=self.zoom_text,
                            bg='#27AE60', fg='white', relief='flat', width=6, font=(10))
        zoom_btn.pack(side='left', padx=2)
        
        # 左下角截图按钮
        capture_btn = tk.Button(control_frame, text="截图",
                               command=self.capture_and_translate,
                               bg='#3498DB', fg='white', relief='flat', width=6, font=(10))
        capture_btn.pack(side='left', padx=2)
    
        exit_btn = tk.Button(control_frame, text="退出",
                             command=self.exit_app,
                             bg='#E74C3C', fg='white', relief='flat', width=6, font=(10))
        exit_btn.pack(side='right', padx=2)


        # 右上角复制按钮
        copy_btn = tk.Button(control_frame, text="复制",
                            command=self.copy_to_clipboard,
                            bg='#9B59B6', fg='white', relief='flat', width=6, font=(10))
        copy_btn.pack(side='right', padx=2)
        
        
        # 快捷键退出
        self.root.bind("<Control-Shift-Q>", lambda e: self.exit_app())

    def exit_app(self):
        self.running = False
        self.root.destroy()

    def run(self):
        self.root.mainloop()

if __name__ == "__main__":
    app = TranslationApp()
    app.run()

十一、源码软件下载
源码下载:
截图翻译源码.zip (4.03 KB, 下载次数: 104)
打包后的工具下载
链接: https://pan.baidu.com/s/1Tl43xRvbq4ANXmlLmK6XDA?pwd=83fh 提取码: 83fh

ocr识别翻译

ocr识别翻译

免费评分

参与人数 3吾爱币 +8 热心值 +3 收起 理由
13719223600 + 1 我很赞同!
hrh123 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
lihao890320 + 1 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

bachelor66 发表于 2025-11-3 17:09
非常实用啊,感谢楼主的分享,有时候用用确实方便                  
慵懒丶L先森 发表于 2025-11-4 00:47
刚在一篇帖子看到一款语音识别成文字本地运行和AI纠错的,需要再找一个离线本地翻译支持OCR的,可惜这个需要联网,还是感谢分享
lihao890320 发表于 2025-11-3 14:55
 楼主| pythonfun 发表于 2025-11-3 14:56
lihao890320 发表于 2025-11-3 14:55
只接入了小牛翻译的API吗

还接入了智谱的api进行识别,源码里面保留的有api,你也可以直接用。
DukeChan 发表于 2025-11-3 15:10
非常有帮助,已经使用,感谢分享!
sai609 发表于 2025-11-3 16:13
做成qq浏览器插件最好,打开外文网站,全网页内容自动翻译为中文,如此甚好
 楼主| pythonfun 发表于 2025-11-3 16:23
sai609 发表于 2025-11-3 16:13
做成qq浏览器插件最好,打开外文网站,全网页内容自动翻译为中文,如此甚好

有道理,不过这种插件已经有现成的了。我这个适用于使用其它工具时进行翻译。
cioceo 发表于 2025-11-3 16:50
截图翻译我用的也是小牛,自己注册免费api够用了,软件用的pot2.4.3,挺好用的
happyxiangyang 发表于 2025-11-3 17:11
感谢楼主分享
GrabySky 发表于 2025-11-3 18:11
有没有PDF的翻译呢
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-1-16 18:05

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表