83 lines
3.2 KiB
Lua
83 lines
3.2 KiB
Lua
|
|
local lang = jarvis.context.language
|
|||
|
|
|
|||
|
|
local temp = jarvis.system.env("TEMP") or jarvis.system.env("TMP") or "C:\\Windows\\Temp"
|
|||
|
|
local ts = jarvis.context.time.year .. jarvis.context.time.month .. jarvis.context.time.day
|
|||
|
|
.. "_" .. jarvis.context.time.hour .. jarvis.context.time.minute .. jarvis.context.time.second
|
|||
|
|
local img = temp .. "\\jarvis_ocr_" .. ts .. ".png"
|
|||
|
|
|
|||
|
|
local capture_ps = string.format(
|
|||
|
|
[[Add-Type -AssemblyName System.Windows.Forms,System.Drawing; $b=[System.Windows.Forms.Screen]::PrimaryScreen.Bounds; $bmp=New-Object Drawing.Bitmap $b.Width,$b.Height; $g=[Drawing.Graphics]::FromImage($bmp); $g.CopyFromScreen($b.Location,[Drawing.Point]::Empty,$b.Size); $bmp.Save('%s'); $g.Dispose(); $bmp.Dispose()]],
|
|||
|
|
img:gsub("\\", "\\\\")
|
|||
|
|
)
|
|||
|
|
local capture_cmd = string.format('powershell -NoProfile -ExecutionPolicy Bypass -Command "%s"', capture_ps:gsub('"', '\\"'))
|
|||
|
|
local cap = jarvis.system.exec(capture_cmd)
|
|||
|
|
|
|||
|
|
if not cap.success or not jarvis.fs.exists(img) then
|
|||
|
|
jarvis.log("error", "screen capture failed: " .. tostring(cap.stderr))
|
|||
|
|
jarvis.system.notify("OCR", lang == "ru" and "Не смог снять экран" or "Could not capture screen")
|
|||
|
|
jarvis.audio.play_error()
|
|||
|
|
return { chain = false }
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
local tesseract_paths = {
|
|||
|
|
"tesseract.exe",
|
|||
|
|
"C:\\Program Files\\Tesseract-OCR\\tesseract.exe",
|
|||
|
|
"C:\\Program Files (x86)\\Tesseract-OCR\\tesseract.exe",
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
local tess = nil
|
|||
|
|
for _, p in ipairs(tesseract_paths) do
|
|||
|
|
local check
|
|||
|
|
if p == "tesseract.exe" then
|
|||
|
|
check = jarvis.system.exec("where tesseract.exe")
|
|||
|
|
else
|
|||
|
|
check = { success = jarvis.fs.exists(p), stdout = p }
|
|||
|
|
end
|
|||
|
|
if check.success and (check.stdout or ""):gsub("[\r\n]+$", "") ~= "" then
|
|||
|
|
tess = p == "tesseract.exe" and "tesseract.exe" or '"' .. p .. '"'
|
|||
|
|
break
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
if not tess then
|
|||
|
|
jarvis.log("error", "tesseract not found")
|
|||
|
|
jarvis.system.notify(
|
|||
|
|
"OCR",
|
|||
|
|
lang == "ru"
|
|||
|
|
and "Tesseract не установлен. Установи: winget install UB-Mannheim.TesseractOCR"
|
|||
|
|
or "Tesseract not installed. Install: winget install UB-Mannheim.TesseractOCR"
|
|||
|
|
)
|
|||
|
|
jarvis.audio.play_error()
|
|||
|
|
return { chain = false }
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
local langs = lang == "en" and "eng" or "rus+eng"
|
|||
|
|
local ocr_cmd = string.format('%s "%s" - -l %s', tess, img, langs)
|
|||
|
|
local ocr = jarvis.system.exec(ocr_cmd)
|
|||
|
|
|
|||
|
|
if not ocr.success then
|
|||
|
|
jarvis.log("error", "tesseract failed: " .. tostring(ocr.stderr):sub(1, 200))
|
|||
|
|
jarvis.system.notify("OCR", lang == "ru" and "Tesseract упал" or "Tesseract failed")
|
|||
|
|
jarvis.audio.play_error()
|
|||
|
|
return { chain = false }
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
local text = (ocr.stdout or ""):gsub("^%s+", ""):gsub("%s+$", "")
|
|||
|
|
if text == "" then
|
|||
|
|
jarvis.system.notify("OCR", lang == "ru" and "Текста не найдено" or "No text found")
|
|||
|
|
jarvis.audio.play_not_found()
|
|||
|
|
return { chain = false }
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
jarvis.system.clipboard.set(text)
|
|||
|
|
jarvis.log("info", "OCR result (" .. #text .. " bytes) copied to clipboard")
|
|||
|
|
|
|||
|
|
local preview = text:gsub("\r?\n", " "):sub(1, 200)
|
|||
|
|
if #text > 200 then preview = preview .. "..." end
|
|||
|
|
jarvis.system.notify(
|
|||
|
|
lang == "ru" and "Текст с экрана" or "Screen text",
|
|||
|
|
preview
|
|||
|
|
)
|
|||
|
|
jarvis.audio.play_ok()
|
|||
|
|
return { chain = false }
|