当前位置:网站首页>用aardio写一个旋转验证码标注小工具
用aardio写一个旋转验证码标注小工具
2022-07-06 13:36:00 【Qwertyuiop2016】
需求
最近想训练旋转验证码识别的模型。标注数据是个无意义且费时间的活,而且针对旋转验证码还没有找到一个顺手的标注工具。没有那就自己写一个。
在网上看到的文章是生成360个角度的图片,找出其中方向为正的一张。生成360个角度的图片很耗时间,一张图片大概需要个一两分钟,然后再在360个图片中选择一张还挺麻烦的。
开始写代码
旋转效果
我找了很久也没看到aardio有什么可以旋转图片的库,正当我打算用aardio调用Python时,突然看到在HTML中旋转图片居然只需要给img标签加一个style="transform: rotate(0deg);"
其中的0就是旋转的角度,支持负数
也就是说旋转图片的功能我只需要用html就能实现,我只需要控制0deg中的数字,就能控制图片旋转的角度。
//截图 远程调试
import win.ui;
import web.view;
/*DSG{
{*/
var mainForm = win.form(text="旋转验证码标注";right=468;bottom=605;acceptfiles=1;bgcolor=16777215;border="thin")
mainForm.add()
/*}}*/
var wb = web.view(mainForm,,0);
wb.go('/res/1.html')
mainForm.show();
return win.loopMessage();
1.html的代码
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style type="text/css"> .vcode-spin-faceboder {
position: relative; overflow: hidden; width: 350px; height: 350px; margin: 28px auto 24px; border: 0; -webkit-background-size: 100% 100%; background-size: 100% 100% } .vcode-spin-img {
position: relative; z-index: 999; width: 100%; height: 100%; pointer-events: none; -webkit-border-radius: 50%; border-radius: 50% } .next {
width: 50px; height: 15px; background-color: rgb(250,0,255) } </style>
<script type="text/javascript"> </script>
</head>
<body style="margin:50px">
<div class="vcode-spin-faceboder">
<img class="vcode-spin-img" src="1.jpg" style="transform: rotate(0deg);">
<button id="next" class="next"></button>
</div>
</body>
</html>
效果:
修改html标签属性
// 180就是旋转的角度
var js = string.format(`this.setAttribute("style", "transform: rotate(%ddeg);");`, 180);
// 100为timeout时间,单位毫秒, 前面是css选择器
wb.waitEle(".vcode-spin-img", js, 100);
如果改成js的写法:
var inp = document.getElementsByClassName("vcode-spin-img");
inp.setAttribute("type", "transform: rotate(180deg);");
加个滑动条
我想通过滑动滑动条的位置来控制图片旋转的角度。首先界面控件里选择跟踪条,刻度的话0-359, 后面我改成了(-179-180)。不过库代码里说不能用负数,我试了负数也没问题,就不理他了
// 指定滑动条最大刻度
mainForm.trackbar.max=359;
// 指定滑动条最小刻度
mainForm.trackbar.min=0;
// 指定滑动条当前刻度
mainForm.trackbar.pos=0;
加入滑动条逻辑
效果:
mainForm.trackbar.onnotify = function(id,code,ptr){
if(code==0xFFFFFFF4){
var js = string.format(`this.setAttribute("style", "transform: rotate(%ddeg);");`, mainForm.trackbar.pos);
wb.waitEle(".vcode-spin-img", js, 100);
}
}
保存
旋转正了,要将旋转后的图片保存。目前想到了两种方法,第一种直接截图当前软件的界面,会把按钮什么的也截进去。后面再做一下处理就行。因为界面的大小是不变的,只需要剪切指定部分的图
var picture = gdip.snap(mainForm.hwnd);
// filename是文件路径,100是文件质量(0-100),仅针对jpg格式
picture.save(filename,100);
第二种则是网页截图,因为界面是基于浏览器的。所以也可以支持devtools protocol协议
第一步:打开远程控制端口
var ws = wb.openRemoteDebugging()
ws.Runtime.enable();
第二步:获取图片控件在网页的位置(x, y和width, height)。用js的方法就可以,然后执行js获取返回值。不截img标签,而是截外层的div。因为外层的div是固定大小的。截img的话大小会变化
// 在aardio中引号是可以换行的
js = '(function(){
var a = document.querySelector(".vcode-spin-faceboder").getBoundingClientRect();
return a.toJSON();
})()'
执行js
ws.Runtime.evaluate(expression=js, awaitPromise=true,returnByValue=true).end = function(result, err){
console.dump(result);
var clip = {
scale=1;x=result.left+pageX;y=result.top+pageY;width=result.width;height=result.height};
}
pageX和pageY获取(为什么要加这个我也不清楚,我看的pyppeteer源码加了这个),实际获取的值也是0,0所以加不加无所谓
var pageX,pageY;
ws.Page.getLayoutMetrics().end = function(result, err){
pageX = result[["layoutViewport"]].pageX
pageY = result[["layoutViewport"]].pageY
}
针对控件截图,实际也就是全屏截图,然后给个x,y加宽高剪切一下
ws.Page.captureScreenshot(clip=clip).end = function(result,err){
if(result[["data"]]){
var bin = crypt.decodeBin(result[["data"]]);
string.save("\1.PNG", bin )
}
}
增加一些按钮
最终效果:
使用说明
滑动条右边的0表示,旋转的角度(滑动条的当前刻度)。这个控件是编辑框,可以修改这个角度,然后点击旋转就可以旋转指定的角度
下面的1表示当前指定文件夹的第几张图片,需要先按选择按钮选择有旋转图片的文件夹,向前和向后则是选择文件夹的上一张图片和下一张图片(会循环)
保存按钮则是保存已经标注好的图片到文件夹下(无法指定文件夹,是在当前文件夹创建了一个result,文件名为1.jpg,1表示第几张图片)
其中一直想用aardio写一些工具,后面说一些怎么用aardio打包Python。
完整代码和软件
https://github.com/kanadeblisst/rotate_qrcode_label
边栏推荐
- In JS, string and array are converted to each other (I) -- the method of converting string into array
- JS traversal array and string
- Yuan Xiaolin: safety is not only a standard, but also Volvo's unchanging belief and pursuit
- 在最长的距离二叉树结点
- Four common ways and performance comparison of ArrayList de duplication (jmh performance analysis)
- C language: comprehensive application of if, def and ifndef
- Redistemplate common collection instructions opsforlist (III)
- 在Pi和Jetson nano上运行深度网络,程序被Killed
- 14年本科毕业,转行软件测试,薪资13.5K
- Internet News: Geely officially acquired Meizu; Intensive insulin purchase was fully implemented in 31 provinces
猜你喜欢
一行代码可以做些什么?
Tiktok will push the independent grass planting app "praiseworthy". Can't bytes forget the little red book?
1292_FreeROS中vTaskResume()以及xTaskResumeFromISR()的实现分析
Fastjson parses JSON strings (deserialized to list, map)
C# 如何在dataGridView里设置两个列comboboxcolumn绑定级联事件的一个二级联动效果
[in depth learning] pytorch 1.12 was released, officially supporting Apple M1 chip GPU acceleration and repairing many bugs
Aggregate function with key in spark
Why rdd/dataset is needed in spark
JPEG2000-Matlab源码实现
Leetcode topic [array] -118 Yang Hui triangle
随机推荐
Broadcast variables and accumulators in spark
[in depth learning] pytorch 1.12 was released, officially supporting Apple M1 chip GPU acceleration and repairing many bugs
【力扣刷题】一维动态规划记录(53零钱兑换、300最长递增子序列、53最大子数组和)
Fastjson parses JSON strings (deserialized to list, map)
Happy sound 2[sing.2]
Sequoia China, just raised $9billion
基于InsightFace的高精度人脸识别,可直接对标虹软
Ravendb starts -- document metadata
ACdreamoj1110(多重背包)
MySQL removes duplicates according to two fields
语谱图怎么看
jvm:大对象在老年代的分配
Internet News: Geely officially acquired Meizu; Intensive insulin purchase was fully implemented in 31 provinces
Technology sharing | packet capturing analysis TCP protocol
The difference between break and continue in the for loop -- break completely end the loop & continue terminate this loop
The role of applicationmaster in spark on Yan's cluster mode
JS get array subscript through array content
Why is the cluster mode of spark on Yan better than the client mode
对话阿里巴巴副总裁贾扬清:追求大模型,并不是一件坏事
The underlying implementation of string