作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试为我的应用程序制作图像编辑 VC 并遇到上述问题。每当我开始在图像上绘图时,图像就会变形,然后失去纵横比。
GIF 是:
我的完整代码是:
class DrawImageController: UIViewController {
var canvasImageView: UIImageView = {
let iv = UIImageView()
iv.translatesAutoresizingMaskIntoConstraints = false
iv.backgroundColor = .yellow
iv.contentMode = .scaleAspectFit
return iv
}()
var lastTouch = CGPoint.zero
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
}
func setupViews() {
view.backgroundColor = .black
view.addSubview(canvasImageView)
canvasImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
canvasImageView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
canvasImageView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
canvasImageView.heightAnchor.constraint(equalToConstant: 300).isActive = true
canvasImageView.image = UIImage(named: "testImage")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let firstTouch = touches.first {
lastTouch = firstTouch.location(in: canvasImageView)
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
if let firstTouch = touches.first {
let touchLocation = firstTouch.location(in: canvasImageView)
drawLine(from: lastTouch, to: touchLocation)
lastTouch = touchLocation
}
}
func drawLine(from: CGPoint, to: CGPoint) {
UIGraphicsBeginImageContext(canvasImageView.frame.size)
if let context = UIGraphicsGetCurrentContext() {
canvasImageView.image?.draw(in: CGRect(x: 0, y: 0, width: canvasImageView.frame.size.width, height: canvasImageView.frame.size.height))
context.move(to: from)
context.addLine(to: to)
context.setLineCap(.round)
context.setLineWidth(5.0)
context.setStrokeColor(UIColor.blue.cgColor)
context.strokePath()
let image = UIGraphicsGetImageFromCurrentImageContext()
canvasImageView.image = image
UIGraphicsEndImageContext()
}
}
}
我根据 YouTube、GitHub 和 SO 上的各种教程改编了我的绘制方法。我哪里出错了?
根据@Sweeper的建议,我修改了setupViews()
和drawLine
中的代码,以考虑图像和imageView的纵横比。
func setupViews() {
view.backgroundColor = .black
view.addSubview(canvasImageView)
canvasImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
canvasImageView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
canvasImageView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
let aspectRatio = getImageAspectRatio(image: UIImage(named: "testImage")!)
let screenWidth = UIScreen.main.bounds.width
let height = CGFloat(1.0) / aspectRatio * screenWidth
canvasImageView.heightAnchor.constraint(equalToConstant: height).isActive = true
canvasImageView.image = UIImage(named: "testImage")
}
func drawLine(from: CGPoint, to: CGPoint) {
UIGraphicsBeginImageContext(canvasImageView.frame.size)
guard let context = UIGraphicsGetCurrentContext() else {return}
if let canvasImage = canvasImageView.image {
let imageViewAspectRatio = getAspectRatio(frame: canvasImageView.frame)
let imageAspectRatio = getImageAspectRatio(image: canvasImage)
if imageViewAspectRatio > imageAspectRatio {
canvasImageView.image?.draw(in: CGRect(x: 0, y: 0, width: imageAspectRatio * canvasImageView.frame.size.height, height: canvasImageView.frame.size.height))
} else if imageViewAspectRatio < imageAspectRatio {
canvasImageView.image?.draw(in: CGRect(x: 0, y: 0, width: canvasImageView.frame.size.width, height: CGFloat(1.0) / imageAspectRatio * canvasImageView.frame.size.width))
} else {
canvasImageView.image?.draw(in: CGRect(x: 0, y: 0, width: canvasImageView.frame.size.width, height: canvasImageView.frame.size.height))
}
context.move(to: from)
context.addLine(to: to)
context.setLineCap(.round)
context.setLineWidth(5.0)
context.setStrokeColor(UIColor.blue.cgColor)
context.strokePath()
let image = UIGraphicsGetImageFromCurrentImageContext()
canvasImageView.image = image
UIGraphicsEndImageContext()
}
}
最佳答案
问题出在这里:
canvasImageView.image?.draw(in: CGRect(x: 0, y: 0, width: canvasImageView.frame.size.width, height: canvasImageView.frame.size.height))
您正在使用 ImageView 的框架绘制图像。 这会拉伸(stretch)图像。
您需要绘制图像就像 contentMode
是.scaleAspectFit
。
为此,首先确定图像的纵横比 (W:H)。您可以通过访问 UIImage
的 size
属性来完成此操作。将此比率与 ImageView 的纵横比进行比较。
如果图像的比例小于 View 的比例,则意味着绘制图像的高度可以与 ImageView 的高度相同,并且可以使用图像的长宽比来计算图像的宽度。
如果图像的比例大于 View 的比例,则意味着绘制图像的宽度可以与 ImageView 的宽度相同,并且可以计算图像的高度,
关于Swift:绘图开始时图像丢失纵横比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52134090/
我有一张 table 。我希望它的数据垂直和水平居中。 我使用了 align="center"valign="middle" ,但它没有用。
我是一名优秀的程序员,十分优秀!