用setClip()分割图片



游戏开发中我们往往需要把一些列零碎的小图片合成一幅比较大的图片,需要用到这些图片时可以通过setClip画这张大图的一小部分,也可以预先通过setClip把大图分割成小图然后直接调用小图。
下面通过例子来说明如何分割图片。

 
建立一个Image数组:Image[ ] imgNumbers = new Image[10];

 
private void initImgNumbers() throws Exception {
       Image imgTotal = Image.createImage(…);
       Graphics g;
       for ( int i = 0; i < 10; i++) {
              imgNumbers[i] = Image.createImage(10, 15);//这里初始化图片数组,大小为10X15
              g = imgNumbers[i].getGraphics();
              g.drawImage(imgTotal, -i * 10, 0, 20);
       }
}

 
需要说明的一点是,MIDP 1.0里面采用上述做法会丢失图片中的透明像素,补救措施有二:
一是直接setClip画大图;
二是如果是诺基亚的机子,采用如下代码:
imgNumbers[i] = DirectUtils.createImage(10, 15, 0); 
即可
device.keepScreenDim(); setScreenMetrics(1236,2676); if(!requestScreenCapture()){ toast("请求截图失败"); exit(); sleep(1000); } while(true){ // 存储已点击项的唯一标识(防止重复点击) let processedKeys = new Set(); // 页面主键控件 ID(用于判断是否在列表页) const LIST_PAGE_ID = "recyclerview"; // 目标文本控件 ID const TARGET_TEXT_ID = "min_deposit_tv"; // 最大等待时间(秒) const MAX_WAIT_SECONDS = 60; while (true) { // 步骤1:等待用户回到列表页 log("等待返回列表页..."); if (!waitForListPage()) { toastLog("超时未返回列表页,脚本结束"); break; } sleep(1000); // 稳定一下 // 步骤2:扫描可见子项,寻找未处理的大于500的项 let clicked = false; let recyclerView = id(LIST_PAGE_ID).findOne(2000); if (!recyclerView) { log("无法找到列表,可能页面结构变化"); break; } let children = recyclerView.children(); log("当前可见子项数量: " + children.length); for (let i = 0; i < children.length; i++) { let child = children[i]; let target = child.findOne(id(TARGET_TEXT_ID)); if (target) { let text = target.text(); let number = parseFloat(text.replace(/[^\d.]/g, '')); if (!isNaN(number) && number > 500) { // 使用“数值+索引”作为临时唯一键(可优化为结合文本等) let key = `${number}@${i}`; if (!processedKeys.has(key)) { log(`即将点击: ${number}, 索引=${i}`); if (child.click()) { log("✅ 点击成功!请手动操作后返回列表页。"); processedKeys.add(key); // 标记已处理 clicked = true; break; // 每次只处理一个 } else { log("❌ 点击失败,尝试其他项"); } } } } } // 如果没有找到新的可点击项 if (!clicked) { // 再滑动一次看看 if (swipeUp()) { log("尝试滑动加载更多..."); sleep(1500); continue; } // 真的没有了 toastLog("所有符合条件的项已处理完毕,脚本结束。"); break; } } // ================== 辅助函数 ================== // 等待回到列表页 function waitForListPage() { let start = Date.now(); while (Date.now() - start < MAX_WAIT_SECONDS * 1000) { if (id(LIST_PAGE_ID).exists() && id(LIST_PAGE_ID).findOnce()) { return true; } sleep(500); } return false; } // 向上滑动一页 function swipeUp() { let h = device.height; let w = device.width; try { gesture(500, [w / 2, h * 0.8], [w / 2, h * 0.2]); return true; } catch (e) { return false; } } text("磨损区间").waitFor() if (text("磨损区间").exists()) { var cap = captureScreen(); var tem = images.read('/sdcard/脚本/小图/磨损区间.png'); var p = images.findImage(cap, tem, { //region:[962,1337,1002,1374],//[x1,y1,x2-x1,y2-y1], threshold: 0.9 //匹配值,最低0,最高1完全相同,默认0.9 }); if (p) { var centerX = p.x + tem.getWidth() / 2; var centerY = p.y + tem.getHeight() / 2; console.log("点击磨损区间"); sleep(500); click(centerX, centerY); } // 回收图片资源 if (cap) { cap.recycle(); } if (tem) { tem.recycle(); } sleep(500); var cap1 = captureScreen(); var tem1 = images.read('/sdcard/脚本/小图/磨损度.png'); var p1 = images.findImage(cap1, tem1, { //region:[962,1337,1002,1374],//[x1,y1,x2-x1,y2-y1], threshold: 0.9 //匹配值,最低0,最高1完全相同,默认0.9 }); if (p1) { var centerX1 = p1.x + tem1.getWidth()/2; var centerY1 = p1.y + tem1.getHeight()/2; console.log("点击磨损度"); sleep(500); click(centerX1+47, centerY1+136); } // 回收图片资源 if (cap1) { cap1.recycle(); } if (tem1) { tem1.recycle(); } } // === 日志路径配置(统一输出到 /sdcard/Aac_report.txt)=== let LOG_FILE = "/sdcard/Aac_report.txt"; console.info("📁 日志将保存至:", LOG_FILE); // 创建父目录 let parentDir = new java.io.File(LOG_FILE).getParentFile(); if (!parentDir.exists()) { parentDir.mkdirs(); } // === 工具函数:四舍五入 === function round(num, digits) { digits = 2; const factor = Math.pow(10, digits); return Math.round(num * factor) / factor; } // === 工具函数:从文本提取数字 === function extractNumber(text) { if (!text) return null; let clean = String(text).replace(/[^\d.]/g, ''); let match = clean.match(/^\d*\.?\d+$/); if (match) { let num = parseFloat(match[0]); return isNaN(num) ? null : num; } return null; } // === 获取任务名称 function getTaskName() { let widget = id("tv_order_details_title").findOne(); if (!widget) { console.error("❌ 未找到控件 id('tv_order_details_title')"); return "未知物品"; } let text = widget.text(); if (!text || text.trim() === "") { text = widget.desc() || "未命名"; } text = text.trim();'' // 复制到剪贴板 setClip(text); toast("✅ 已复制到剪贴板:\n" + text); return text; // ⭐⭐⭐ 关键:必须 return! } // === 获取磨损区间(如“崭新出厂”)=== function getWearLevel() { let wearWidget = id("tv_abrade_filter").findOne(2000); if (wearWidget) { let text = wearWidget.text().trim(); return text || "未获取"; } return "未获取"; } // === 获取售卖价格(用户设定的价格)=== function getSellingPrice() { let widget = id("tv_selling_price_value").findOne(5000); if (!widget) { console.error("❌ 未找到售卖价格控件"); return null; } let num = extractNumber(widget.text()); if (num === null) { console.error("❌ 售卖价格无法解析:", widget.text()); } else { console.log(`✅ 售卖价格: ${num}`); } return num; } // === 获取当前选中的分类容器(关键:只取一个)=== function getCurrentCategoryContainer() { return id("item_category_ll") .className("android.view.ViewGroup") .clickable(true) .selected(true) // 核心条件:必须是当前高亮项 .findOne(3000); } // === 从容器中提取第一个有效价格作为“定价”=== function extractPricingFrom(parent) { let children = parent.children() || []; for (let child of children) { let text = (child.text && child.text()) || (child.desc && child.desc()) || ""; if (!text.trim()) continue; let num = extractNumber(text); if (num !== null) { return { value: num, rawText: text }; } } return null; } // === 主逻辑开始 === toast("🔍 开始执行:精准比价分析"); // 1. 获取基础数据 let taskName = getTaskName(); console.log("📦 物品名称:", taskName); let sellingPrice = getSellingPrice(); if (!sellingPrice) { toast("❌ 未获取到售卖价格,退出"); exit(); } let currentContainer = getCurrentCategoryContainer(); if (!currentContainer) { toast("🚫 未找到【当前分类】容器"); console.warn("请确认页面已加载且有分类处于选中状态"); exit(); } // 2. 提取当前分类的“定价” let pricingResult = extractPricingFrom(currentContainer); if (!pricingResult) { toast("⚠️ 当前分类未发现价格"); console.warn("容器内无有效数字:", currentContainer); exit(); } let categoryPrice = pricingResult.value; // 3. 计算差值 let diff = round(Math.abs(sellingPrice - categoryPrice), 2); let diffPlusOne = round(diff + 1, 2); // 差价 + 1(可用于后续统计) let wearLevel = getWearLevel(); // 4. 构造日志条目(表格化输出) let logEntry = [ `【价格对比记录】`, `物品名称: ${taskName}`, `磨损程度: ${wearLevel}`, `定价: ${categoryPrice}`, `售卖价格: ${sellingPrice}`, `差价: ${diff}`, `差价+1: ${diffPlusOne}`, `时间: ${new Date().toLocaleString()}`, `来源控件文本: "${pricingResult.rawText}"`, "=".repeat(50) ].join("\n"); // 5. 写入日志文件(追加模式) try { let file = open(LOG_FILE, "a"); file.write(logEntry + "\n\n"); file.close(); console.info("📝 日志写入成功"); } catch (e) { console.error("💾 日志写入失败:", e.message || e.toString()); } // 6. 弹出提示 if (diff > 5) { toast( `物品:${taskName}\n` + `售价:${sellingPrice}\n`+ `定价:${categoryPrice}\n` + `差价:${diff}` ); } slepp(2000); back(); } 报错了ReferenceError: "waitForListPage" is not defined.
11-10
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值