如何将镜像添加到 2d Box 角
how Add mirror image to 2d Box corners
你好朋友我需要在右下角和底部添加镜像。
我在这个答案的帮助下创建了视图类型
但我无法在右下角和底部添加图像
一种方法是使用 3 个图像视图 - "main" 图像视图加上右侧图像视图和底部图像视图。
- 缩放您的图像以适合主视图 + 右侧和底部的少量缩放。
- 设置主imageView的
.contentMode = .topLeft
裁剪右边和底部。
- 将右侧的imageView设置为
.topRight
以裁剪左侧和底部。
- 将底部 imageView 设置为
.leftBottom
以剪裁顶部和右侧。
- 将右视图和底视图的图像调暗(使其看起来有点 "shadowed"
然后,将CGAffineTransform
应用于倾斜右侧视图和底部视图。
使用此图像(3:2 比例):
和这段代码(一切都是通过代码完成的——不需要 IBOutlets):
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!
}
}
这是结果:
有一个名为 vDepth
的变量控制右侧的宽度和底部 imageViews 的高度。
注意:这只是示例代码...希望这能帮助您上路。
当前方法与 方法有些不同。
之前我已经绘制了右下角并调整了图像的大小,因此在 .
中询问了外观
但在这个问题中,这种方法将不再适用。第一个原因是 draw(in rect: CGRect)
不提供绘图时图像的镜像功能。 iOS 在 UIImageView
中绘图时仅提供镜像功能。所以要进行镜像,我们需要设置 3 个图像视图。
所以实现方法如下
- 将一个
UIImageView
放在中间。
- 将一个
UIImageView
放在中间的右边,另一个放在底部。
- 现在计算右镜像并应用剪切右图像视图。
- 对底部做同样的事情。
上述方法还存在一个问题。例如,我们根据 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!
}
}
输出
你好朋友我需要在右下角和底部添加镜像。 我在这个答案的帮助下创建了视图类型
但我无法在右下角和底部添加图像
一种方法是使用 3 个图像视图 - "main" 图像视图加上右侧图像视图和底部图像视图。
- 缩放您的图像以适合主视图 + 右侧和底部的少量缩放。
- 设置主imageView的
.contentMode = .topLeft
裁剪右边和底部。 - 将右侧的imageView设置为
.topRight
以裁剪左侧和底部。 - 将底部 imageView 设置为
.leftBottom
以剪裁顶部和右侧。 - 将右视图和底视图的图像调暗(使其看起来有点 "shadowed"
然后,将CGAffineTransform
应用于倾斜右侧视图和底部视图。
使用此图像(3:2 比例):
和这段代码(一切都是通过代码完成的——不需要 IBOutlets):
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!
}
}
这是结果:
有一个名为 vDepth
的变量控制右侧的宽度和底部 imageViews 的高度。
注意:这只是示例代码...希望这能帮助您上路。
当前方法与
之前我已经绘制了右下角并调整了图像的大小,因此在
但在这个问题中,这种方法将不再适用。第一个原因是 draw(in rect: CGRect)
不提供绘图时图像的镜像功能。 iOS 在 UIImageView
中绘图时仅提供镜像功能。所以要进行镜像,我们需要设置 3 个图像视图。
所以实现方法如下
- 将一个
UIImageView
放在中间。 - 将一个
UIImageView
放在中间的右边,另一个放在底部。 - 现在计算右镜像并应用剪切右图像视图。
- 对底部做同样的事情。
上述方法还存在一个问题。例如,我们根据 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!
}
}
输出