how Add mirror image to 2d Box corners

ぃ、小莉子 提交于 2019-12-08 11:42:40

问题


hello friends i need to add mirror image in right corner and bottom. i create the type of view with the help of this answer

how to create a view like this shape in swift?

but i am not able to add image in right corner and bottom


回答1:


Current approach is somewhat different from the previous one.

Previously i've drawn the right and bottom corner and resized the image such that, the appearance is asked in that question.

But in this question, that approach won't work anymore. First reason is that draw(in rect: CGRect) does not provide mirroring functionality for image while drawing. iOS only provide mirroring functionality while drawing in UIImageView. So to do the mirroring we need to setup 3 image view.

So the approach to achieve it is following

  1. Put one UIImageView in center.
  2. Put one UIImageView in the right of the center another to the bottom.
  3. Now calculate the right mirrored image and apply shear the right image view.
  4. Do the same for the bottom.

One problem still remain in the approach described above. For example we shear the right image view according to y axis. The shear operation works along with center. So the left side and right side both shears across the y axis. So we translate positive to the x axis so that all the shear applies to the right of UIImageView. Thats why overlap the right and main image view to fill the gap between to, as following

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

Same goes for the bottom image view.

Code

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




回答2:


One approach is to use 3 image views - the "main" imageView plus a right-side imageView and a bottom imageView.

  • Scale your image to fit the main view + a small amount for the right-side and bottom.
  • Set the main imageView's .contentMode = .topLeft to clip the right and bottom.
  • Set the right-side imageView to .topRight to clip the left and bottom.
  • Set the bottom imageView to .leftBottom to clip the top and right.
  • Darken the image for the right-side and bottom views (to make it look a little "shadowed"

Then, apply CGAffineTransform to skew the right-side and bottom views.

Using this image (3:2 ratio):

and this code (everything is done via code - no IBOutlets needed):

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!
    }

}

This is the result:

There is a variable named vDepth that controls the width of the right-side and the height of the bottom imageViews.

Note: this is just example code... Hopefully this will get you on your way.



来源:https://stackoverflow.com/questions/57786763/how-add-mirror-image-to-2d-box-corners

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!