用Swift裁剪图像并放在中心位置

在Swift编程中,如何裁剪图像并将其放在中间位置?

这就是我迄今为止所做的…我已经成功地裁剪了图像,但是我想把它放在中心之后

ImgView.image = OrigImage var masklayer = CAShapeLayer() masklayer.frame = ImgView.frame masklayer.path = path.CGPath masklayer.fillColor = UIColor.whiteColor().CGColor masklayer.backgroundColor = UIColor.clearColor().CGColor ImgView.layer.mask = masklayer UIGraphicsBeginImageContext(ImgView.bounds.size); ImgView.layer.renderInContext(UIGraphicsGetCurrentContext()) var image = UIGraphicsGetImageFromCurrentImageContext() ImgView.image = image UIGraphicsEndImageContext(); 

更新:

  let rect: CGRect = CGRectMake(path.bounds.minX, path.bounds.minY, path.bounds.width, path.bounds.height) // Create bitmap image from context using the rect let imageRef: CGImageRef = CGImageCreateWithImageInRect(image.CGImage, rect) ImgView.bounds = rect ImgView.image = UIImage(CGImage: imageRef) 

我能够通过获取path.bound和size来改变我的ImageView的边界。 🙂

要获得作物的中心位置,可以将高度和宽度的差异减半。 然后,可以在检查图像的方向(哪个部分更长)后指定新宽度和高度的边界,

 func cropToBounds(image: UIImage, width: Double, height: Double) -> UIImage { let contextImage: UIImage = UIImage(CGImage: image.CGImage)! let contextSize: CGSize = contextImage.size var posX: CGFloat = 0.0 var posY: CGFloat = 0.0 var cgwidth: CGFloat = CGFloat(width) var cgheight: CGFloat = CGFloat(height) // See what size is longer and create the center off of that if contextSize.width > contextSize.height { posX = ((contextSize.width - contextSize.height) / 2) posY = 0 cgwidth = contextSize.height cgheight = contextSize.height } else { posX = 0 posY = ((contextSize.height - contextSize.width) / 2) cgwidth = contextSize.width cgheight = contextSize.width } let rect: CGRect = CGRectMake(posX, posY, cgwidth, cgheight) // Create bitmap image from context using the rect let imageRef: CGImageRef = CGImageCreateWithImageInRect(contextImage.CGImage, rect) // Create a new image based on the imageRef and rotate back to the original orientation let image: UIImage = UIImage(CGImage: imageRef, scale: image.scale, orientation: image.imageOrientation)! return image } 

如果您想进一步阅读,我在这个网站上发现了大部分信息。

被接受的答案只为我做广场。 我需要一个更灵活的裁剪机制,所以我写了一个扩展如下:

 import UIKit extension UIImage { func crop(to:CGSize) -> UIImage { guard let cgimage = self.CGImage else { return self } let contextImage: UIImage = UIImage(CGImage: cgimage) let contextSize: CGSize = contextImage.size //Set to square var posX: CGFloat = 0.0 var posY: CGFloat = 0.0 let cropAspect: CGFloat = to.width / to.height var cropWidth: CGFloat = to.width var cropHeight: CGFloat = to.height if to.width > to.height { //Landscape cropWidth = contextSize.width cropHeight = contextSize.width / cropAspect posY = (contextSize.height - cropHeight) / 2 } else if to.width < to.height { //Portrait cropHeight = contextSize.height cropWidth = contextSize.height * cropAspect posX = (contextSize.width - cropWidth) / 2 } else { //Square if contextSize.width >= contextSize.height { //Square on landscape (or square) cropHeight = contextSize.height cropWidth = contextSize.height * cropAspect posX = (contextSize.width - cropWidth) / 2 }else{ //Square on portrait cropWidth = contextSize.width cropHeight = contextSize.width / cropAspect posY = (contextSize.height - cropHeight) / 2 } } let rect: CGRect = CGRectMake(posX, posY, cropWidth, cropHeight) // Create bitmap image from context using the rect let imageRef: CGImageRef = CGImageCreateWithImageInRect(contextImage.CGImage, rect)! // Create a new image based on the imageRef and rotate back to the original orientation let cropped: UIImage = UIImage(CGImage: imageRef, scale: self.scale, orientation: self.imageOrientation) UIGraphicsBeginImageContextWithOptions(to, true, self.scale) cropped.drawInRect(CGRectMake(0, 0, to.width, to.height)) let resized = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return resized } } 

你可以这样使用它:

 let size = CGSize(width: 300, height: 200) let image = UIImage(named: "my_great_photo")?.crop(size) 

如果任何人有想法如何使景观,肖像和广场处理好一点让我知道。

你可以试试这个答案。 这是写在迅速3。

 extension UIImage { func crop(to:CGSize) -> UIImage { guard let cgimage = self.cgImage else { return self } let contextImage: UIImage = UIImage(cgImage: cgimage) let contextSize: CGSize = contextImage.size //Set to square var posX: CGFloat = 0.0 var posY: CGFloat = 0.0 let cropAspect: CGFloat = to.width / to.height var cropWidth: CGFloat = to.width var cropHeight: CGFloat = to.height if to.width > to.height { //Landscape cropWidth = contextSize.width cropHeight = contextSize.width / cropAspect posY = (contextSize.height - cropHeight) / 2 } else if to.width < to.height { //Portrait cropHeight = contextSize.height cropWidth = contextSize.height * cropAspect posX = (contextSize.width - cropWidth) / 2 } else { //Square if contextSize.width >= contextSize.height { //Square on landscape (or square) cropHeight = contextSize.height cropWidth = contextSize.height * cropAspect posX = (contextSize.width - cropWidth) / 2 }else{ //Square on portrait cropWidth = contextSize.width cropHeight = contextSize.width / cropAspect posY = (contextSize.height - cropHeight) / 2 } } let rect: CGRect = CGRect(x : posX, y : posY, width : cropWidth, height : cropHeight) // Create bitmap image from context using the rect let imageRef: CGImage = contextImage.cgImage!.cropping(to: rect)! // Create a new image based on the imageRef and rotate back to the original orientation let cropped: UIImage = UIImage(cgImage: imageRef, scale: self.scale, orientation: self.imageOrientation) cropped.draw(in: CGRect(x : 0, y : 0, width : to.width, height : to.height)) return cropped } } 

工作Swift 3的例子

 extension UIImage { func crop(to:CGSize) -> UIImage { guard let cgimage = self.cgImage else { return self } let contextImage: UIImage = UIImage(cgImage: cgimage) let contextSize: CGSize = contextImage.size //Set to square var posX: CGFloat = 0.0 var posY: CGFloat = 0.0 let cropAspect: CGFloat = to.width / to.height var cropWidth: CGFloat = to.width var cropHeight: CGFloat = to.height if to.width > to.height { //Landscape cropWidth = contextSize.width cropHeight = contextSize.width / cropAspect posY = (contextSize.height - cropHeight) / 2 } else if to.width < to.height { //Portrait cropHeight = contextSize.height cropWidth = contextSize.height * cropAspect posX = (contextSize.width - cropWidth) / 2 } else { //Square if contextSize.width >= contextSize.height { //Square on landscape (or square) cropHeight = contextSize.height cropWidth = contextSize.height * cropAspect posX = (contextSize.width - cropWidth) / 2 }else{ //Square on portrait cropWidth = contextSize.width cropHeight = contextSize.width / cropAspect posY = (contextSize.height - cropHeight) / 2 } } let rect: CGRect = CGRect(x: posX, y: posY, width: cropWidth, height: cropHeight) // Create bitmap image from context using the rect let imageRef: CGImage = contextImage.cgImage!.cropping(to: rect)! // Create a new image based on the imageRef and rotate back to the original orientation let cropped: UIImage = UIImage(cgImage: imageRef, scale: self.scale, orientation: self.imageOrientation) UIGraphicsBeginImageContextWithOptions(to, true, self.scale) cropped.draw(in: CGRect(x: 0, y: 0, width: to.width, height: to.height)) let resized = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return resized! } } 

道具Cole

Swift 3

 func crop(image: UIImage, withWidth width: Double, andHeight height: Double) -> UIImage? { if let cgImage = image.cgImage { let contextImage: UIImage = UIImage(cgImage: cgImage) let contextSize: CGSize = contextImage.size var posX: CGFloat = 0.0 var posY: CGFloat = 0.0 var cgwidth: CGFloat = CGFloat(width) var cgheight: CGFloat = CGFloat(height) // See what size is longer and create the center off of that if contextSize.width > contextSize.height { posX = ((contextSize.width - contextSize.height) / 2) posY = 0 cgwidth = contextSize.height cgheight = contextSize.height } else { posX = 0 posY = ((contextSize.height - contextSize.width) / 2) cgwidth = contextSize.width cgheight = contextSize.width } let rect: CGRect = CGRect(x: posX, y: posY, width: cgwidth, height: cgheight) // Create bitmap image from context using the rect var croppedContextImage: CGImage? = nil if let contextImage = contextImage.cgImage { if let croppedImage = contextImage.cropping(to: rect) { croppedContextImage = croppedImage } } // Create a new image based on the imageRef and rotate back to the original orientation if let croppedImage:CGImage = croppedContextImage { let image: UIImage = UIImage(cgImage: croppedImage, scale: image.scale, orientation: image.imageOrientation) return image } } return nil } 

改变这个:

 masklayer.frame = ImgView.frame 

对此:

 masklayer.frame = ImgView.bounds 

您也可以非常简单地将相关的ImageView放置在故事板的“Aspect Fill”模式中,并将其添加到代码中:

 imageView.layer.masksToBound = true imageView.clipsToBounds = true 

接受的答案不适合我,所以我试着写我自己的。 这是我的工作的效果:

 import UIKit extension UIImage { func cropedToRatio(ratio: CGFloat) -> UIImage? { let newImageWidth = size.height * ratio let cropRect = CGRect(x: ((size.width - newImageWidth) / 2.0) * scale, y: 0.0, width: newImageWidth * scale, height: size.height * scale) guard let cgImage = cgImage else { return nil } guard let newCgImage = cgImage.cropping(to: cropRect) else { return nil } return UIImage(cgImage: newCgImage, scale: scale, orientation: imageOrientation) } } 

这个function裁剪图像给定的比例。 它保持图像的规模。 裁切的图像始终是原始图像的中心。