Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

请教一个问题 #1

Open
make1a opened this issue Aug 7, 2019 · 4 comments
Open

请教一个问题 #1

make1a opened this issue Aug 7, 2019 · 4 comments

Comments

@make1a
Copy link

make1a commented Aug 7, 2019

大神你好,最近在做一款儿童填色应用。
需求是点击一个闭合区域,然后相关的其他闭合区域也会跟着填色。
比如图片上的耳朵,点左耳然后左右边耳朵都成了红色。
IMG_ADA444F82EA6-1

不知道这种有什么好的方法实现吗?

@make1a
Copy link
Author

make1a commented Aug 7, 2019

我有一个比较粗糙的想法。

  1. 首先在耳朵上找出两个种子点(seed point)A、B绑定成一组
  2. 点击图片上某一个点之后,在压栈的时候若是包含其中一个种子点A。调用floodFill(from: B)

现在的问题是不知道要怎么实现 在压栈的时候若是包含其中一个种子点A 求大神指点一下

@make1a
Copy link
Author

make1a commented Aug 7, 2019

已经实现了,感谢大神的demo算法。受益匪浅

@make1a make1a closed this as completed Aug 7, 2019
@make1a make1a reopened this Aug 7, 2019
@make1a
Copy link
Author

make1a commented Aug 7, 2019

在判断 区域 是否包含种子点 这个算法,还有一些问题。 demo
我判断的是X-Y点的区域,似乎还有更好的方法,请大神帮忙看一下。

             var maxX = 0
                var minX = 0
                var maxY = 0
                var minY = 0
                seedPointList.push(realPoint)
                while !seedPointList.isEmpty {

                    if let point = seedPointList.pop() {
                        let (xLeft,xRight) = fillLine(seedPoint: point, newColorRgbaValue: newColorRgbaValue,
                                                      originalColorRgbaValue: colorRgbaValue)
                        scanLine(lineNumer: Int(point.y) + 1, xLeft: xLeft, xRight: xRight, originalColorRgbaValue: colorRgbaValue)
                        scanLine(lineNumer: Int(point.y) - 1, xLeft: xLeft, xRight: xRight, originalColorRgbaValue: colorRgbaValue)
                        
                        if xLeft < minX || minX == 0 { //最小X
                            minX = xLeft
                        }
                        if xRight > maxX || maxX == 0 { //最大X
                            maxX = xRight
                        }
                        if maxY == 0 && minY == 0 {
                            maxY = Int(point.y)
                            minY = Int(point.y)
                        }
                        if maxY < Int(point.y) {
                            maxY = Int(point.y)
                        }
                        if minY > Int(point.y) {
                            minY = Int(point.y)
                        }
                    }
                }
                
                print(maxX,minX,maxY,minY)
                if isFindSeedPoint == false {
                    for  p in seedPointArray {
                        let x = p.x * widthScale
                        let y = p.y * heightScale
                        if (Int(x) < maxX && Int(x) > minX) && (Int(y) < maxY && Int(y) > minY) {
                            isFindSeedPoint = true
                            guard let index = seedPointArray.firstIndex(of: p) else { return  }
                            seedPointArray.remove(at: index)
                            break
                        }
                    }
                }

                
                if let cgImage = context.makeImage() {
                   let img = UIImage(cgImage: cgImage, scale: image?.scale ?? 2, orientation: .up)
                    let transition = CATransition.init()
                    transition.duration = 0.5
                    transition.timingFunction = CAMediaTimingFunction.init(name: .linear)
                    transition.type = .fade
                    layer.add(transition, forKey: "colorAnimation")
                    image = img
                    

                }
                
                if isFindSeedPoint == true && isEndCurrentFill == false {
                    isEndCurrentFill = true
                    for p in seedPointArray {
                        floodFill(from: p)
                    }
                }
                
                isFindSeedPoint = false
                isEndCurrentFill = false

@make1a make1a closed this as completed Aug 8, 2019
@make1a
Copy link
Author

make1a commented Aug 28, 2019

    /// 填充其他绑定的种子点
    ///
    /// - Parameters:
    ///   - scanline: 扫描线
    ///   - widthScale: 获取图片上的实际像素点
    ///   - heightScale: 获取图片上的实际像素点
    private func fillColorWithOtherSeed(scanline: FillLineInfo, widthScale: CGFloat, heightScale: CGFloat) {
        guard let seedPointArray = seedPointArray else { return }
        for  array in seedPointArray {
            for p in array {
                let x = Int(p.x * widthScale)
                let y = Int(p.y * heightScale)
                if (scanline.lineNumber == y) && (scanline.xLeft <= x && scanline.xRight >= x) {
                    currentSeedPointArray = array
                    guard let index = currentSeedPointArray.firstIndex(of: p) else { return  }
                    currentSeedPointArray.remove(at: index)
                    for p in currentSeedPointArray {
                        floodFill(from: p, fillOtherSeed: false)
                    }
                }
            }
        }
    }

这个算法目前也存在一些缺陷,有时候找不到我埋在里面的种子点。 @lkkwxy 请教一下哈。

@make1a make1a reopened this Aug 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant