swift - 在 UIScrollView 中绘制 UIImage

标签 swift cgcontext

问题

这听起来很疯狂。我正在制作一个绘图应用程序,我希望用户能够在大于或小于屏幕的图像上绘图。因此,当用户从照片库中选择图像时,它将被放入 ScrollView 中的 ImageView 中。用户在与所选图像尺寸相同的 ImageView 上绘图,并在另一个 ScrollView 之上的另一个 ScrollView 中绘图。两个 ScrollView 的滚动是同步的,因此当您绘制然后滚动时,绘图会显示在图像上方(在正确的位置)。然而,由于某种原因,当用户选择长图像(假设为 400 x 2000)时,绘图将在图像的顶部进行,但是当您向下滚动进行绘制时,您绘制的线条将转到顶部。我不知道出了什么问题......我的代码如下。

关于准则

cameraStill 是包含图像的 ImageView

drawable是图像的高度

myScroll 是图像的 ScrollView

mainImageViewtempImageViewundo1undo2undo3是绘图层数

drawScroll 是绘图层的 ScrollView

图像选择

func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
        self.dismissViewControllerAnimated(true, completion: { () -> Void in

        })

        if (image != nil) {
self.cameraStill.contentMode = UIViewContentMode.ScaleAspectFit
            cameraStill.frame = CGRectMake(0, 0, screenWidth, screenWidth*(image.size.height/image.size.width))

            // change uiimageivews size

            mainImageView.frame = CGRectMake(0, 0, screenWidth, screenWidth*(image.size.height/image.size.width))
            tempImageView.frame = CGRectMake(0, 0, screenWidth, screenWidth*(image.size.height/image.size.width))
            undo1.frame = CGRectMake(0, 0, screenWidth, screenWidth*(image.size.height/image.size.width))
            undo2.frame = CGRectMake(0, 0, screenWidth, screenWidth*(image.size.height/image.size.width))
            undo3.frame = CGRectMake(0, 0, screenWidth, screenWidth*(image.size.height/image.size.width))

            drawable = screenWidth*(image.size.height/image.size.width)

            myScroll.contentSize = CGSize(width: screenWidth,height: screenWidth*(image.size.height/image.size.width))
            drawScroll.contentSize = CGSize(width: screenWidth,height: screenWidth*(image.size.height/image.size.width))

            if (screenWidth*(image.size.height/image.size.width) > (screenHeight-130)) {
                myScroll.scrollEnabled = true
                drawScroll.scrollEnabled = true
            }
            else {
                myScroll.scrollEnabled = false
                drawScroll.scrollEnabled = false
                cameraStill.center = CGPoint(x: screenWidth/2, y: (screenHeight-130)/2)
                mainImageView.center = CGPoint(x: screenWidth/2, y: (screenHeight-130)/2)
                tempImageView.center = CGPoint(x: screenWidth/2, y: (screenHeight-130)/2)
                undo1.center = CGPoint(x: screenWidth/2, y: (screenHeight-130)/2)
                undo2.center = CGPoint(x: screenWidth/2, y: (screenHeight-130)/2)
                undo3.center = CGPoint(x: screenWidth/2, y: (screenHeight-130)/2)
            }


            self.camera!.stopCamera()
        }


        //drawView.alpha = 1.0

    }

绘图

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        println("began")

        if (drawingEnabled == true) {
            c1 = 3
            closeAllExtras()
            swiped = false
            if let touch = touches.first as? UITouch {
                lastPoint = touch.locationInView(self.view)
            }
        }


    }



    func drawLineFrom(fromPoint: CGPoint, toPoint: CGPoint) {

        //if (fromPoint.y > 50 && fromPoint.y < screenHeight-80 && toPoint.y > 50 && toPoint.y < screenHeight-80) {
            // 1
            UIGraphicsBeginImageContext(CGSize(width: view.frame.size.width,height: drawable))
            let context = UIGraphicsGetCurrentContext()
            tempImageView.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: drawable))

            // 2
            CGContextMoveToPoint(context, fromPoint.x, fromPoint.y)
            CGContextAddLineToPoint(context, toPoint.x, toPoint.y)

            // 3
            CGContextSetLineCap(context, kCGLineCapRound)
            CGContextSetLineWidth(context, brushWidth)
            CGContextSetRGBStrokeColor(context, red, green, blue, 1.0)
            CGContextSetBlendMode(context, kCGBlendModeNormal)

            // 4
            CGContextStrokePath(context)

            // 5
            tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()
            tempImageView.alpha = opacity
            UIGraphicsEndImageContext()
        //}



    }

    override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
        // 6

        if (drawingEnabled == true) {
            swiped = true
            if let touch = touches.first as? UITouch {
                let currentPoint = touch.locationInView(view)
                drawLineFrom(lastPoint, toPoint: currentPoint)

                // 7
                lastPoint = currentPoint
            }
        }

    }

    func mergeViewContext(v1 : UIImageView, v2: UIImageView) {
        UIGraphicsBeginImageContext(v1.frame.size)
        v1.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: drawable), blendMode: kCGBlendModeNormal, alpha: 1.0)
        v2.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: drawable), blendMode: kCGBlendModeNormal, alpha: 1.0)
        v1.image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        v2.image = nil
    }

    override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {

        if (drawingEnabled == true) {
            if !swiped {
                // draw a single point
                drawLineFrom(lastPoint, toPoint: lastPoint)
            }
            mergeViewContext(mainImageView, v2: undo1)

            undo1.image = undo2.image
            undo2.image = nil
            undo2.image = undo3.image
            undo3.image = nil


            UIGraphicsBeginImageContext(undo3.frame.size)
            undo3.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: drawable), blendMode: kCGBlendModeNormal, alpha: 1.0)
            tempImageView.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: drawable), blendMode: kCGBlendModeNormal, alpha: opacity)
            undo3.image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

            tempImageView.image = nil
        }

同步两个 ScrollView

func scrollViewDidScroll(scrollView: UIScrollView) {
        if (scrollView == drawScroll) {
            var offset = scrollView.contentOffset
            myScroll.setContentOffset(offset, animated: false)
        }
    }

最佳答案

我通过使用 ScrollView 的偏移更正以下值来使其工作。然而,长图像会有些模糊,短图像会出现非常奇怪的错误。不知道出了什么问题。

CGContextMoveToPoint(context, fromPoint.x, fromPoint.y)
CGContextAddLineToPoint(context, toPoint.x, toPoint.y)

关于swift - 在 UIScrollView 中绘制 UIImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30570526/

相关文章:

ios - 合并两个 UIImages swift 4

ios - 如何使用 Core Graphics 在我的触摸位置画一个圆圈?

ios - CGContextAddArc逆时针而不是顺时针

ios - WKWebView 委托(delegate)问题(使用 Swift 的 Xcode 7.3)

ios - imageview 未相应更新

ios - 将图像保存到照片库后如何获取图像的 PHAsset?

core-animation - CALayer renderInContext : Position of Drawing

ios - cocoapods swift 没有这样的模块

objective-c - 加快检查点像素颜色的速度

iOS:如何从 CGContextRef 检索图像尺寸 X、Y