如何将镜像添加到2d框角

时间:2019-09-04 10:45:06

标签: ios swift core-graphics core-animation swift5

enter image description here

你好朋友,我需要在右下角和底部添加镜像。 我借助此答案创建视图类型

how to create a view like this shape in swift?

enter image description here

但是我无法在右下角和底部

添加图像

2 个答案:

答案 0 :(得分:1)

一种方法是使用3个图像视图-“主”图像视图加上右侧imageView和底部imageView。

  • 缩放图像以适合主视图,并为右侧和底部添加少量图像。
  • 设置主imageView的.contentMode = .topLeft来裁剪右边和底部。
  • 将右侧imageView设置为.topRight,以裁剪左侧和底部。
  • 将底部imageView设置为.leftBottom,以裁剪顶部和右侧。
  • 使图像的右侧视图和底视图变暗(以使其看起来有点“阴影”

然后,将CGAffineTransform应用于右侧和底视图的倾斜

使用此图像(比例为3:2):

enter image description here

和此代码(一切都通过代码完成-无需IBOutlet):

import UIKit
import CoreImage

class ImageWorkViewController: UIViewController {

    let mainImageView: UIImageView = {
        let v = UIImageView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.clipsToBounds = true
        v.contentMode = .topLeft
        return v
    }()

    let rightImageView: UIImageView = {
        let v = UIImageView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.clipsToBounds = true
        v.contentMode = .topRight
        return v
    }()

    let bottomImageView: UIImageView = {
        let v = UIImageView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.clipsToBounds = true
        v.contentMode = .bottomLeft
        return v
    }()

    // this will be the width of the skewed right-side and height of the skewed bottom
    let vDepth:CGFloat = 10.0

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(mainImageView)
        view.addSubview(rightImageView)
        view.addSubview(bottomImageView)

        NSLayoutConstraint.activate([

            // constrain main image view 40-pts from each side
            mainImageView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 40.0),
            mainImageView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -40.0),

            // centered vertically
            mainImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0.0),

            // use 3:2 ratio
            mainImageView.heightAnchor.constraint(equalTo: mainImageView.widthAnchor, multiplier: 2.0 / 3.0),

            // constrain right image view to main image view
            //      right-edge
            //      top + 1/2 of vDepth
            //      equal height
            //      width = vDepth
            rightImageView.leadingAnchor.constraint(equalTo: mainImageView.trailingAnchor, constant: 0.0),
            rightImageView.topAnchor.constraint(equalTo: mainImageView.topAnchor, constant: vDepth / 2.0),
            rightImageView.heightAnchor.constraint(equalTo: mainImageView.heightAnchor, multiplier: 1.0),
            rightImageView.widthAnchor.constraint(equalToConstant: vDepth),

            // constrain bottom image view to main image view
            //      left-edge + 1/2 of vDepth
            //      bottom
            //      equal width
            //      height = vDepth
            bottomImageView.leadingAnchor.constraint(equalTo: mainImageView.leadingAnchor, constant: vDepth / 2.0),
            bottomImageView.topAnchor.constraint(equalTo: mainImageView.bottomAnchor, constant: 0.0),
            bottomImageView.widthAnchor.constraint(equalTo: mainImageView.widthAnchor, multiplier: 1.0),
            bottomImageView.heightAnchor.constraint(equalToConstant: vDepth),

            ])

    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        // run this on viewDidLayoutSubviews() so we have valid frame sizes
        if let sourceImg = UIImage(named: "goal3x2") {

            // resize image to width and height of main image view, plus vDepth value
            let mainImg = resizeImage(image: sourceImg, newSize: CGSize(width: mainImageView.frame.width + vDepth, height: mainImageView.frame.height + vDepth))

            // set the main image
            mainImageView.image = mainImg

            // we're going to darken the right-side and bottom images a little bit
            if let currentFilter = CIFilter(name: "CIColorControls") {
                let context = CIContext(options: nil)

                let beginImage = CIImage(image: mainImg)
                currentFilter.setValue(beginImage, forKey: kCIInputImageKey)

                // darken right-image by 40%
                currentFilter.setValue(-0.4, forKey: kCIInputBrightnessKey)

                if let output = currentFilter.outputImage {
                    if let cgimg = context.createCGImage(output, from: output.extent) {
                        let processedImage = UIImage(cgImage: cgimg)
                        // set the right-side image
                        rightImageView.image = processedImage
                    }
                }

                // darken bottom-image by 50%
                currentFilter.setValue(-0.5, forKey: kCIInputBrightnessKey)

                if let output = currentFilter.outputImage {
                    if let cgimg = context.createCGImage(output, from: output.extent) {
                        let processedImage = UIImage(cgImage: cgimg)
                        // set the bottom image
                        bottomImageView.image = processedImage
                    }
                }
            }

        }

        // skew the right-side and bottom image views
        let skewVal: CGFloat = 1.0

        // bottom part transform
        let bottomTransform = CGAffineTransform(a: 1.0, b: 0.0, c: skewVal, d: 1.0, tx: 0.0, ty: 0.0)
        bottomImageView.transform = bottomTransform

        // right part transform
        let rightTransform = CGAffineTransform(a: 1.0, b: skewVal, c: 0.0, d: 1.0, tx: 0.0, ty: 0.0)
        rightImageView.transform = rightTransform

    }

    func resizeImage(image: UIImage, newSize: CGSize) -> UIImage {

        let newWidth = newSize.width
        let newHeight = newSize.height
        UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
        image.draw(in: CGRect(x: 0.0, y: 0.0, width: newWidth, height: newHeight))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage!
    }

}

