| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- /**
- * fun 标签:img-cropping
- * 根据区域坐标裁剪截图指定区域并保存
- */
- const path = require('path')
- const fs = require('fs')
- const { spawnSync } = require('child_process')
- const { captureScreenshot } = require('../../../adb/adb-screencap.js')
- const tagName = 'img-cropping'
- const configPath = process.env.STATIC_ROOT
- ? path.join(path.dirname(process.env.STATIC_ROOT), 'config.js')
- : path.join(__dirname, '..', '..', '..', '..', 'config.js')
- const projectRoot = path.dirname(path.resolve(configPath))
- const config = fs.existsSync(configPath) ? require(configPath) : {}
- const imgCropScriptPath = path.join(projectRoot, 'python', 'scripts', 'img-crop.py')
- /** 解析 area 为 { x, y, width, height } */
- function parseAreaToRect(area) {
- const obj = typeof area === 'string' ? JSON.parse(area) : area
- if (obj.topLeft && obj.bottomRight) {
- return {
- x: parseInt(obj.topLeft.x, 10),
- y: parseInt(obj.topLeft.y, 10),
- width: parseInt(obj.bottomRight.x - obj.topLeft.x, 10),
- height: parseInt(obj.bottomRight.y - obj.topLeft.y, 10),
- }
- }
- if (obj.topLeft && obj.topRight && obj.bottomLeft && obj.bottomRight) {
- return {
- x: parseInt(obj.topLeft.x, 10),
- y: parseInt(obj.topLeft.y, 10),
- width: parseInt(obj.bottomRight.x - obj.topLeft.x, 10),
- height: parseInt(obj.bottomRight.y - obj.topLeft.y, 10),
- }
- }
- if (obj.x != null && obj.y != null && obj.width != null && obj.height != null) {
- return {
- x: parseInt(obj.x, 10),
- y: parseInt(obj.y, 10),
- width: parseInt(obj.width, 10),
- height: parseInt(obj.height, 10),
- }
- }
- return null
- }
- /** 构建截图路径 */
- function buildScreenshotPath(folderPath) {
- return path.join(folderPath, 'history', 'ScreenShot.png')
- }
- /** 构建保存路径 */
- function buildSavePath(savePath, folderPath) {
- return savePath.includes(':') ? savePath : path.join(folderPath, savePath)
- }
- /** 解析 Python 可执行路径(与 config.pythonPath:python/py)。 */
- function getPythonExe() {
- const base = config.pythonPath?.path || path.join(projectRoot, 'python', 'py')
- const winPy = path.join(base, 'python.exe')
- if (fs.existsSync(winPy)) return winPy
- const unixPy = path.join(base, 'python')
- if (fs.existsSync(unixPy)) return unixPy
- return 'python'
- }
- /** 调用 Python 裁剪图片并保存 */
- function cropAndSaveImage(inputPath, outputPath, x, y, width, height) {
- const pythonExe = getPythonExe()
- const r = spawnSync(pythonExe, [imgCropScriptPath, inputPath, outputPath, String(x), String(y), String(width), String(height)], {
- encoding: 'utf-8',
- timeout: 10000,
- cwd: projectRoot
- })
- if (r.status !== 0) {
- return { success: false, error: (r.stderr || r.stdout || '').trim() || '裁剪失败' }
- }
- return { success: true }
- }
- /** 执行 img-cropping */
- async function executeImgCropping({ area, savePath, folderPath, device }) {
- const rect = parseAreaToRect(area)
- if (!rect || rect.width <= 0 || rect.height <= 0) {
- return { success: false, error: '区域坐标格式不正确' }
- }
- const screenshotPath = buildScreenshotPath(folderPath)
- const outputPath = buildSavePath(savePath, folderPath)
- if (device) {
- const cap = captureScreenshot(device, screenshotPath)
- if (!cap.success) return { success: false, error: cap.error }
- }
- const crop = cropAndSaveImage(screenshotPath, outputPath, rect.x, rect.y, rect.width, rect.height)
- if (!crop.success) return { success: false, error: crop.error }
- return { success: true }
- }
- module.exports = { tagName, executeImgCropping, cropAndSaveImage }
|