Я изо всех сил пытался изменить размер изображения. В основном я наткнулся на: как уменьшить масштаб UIImage и сделать его одновременно хрустящим / резким, а не размытым?
Это кажется правильным решением, но почему-то работает некорректно.
Мое приложение работает с фотографиями из камеры. Размер этих фотографий должен быть уменьшен примерно до 200x200, тогда как ширина важна, а не высота.
К сожалению, у меня нет образца кода, так как я отбросил его в ярости из-за неработающего решения, извините.
Ответы:
Вот мой код. Изображение имеет ширину 850 пикселей, а не 200 пикселей:
func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage { let scale = newWidth / image.size.width let newHeight = image.size.height * scale UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight)) image.drawInRect(CGRectMake(0, 0, newWidth, newHeight)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage } @IBAction func chooseImage(sender: AnyObject) { var myPickerController = UIImagePickerController() myPickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary myPickerController.delegate = self; self.presentViewController(myPickerController, animated: true, completion: nil) } func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) { var imagenow = info[UIImagePickerControllerOriginalImage] as? UIImage imageImage.image = resizeImage(imagenow!, newWidth: 200) pimg2 = imageImage.image! cidnew2 = textFieldCID!.text! pname2 = textFieldName!.text pmanu2 = textFieldMan!.text pnick2 = textFieldNick!.text podate2 = textFieldPODate!.text pno2 = textFieldArtNo!.text self.dismissViewControllerAnimated(true, completion: nil) }
источник
func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage { let scale = newWidth / image.size.width let newHeight = image.size.height * scale UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight)) image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! }
На основе ответа swift_dan обновление для Swift 3
func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage? { let scale = newWidth / image.size.width let newHeight = image.size.height * scale UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight)) image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage }
источник
Если вы имеете дело с изображениями PNG, которые содержат прозрачные пленки, то функция принятого ответа фактически преобразует прозрачные области в черные.
Если вы хотите масштабировать и сохранять прозрачность на месте, попробуйте эту функцию:
SWIFT 4
extension UIImage { func scaleImage(toSize newSize: CGSize) -> UIImage? { var newImage: UIImage? let newRect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height).integral UIGraphicsBeginImageContextWithOptions(newSize, false, 0) if let context = UIGraphicsGetCurrentContext(), let cgImage = self.cgImage { context.interpolationQuality = .high let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: newSize.height) context.concatenate(flipVertical) context.draw(cgImage, in: newRect) if let img = context.makeImage() { newImage = UIImage(cgImage: img) } UIGraphicsEndImageContext() } return newImage } }
источник
let scale = UIScreen.main.scale let newImage = UIImage(cgImage: context.makeImage()!, scale: scale, orientation: .up)
просто добавьте этот фрагмент в качестве расширения к
UIImage
. Однако помните, что изображение не будет квадратным, но если оно было в такой форме, результат будет квадратным.extension UIImage { func resizeImage(newWidth: CGFloat) -> UIImage { let scale = newWidth / self.size.width let newHeight = self.size.height * scale UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight)) self.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } }
источник
Swift 4.0 -
Если вы имеете дело с изображениями, которые содержат прозрачные пленки, то функция принятого ответа фактически преобразует прозрачные области в черные.
Если вы хотите масштабировать и сохранять прозрачность на месте, попробуйте эту функцию:
func resizeImageWith(image: UIImage, newSize: CGSize) -> UIImage { let horizontalRatio = newSize.width / image.size.width let verticalRatio = newSize.height / image.size.height let ratio = max(horizontalRatio, verticalRatio) let newSize = CGSize(width: image.size.width * ratio, height: image.size.height * ratio) var newImage: UIImage if #available(iOS 10.0, *) { let renderFormat = UIGraphicsImageRendererFormat.default() renderFormat.opaque = false let renderer = UIGraphicsImageRenderer(size: CGSize(width: newSize.width, height: newSize.height), format: renderFormat) newImage = renderer.image { (context) in image.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)) } } else { UIGraphicsBeginImageContextWithOptions(CGSize(width: newSize.width, height: newSize.height), isOpaque, 0) image.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)) newImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() } return newImage }
источник
В этом коде используется UIGraphicsImageRenderer, представленный в iOS 10: в моем тестировании он был на 10-40% быстрее, чем предыдущие образцы с UIGraphicsBeginImageContext (Swift 4 / Xcode 9):
extension UIImage { func renderResizedImage (newWidth: CGFloat) -> UIImage { let scale = newWidth / self.size.width let newHeight = self.size.height * scale let newSize = CGSize(width: newWidth, height: newHeight) let renderer = UIGraphicsImageRenderer(size: newSize) let image = renderer.image { (context) in self.draw(in: CGRect(origin: CGPoint(x: 0, y: 0), size: newSize)) } return image } }
источник
Эта функция вернет изображение указанной вами ширины :
func scaleImage(image: UIImage, maximumWidth: CGFloat) -> UIImage { let rect: CGRect = CGRectMake(0, 0, image.size.width, image.size.height) let cgImage: CGImageRef = CGImageCreateWithImageInRect(image.CGImage!, rect)! return UIImage(CGImage: cgImage, scale: image.size.width / maximumWidth, orientation: image.imageOrientation) }
Swift 3.0
func scaledImage(_ image: UIImage, maximumWidth: CGFloat) -> UIImage { let rect: CGRect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height) let cgImage: CGImage = image.cgImage!.cropping(to: rect)! return UIImage(cgImage: cgImage, scale: image.size.width / maximumWidth, orientation: image.imageOrientation) }
источник
Дальнейшее улучшение ответа @rommex с использованием максимального размера в Swift 4.2:
private extension UIImage { func scaled(to maxSize: CGFloat) -> UIImage? { let aspectRatio: CGFloat = min(maxSize / size.width, maxSize / size.height) let newSize = CGSize(width: size.width * aspectRatio, height: size.height * aspectRatio) let renderer = UIGraphicsImageRenderer(size: newSize) return renderer.image { context in draw(in: CGRect(origin: CGPoint(x: 0, y: 0), size: newSize)) } } }
источник
Этот код отлично работает на квадратном изображении и не потеряет в качестве
extension UIImage { func resize(targetSize: CGSize) -> UIImage { return UIGraphicsImageRenderer(size:targetSize).image { _ in self.draw(in: CGRect(origin: .zero, size: targetSize)) } } }
Ответ от: Изменить размер изображения без потери качества
источник
Если вы используете Kingfisher lib для загрузки изображений в свой проект и хотите изменить его размер, вот способ:
let imageUrl = URL(string: "your image url") //Size refer to the size which you want to resize your original image let size = CGSize(width: 60, height: 60) let processImage = ResizingImageProcessor(targetSize: size, contentMode: .aspectFit) cell.courseTitleImage.kf.setImage(with: imageUrl! , placeholder: UIImage(named: "placeholder"), options: [.transition(ImageTransition.fade(1)), .processor(processImage)], progressBlock: nil, completionHandler: nil)
ИЛИ ЖЕ
Изменить размер локального изображения: - вы можете обратиться к ответу @Christoph R
источник
func getScaledDimension(width: CGFloat, height: CGFloat,new_width: CGFloat, new_height: CGFloat)->CGPoint { let widthAspect = (width / new_width) let heightAspect = (height / new_height) if widthAspect == 0 || heightAspect == 0 { return CGPoint(x: width, y: height) } var width1 : CGFloat = 0 var height1 : CGFloat = 0 if widthAspect > heightAspect { width1 = (width) / heightAspect height1 = (height) / heightAspect } else { width1 = (width) / widthAspect height1 = (height) / widthAspect } return CGPoint(x: width1, y: height1 ) } func ResizeImage(image: UIImage, targetSize: CGSize) -> UIImage { let rect = CGRectMake(0, 0, targetSize.width, targetSize.height) UIGraphicsBeginImageContextWithOptions(targetSize, false, 1.0) image.drawInRect(rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage } let imagesize = getScaledDimension(image.size.width, height: image.size.height , new_width: Width, new_height: Hieght) print("Image Size Scaled Dimension -> H:\(imagesize.x) W:\(imagesize.y)") let newImage = ResizeImage(image, targetSize: CGSizeMake(imagesize.x,imagesize.y)) print("Resize Image Size -> H\(newImage.size.height) W\(newImage.size.width) ")
источник
Это продолжение ответа @Christoph R, опубликованного для Swift 3.0. Этот код работает для Swift 5.0.1.
static func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage { let scale = newWidth / image.size.width let newHeight = image.size.height * scale UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight)) image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! }
на сайте звонящего
TaskUtilties.resizeImage(image: rawImage!, newWidth: CGFloat(50))
источник
Уменьшите размер изображения на 1024, вы всегда можете конвертировать в соответствии с мощностью сервера
func resizeImage(image: UIImage) -> UIImage { if image.size.height >= 1024 && image.size.width >= 1024 { UIGraphicsBeginImageContext(CGSize(width:1024, height:1024)) image.draw(in: CGRect(x:0, y:0, width:1024, height:1024)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } else if image.size.height >= 1024 && image.size.width < 1024 { UIGraphicsBeginImageContext(CGSize(width:image.size.width, height:1024)) image.draw(in: CGRect(x:0, y:0, width:image.size.width, height:1024)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } else if image.size.width >= 1024 && image.size.height < 1024 { UIGraphicsBeginImageContext(CGSize(width:1024, height:image.size.height)) image.draw(in: CGRect(x:0, y:0, width:1024, height:image.size.height)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } else { return image } }
источник