这是结果:

enter image description here

有一个名为vDepth的变量,用于控制右侧imageViews的宽度和底部imageViews的高度。

注意:这只是示例代码...希望这可以帮助您。

答案 1 :(得分:1)

当前的方法与previous有所不同。

以前,我已经绘制了右下角并调整了图像的大小,以便在question中询问外观。

但是在这个问题上,这种方法不再有效。第一个原因是draw(in rect: CGRect)在绘制时不提供图像的镜像功能。 iOS仅在绘制UIImageView时提供镜像功能。因此,要进行镜像,我们需要设置3个图像视图。

因此遵循的方法是

  1. 在中心放置一个UIImageView
  2. 在中心的右侧放置一个UIImageView,在底部放置另一个。
  3. 现在计算右镜像图像并剪切右图像视图。
  4. 对底部执行相同操作。

上述方法仍然存在一个问题。例如,我们根据y轴剪切右图像视图。剪切操作与中心一起工作。因此,左侧和右侧都在y轴上剪切。因此,我们将正向平移到x轴,以使所有剪切力都适用于UIImageView的右侧。 这就是为什么要重叠右图和主图视图以填充到之间的空隙,如下所述

rightImageView.leadingAnchor.constraint(equalTo: mainImageView.trailingAnchor, constant: -stripSize / 2),

底部图像视图相同。

代码

