美文网首页JS脚本
Auto.pro 找图适配分辨率(循环找图优化版)

Auto.pro 找图适配分辨率(循环找图优化版)

作者: 魔力sama | 来源:发表于2019-08-19 10:31 被阅读0次

    上个版本的适配虽然可以解决问题,但是细节操作过多,大量scale操作也会在循环时增加耗时,这里给出另一种解决方案。

    上版本的思路是,分辨率大于设定值1280x720时,将截图缩小;分辨率小于设定值时,将待查图片缩小;最后再将匹配坐标缩放成屏幕分辨率尺寸,思路比较绕。

    这个版本的思路为,在循环找图前将待查图片缩放,截图不做改变。即1280x720下整理出的图片,在1920x1080设备上放大成1080/720倍,在小于1280x720设备上则缩小。

    这样匹配得到的坐标直接就是设备分辨率下的,不需要再做一次坐标适配。坏处是放大待查图片导致了无中生有,匹配度会有略微下降,而且因为没有做设备的截图缩放,在高分辨率下匹配图片会更耗时,因此务必做好region缓存。

    这个版本的细节不多,根据思路应该很容易实现。不过还是放上我的代码,基于RxJS实现,忽略了width、scale等参数的设置过程。

    // 缓存region
    const cache = {}
    
    // 获取截图,多个找图函数共享该cap$数据
    const cap$ = interval(100).pipe(
        exhaustMap(_ => {
            sleep(30)
            let t1 = new Date().getTime()
            let cap = action.cap()
            let t2 = new Date().getTime()
            log('cap cost', t2 - t1)
            return of(cap)
            // return of(images.captureScreen())
        }),
        share()
    )
    
    /**
     * 循环找图,找到后返回坐标
     */
    function findImg (param={
        path: '',
        option: {},
        useCache: false,
        forEver: false,
        eachTime: 100,
        nextTime: null
    }) {
        // 待查图片路径
        let path = param.path || ''
        // 查询参数
        let option = param.option || {}
        // 设置是否使用缓存
        const useCache = param.useCache || false
        const cachePath = param.path + useCache
        // 查1次或一直重复查询
        const takeNum = param.forEver ? 99999 : 1
        // 每次查询间隔
        const eachTime = param.eachTime || 100
        // 查到一次后,离下次查询的间隔
        const nextTime = param.nextTime
        // 待查图片
        let template = images.read(path)
        if (!template) {
            return throwError('template path is null')
        }
    
        template = images.scale(template, r.scale, r.scale)
    
        let queryOption = {...option}
        queryOption.threshold = queryOption.threshold || 0.8
    
        // 如果确认使用缓存,且缓存里已经设置有region的话,直接赋值
        if (useCache && cache[cachePath]) {
            queryOption.region = cache[cachePath]
        } else if (queryOption.region) {
            let region = queryOption.region
            if (region[0] < 0) {
                region[0] = 0
            }
            if (region[1] < 0) {
                region[1] = 0
            }
            if (region.length == 4) {
                let x = region[0] + region[2]
                let y = region[1] + region[3]
                if (x > width) {
                    region[2] = width - region[0]
                }
                if (y > height) {
                    region[3] = height - region[1]
                }
            }
            queryOption.region = region
        }
    
        let pass$ = new BehaviorSubject(true).pipe(
            switchMap(v => {
                if (v) {
                    return of(v)
                } else {
                    return timer(nextTime || 500).pipe(
                        mapTo(true),
                        startWith(false)
                    )
                }
            })
        )
    
        return cap$.pipe(
            throttleTime(eachTime),
            withLatestFrom(pass$),
            filter(([img, pass]) => pass),
            exhaustMap(([img, pass]) => {
                return of(images.matchTemplate(img, template, queryOption).matches)
            }),
            filter(v => v && v.length > 0),
            take(takeNum),
            map(res => {
                return res.map(p => {
                        return [
                            parseInt(p.point['x']),
                            parseInt(p.point['y'])
                        ]
                    }).sort((a, b) => {
                        let absY = Math.abs(a[1] - b[1])
                        let absX = Math.abs(a[0] - b[0])
                        if (absY > 4 && a[1] > b[1]) {
                            return true
                        }
                        else if (absY < 4) {
                            return absX > 4 && a[0] > b[0]
                        } else {
                            return false
                        }
                    })
            }),
            tap(res => {
                // 如果设置了使用缓存,但缓存内还不含有该路径
                if (useCache && !cache[cachePath]) {
                    let scaleWidth = r.width
                    let scaleHeight = r.height
    
                    let x = Math.max(0, res[0][0] - 10)
                    let y = Math.max(0, res[0][1] - 10)
                    let w = template.width + 20
                    let h = template.height + 20
                    w = x + w >= scaleWidth ? scaleWidth - x : w
                    h = y + h >= scaleHeight ? scaleHeight - y : h
    
                    cache[cachePath] = [x, y, w, h]
                    queryOption.region = cache[cachePath]
                }
                // 如果设置了下次间隔
                if (nextTime) {
                    pass$.next(false)
                }
            }),
            finalize(() => {
                // 循环找图结束后,释放待查图片资源
                template.recycle()
                pass$.complete()
            })
        )
    }
    
    

    相关文章

      网友评论

        本文标题:Auto.pro 找图适配分辨率(循环找图优化版)

        本文链接:https://www.haomeiwen.com/subject/iznjsctx.html