我想为正在执行的项目调整位图的大小。我设法通过将cgbitmapcontextref转换为像素数组,然后操纵像素数组,然后从操纵的像素数据生成新图像来做到这一点。这种方式非常麻烦。
我想知道是否还有其他方法可以调整CGBitmapContextRef的大小。谢谢。
如果您不愿意CGBitmapContextRef,这里有一些基于UIKit的简单图像大小调整例程。此扩展通过裁剪,缩放,宽高比填充和宽高比拟合(类似于UIImageView提供的一些主要内容模式)来提供调整图像大小的功能。
CGBitmapContextRef
// // UIImage+Resize.swift // // Image resizing extension // // Created by Robert Ryan on 19-May-11. // Ported to Swift by Robert Ryan on 12-Feb-15. // Modified for Swift 2 by Robert Ryan on 14-Oct-15 // Modified for Swift 3 by Robert Ryan on 26-May-17 // Modified for Swift 4 by Robert Ryan on 15-Feb-19 // // Inspired by http://ofcodeandmen.poltras.com/2008/10/30/undocumented-uiimage-resizing/ // but adjusted to support AspectFill and AspectFit modes. // // Copyright (c) 2015 Robert M. Ryan. All rights reserved. // // This work by Robert M. Ryan is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. // http://creativecommons.org/licenses/by-sa/4.0/ import UIKit extension UIImage { /// Resize the image to be the required size, stretching it as needed. /// /// - parameter newSize: The new size of the image. /// - parameter contentMode: The `UIView.ContentMode` to be applied when resizing image. /// Either `.scaleToFill`, `.scaleAspectFill`, or `.scaleAspectFit`. /// /// - returns: Return `UIImage` of resized image. func scaled(to newSize: CGSize, contentMode: UIView.ContentMode = .scaleToFill) -> UIImage? { switch contentMode { case .scaleToFill: return filled(to: newSize) case .scaleAspectFill, .scaleAspectFit: let horizontalRatio = size.width / newSize.width let verticalRatio = size.height / newSize.height let ratio: CGFloat! if contentMode == .scaleAspectFill { ratio = min(horizontalRatio, verticalRatio) } else { ratio = max(horizontalRatio, verticalRatio) } let sizeForAspectScale = CGSize(width: size.width / ratio, height: size.height / ratio) let image = filled(to: sizeForAspectScale) let doesAspectFitNeedCropping = contentMode == .scaleAspectFit && (newSize.width > sizeForAspectScale.width || newSize.height > sizeForAspectScale.height) if contentMode == .scaleAspectFill || doesAspectFitNeedCropping { let subRect = CGRect( x: floor((sizeForAspectScale.width - newSize.width) / 2.0), y: floor((sizeForAspectScale.height - newSize.height) / 2.0), width: newSize.width, height: newSize.height) return image?.cropped(to: subRect) } return image default: return nil } } /// Resize the image to be the required size, stretching it as needed. /// /// - parameter newSize: The new size of the image. /// /// - returns: Resized `UIImage` of resized image. func filled(to newSize: CGSize) -> UIImage? { let format = UIGraphicsImageRendererFormat() format.opaque = false format.scale = scale return UIGraphicsImageRenderer(size: newSize, format: format).image { _ in draw(in: CGRect(origin: .zero, size: newSize)) } } /// Crop the image to be the required size. /// /// - parameter bounds: The bounds to which the new image should be cropped. /// /// - returns: Cropped `UIImage`. func cropped(to bounds: CGRect) -> UIImage? { // if bounds is entirely within image, do simple CGImage `cropping` ... if CGRect(origin: .zero, size: size).contains(bounds) { return cgImage?.cropping(to: bounds * scale).flatMap { UIImage(cgImage: $0, scale: scale, orientation: imageOrientation) } } // ... otherwise, manually render whole image, only drawing what we need let format = UIGraphicsImageRendererFormat() format.opaque = false format.scale = scale return UIGraphicsImageRenderer(size: bounds.size, format: format).image { _ in let origin = CGPoint(x: -bounds.minX, y: -bounds.minY) draw(in: CGRect(origin: origin, size: size)) } } /// Resize the image to fill the rectange of the specified size, preserving the aspect ratio, trimming if needed. /// /// - parameter newSize: The new size of the image. /// /// - returns: Return `UIImage` of resized image. func scaledAspectFill(to newSize: CGSize) -> UIImage? { return scaled(to: newSize, contentMode: .scaleAspectFill) } /// Resize the image to fit within the required size, preserving the aspect ratio, with no trimming taking place. /// /// - parameter newSize: The new size of the image. /// /// - returns: Return `UIImage` of resized image. func scaledAspectFit(to newSize: CGSize) -> UIImage? { return scaled(to: newSize, contentMode: .scaleAspectFit) } } extension CGSize { static func * (lhs: CGSize, rhs: CGFloat) -> CGSize { return CGSize(width: lhs.width * rhs, height: lhs.height * rhs) } } extension CGPoint { static func * (lhs: CGPoint, rhs: CGFloat) -> CGPoint { return CGPoint(x: lhs.x * rhs, y: lhs.y * rhs) } } extension CGRect { static func * (lhs: CGRect, rhs: CGFloat) -> CGRect { return CGRect(origin: lhs.origin * rhs, size: lhs.size * rhs) } }
对于Swift 2复制,请参阅此答案的先前版本。