lass ViewController: UIViewController {

    let mainImageView: UIImageView = {
        let view = UIImageView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.clipsToBounds = true
        return view
    }()
    let rightImageView: UIImageView = {
        let view = UIImageView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.clipsToBounds = true
        return view
    }()
    let bottomImageView: UIImageView = {
        let view = UIImageView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.clipsToBounds = true
        return view
    }()

    let rightDarkView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.4)
        return view
    }()

    let bottomDarkView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.5)
        return view
    }()


    let mainImageSize = CGSize(width: 240, height: 240)
    let stripSize = CGFloat(20)


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        setupView()
        setupMirroView()
    }



    func setupView() {
        view.addSubview(mainImageView)
        view.addSubview(rightImageView)
        view.addSubview(bottomImageView)

        view.addSubview(rightDarkView)
        view.addSubview(bottomDarkView)

        NSLayoutConstraint.activate([
            mainImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            mainImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            mainImageView.widthAnchor.constraint(equalToConstant: mainImageSize.width),
            mainImageView.heightAnchor.constraint(equalToConstant: mainImageSize.height),

            rightImageView.leadingAnchor.constraint(equalTo: mainImageView.trailingAnchor, constant: -stripSize / 2),
            rightImageView.topAnchor.constraint(equalTo: mainImageView.topAnchor),
            rightImageView.bottomAnchor.constraint(equalTo: mainImageView.bottomAnchor),
            rightImageView.widthAnchor.constraint(equalToConstant: stripSize),

            rightDarkView.leadingAnchor.constraint(equalTo: rightImageView.leadingAnchor),
            rightDarkView.topAnchor.constraint(equalTo: rightImageView.topAnchor),
            rightDarkView.trailingAnchor.constraint(equalTo: rightImageView.trailingAnchor),
            rightDarkView.bottomAnchor.constraint(equalTo: rightImageView.bottomAnchor),

            bottomImageView.topAnchor.constraint(equalTo: mainImageView.bottomAnchor, constant: -stripSize / 2),
            bottomImageView.leadingAnchor.constraint(equalTo: mainImageView.leadingAnchor),
            bottomImageView.trailingAnchor.constraint(equalTo: mainImageView.trailingAnchor),
            bottomImageView.heightAnchor.constraint(equalToConstant: stripSize),

            bottomDarkView.leadingAnchor.constraint(equalTo: bottomImageView.leadingAnchor),
            bottomDarkView.topAnchor.constraint(equalTo: bottomImageView.topAnchor),
            bottomDarkView.trailingAnchor.constraint(equalTo: bottomImageView.trailingAnchor),
            bottomDarkView.bottomAnchor.constraint(equalTo: bottomImageView.bottomAnchor)

            ])
    }

    func setupMirroView() {
        let image = UIImage(named: "image")
        mainImageView.image = image

        // prepare the image for the right image view
        let rightImage = image?.cropped(to: CGSize(width: stripSize, height: mainImageSize.height),
                                        drawInto: CGRect(x: stripSize - mainImageSize.width, y: 0, width: mainImageSize.width, height: mainImageSize.height))
        let rightImageMirrored = UIImage(cgImage: rightImage!.cgImage!, scale: 1.0, orientation: .upMirrored)
        rightImageView.image = rightImageMirrored

        var rightTransform = CGAffineTransform.identity
        rightTransform = rightTransform.translatedBy(x: stripSize / 2, y: 0)
        rightTransform = rightTransform.concatenating(CGAffineTransform(a: 1.0, b: 1.0, c: 0.0, d: 1.0, tx: 0.0, ty: 0.0))
        rightImageView.transform = rightTransform
        rightDarkView.transform = rightTransform


        // prepare the image for the left image view
        let downImage = image?.cropped(to: CGSize(width: mainImageSize.width, height: stripSize),
                                       drawInto: CGRect(x: 0, y: stripSize - mainImageSize.height, width: mainImageSize.width, height: mainImageSize.height))
        let downImageMirroed = UIImage(cgImage: downImage!.cgImage!, scale: 1.0, orientation: .downMirrored)
        bottomImageView.image = downImageMirroed

        var downTransform = CGAffineTransform.identity
        downTransform = downTransform.translatedBy(x: 0, y: stripSize / 2)
        downTransform = downTransform.concatenating(__CGAffineTransformMake(1.0, 0.0, 1.0, 1.0, 0.0, 0.0))
        bottomImageView.transform = downTransform
        bottomDarkView.transform = downTransform

    }

}

extension UIImage {
    func cropped(to size: CGSize, drawInto: CGRect) -> UIImage {
        UIGraphicsBeginImageContext(size)
        self.draw(in: drawInto)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage!
    }
}

输出

OUTPUT