[英]How to Resize image in Swift?
我正在為 iOS 制作一個應用程序,使用Swift和 Parse.com
我試圖讓用戶 select 從圖像選擇器中獲取圖片,然后在上傳到我的后端之前將所選圖像調整為 200x200 像素。
Parse.com 有一個名為“AnyPic”的 Instagram 復制應用程序的教程,它提供了用於調整圖像大小的代碼,但它位於 Objective-C ....
// Resize the image to be square (what is shown in the preview)
UIImage *resizedImage = [anImage resizedImageWithContentMode:UIViewContentModeScaleAspectFit
bounds:CGSizeMake(560.0f, 560.0f)
interpolationQuality:kCGInterpolationHigh];
// Create a thumbnail and add a corner radius for use in table views
UIImage *thumbnailImage = [anImage thumbnailImage:86.0f
transparentBorder:0.0f
cornerRadius:10.0f
interpolationQuality:kCGInterpolationDefault];
我如何在 Swift 中創建所選圖片的 200x200px 版本(然后上傳)?
而且,thumbnailImage function 在做什么?
有關更多詳細信息,請參閱我的博客文章Resize image in swift andobjective C 。
快速調整圖像大小功能,如下所示。
func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage? {
let size = image.size
let widthRatio = targetSize.width / size.width
let heightRatio = targetSize.height / size.height
// Figure out what our orientation is, and use that to form the rectangle
var newSize: CGSize
if(widthRatio > heightRatio) {
newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
} else {
newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
}
// This is the rect that we've calculated out and this is what is actually used below
let rect = CGRect(origin: .zero, size: newSize)
// Actually do the resizing to the rect using the ImageContext stuff
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
image.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
使用上面的函數並用 200*200 調整圖像大小,如下代碼
self.resizeImage(UIImage(named: "yourImageName")!, targetSize: CGSizeMake(200.0, 200.0))
swift3 更新
func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage {
let size = image.size
let widthRatio = targetSize.width / size.width
let heightRatio = targetSize.height / size.height
// Figure out what our orientation is, and use that to form the rectangle
var newSize: CGSize
if(widthRatio > heightRatio) {
newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
} else {
newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
}
// This is the rect that we've calculated out and this is what is actually used below
let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
// Actually do the resizing to the rect using the ImageContext stuff
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
image.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
適用於 Swift 4.0 和 iOS 10
extension UIImage {
func resizeImage(_ dimension: CGFloat, opaque: Bool, contentMode: UIViewContentMode = .scaleAspectFit) -> UIImage {
var width: CGFloat
var height: CGFloat
var newImage: UIImage
let size = self.size
let aspectRatio = size.width/size.height
switch contentMode {
case .scaleAspectFit:
if aspectRatio > 1 { // Landscape image
width = dimension
height = dimension / aspectRatio
} else { // Portrait image
height = dimension
width = dimension * aspectRatio
}
default:
fatalError("UIIMage.resizeToFit(): FATAL: Unimplemented ContentMode")
}
if #available(iOS 10.0, *) {
let renderFormat = UIGraphicsImageRendererFormat.default()
renderFormat.opaque = opaque
let renderer = UIGraphicsImageRenderer(size: CGSize(width: width, height: height), format: renderFormat)
newImage = renderer.image {
(context) in
self.draw(in: CGRect(x: 0, y: 0, width: width, height: height))
}
} else {
UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), opaque, 0)
self.draw(in: CGRect(x: 0, y: 0, width: width, height: height))
newImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
}
return newImage
}
}
由於@KiritModi 的回答是從 2015 年開始的,因此這是 Swift 3.0 的版本:
func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage {
let size = image.size
let widthRatio = targetSize.width / image.size.width
let heightRatio = targetSize.height / image.size.height
// Figure out what our orientation is, and use that to form the rectangle
var newSize: CGSize
if(widthRatio > heightRatio) {
newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
} else {
newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
}
// This is the rect that we've calculated out and this is what is actually used below
let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
// Actually do the resizing to the rect using the ImageContext stuff
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
image.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
import UIKit
import CoreGraphics
import Accelerate
extension UIImage {
public enum ResizeFramework {
case uikit, coreImage, coreGraphics, imageIO, accelerate
}
/// Resize image with ScaleAspectFit mode and given size.
///
/// - Parameter dimension: width or length of the image output.
/// - Parameter resizeFramework: Technique for image resizing: UIKit / CoreImage / CoreGraphics / ImageIO / Accelerate.
/// - Returns: Resized image.
func resizeWithScaleAspectFitMode(to dimension: CGFloat, resizeFramework: ResizeFramework = .coreGraphics) -> UIImage? {
if max(size.width, size.height) <= dimension { return self }
var newSize: CGSize!
let aspectRatio = size.width/size.height
if aspectRatio > 1 {
// Landscape image
newSize = CGSize(width: dimension, height: dimension / aspectRatio)
} else {
// Portrait image
newSize = CGSize(width: dimension * aspectRatio, height: dimension)
}
return resize(to: newSize, with: resizeFramework)
}
/// Resize image from given size.
///
/// - Parameter newSize: Size of the image output.
/// - Parameter resizeFramework: Technique for image resizing: UIKit / CoreImage / CoreGraphics / ImageIO / Accelerate.
/// - Returns: Resized image.
public func resize(to newSize: CGSize, with resizeFramework: ResizeFramework = .coreGraphics) -> UIImage? {
switch resizeFramework {
case .uikit: return resizeWithUIKit(to: newSize)
case .coreGraphics: return resizeWithCoreGraphics(to: newSize)
case .coreImage: return resizeWithCoreImage(to: newSize)
case .imageIO: return resizeWithImageIO(to: newSize)
case .accelerate: return resizeWithAccelerate(to: newSize)
}
}
// MARK: - UIKit
/// Resize image from given size.
///
/// - Parameter newSize: Size of the image output.
/// - Returns: Resized image.
private func resizeWithUIKit(to newSize: CGSize) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(newSize, true, 1.0)
self.draw(in: CGRect(origin: .zero, size: newSize))
defer { UIGraphicsEndImageContext() }
return UIGraphicsGetImageFromCurrentImageContext()
}
// MARK: - CoreImage
/// Resize CI image from given size.
///
/// - Parameter newSize: Size of the image output.
/// - Returns: Resized image.
// https://developer.apple.com/library/archive/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html
private func resizeWithCoreImage(to newSize: CGSize) -> UIImage? {
guard let cgImage = cgImage, let filter = CIFilter(name: "CILanczosScaleTransform") else { return nil }
let ciImage = CIImage(cgImage: cgImage)
let scale = (Double)(newSize.width) / (Double)(ciImage.extent.size.width)
filter.setValue(ciImage, forKey: kCIInputImageKey)
filter.setValue(NSNumber(value:scale), forKey: kCIInputScaleKey)
filter.setValue(1.0, forKey: kCIInputAspectRatioKey)
guard let outputImage = filter.value(forKey: kCIOutputImageKey) as? CIImage else { return nil }
let context = CIContext(options: [.useSoftwareRenderer: false])
guard let resultCGImage = context.createCGImage(outputImage, from: outputImage.extent) else { return nil }
return UIImage(cgImage: resultCGImage)
}
// MARK: - CoreGraphics
/// Resize image from given size.
///
/// - Parameter newSize: Size of the image output.
/// - Returns: Resized image.
private func resizeWithCoreGraphics(to newSize: CGSize) -> UIImage? {
guard let cgImage = cgImage, let colorSpace = cgImage.colorSpace else { return nil }
let width = Int(newSize.width)
let height = Int(newSize.height)
let bitsPerComponent = cgImage.bitsPerComponent
let bytesPerRow = cgImage.bytesPerRow
let bitmapInfo = cgImage.bitmapInfo
guard let context = CGContext(data: nil, width: width, height: height,
bitsPerComponent: bitsPerComponent,
bytesPerRow: bytesPerRow, space: colorSpace,
bitmapInfo: bitmapInfo.rawValue) else { return nil }
context.interpolationQuality = .high
let rect = CGRect(origin: CGPoint.zero, size: newSize)
context.draw(cgImage, in: rect)
return context.makeImage().flatMap { UIImage(cgImage: $0) }
}
// MARK: - ImageIO
/// Resize image from given size.
///
/// - Parameter newSize: Size of the image output.
/// - Returns: Resized image.
private func resizeWithImageIO(to newSize: CGSize) -> UIImage? {
var resultImage = self
guard let data = jpegData(compressionQuality: 1.0) else { return resultImage }
let imageCFData = NSData(data: data) as CFData
let options = [
kCGImageSourceCreateThumbnailWithTransform: true,
kCGImageSourceCreateThumbnailFromImageAlways: true,
kCGImageSourceThumbnailMaxPixelSize: max(newSize.width, newSize.height)
] as CFDictionary
guard let source = CGImageSourceCreateWithData(imageCFData, nil),
let imageReference = CGImageSourceCreateThumbnailAtIndex(source, 0, options) else { return resultImage }
resultImage = UIImage(cgImage: imageReference)
return resultImage
}
// MARK: - Accelerate
/// Resize image from given size.
///
/// - Parameter newSize: Size of the image output.
/// - Returns: Resized image.
private func resizeWithAccelerate(to newSize: CGSize) -> UIImage? {
var resultImage = self
guard let cgImage = cgImage, let colorSpace = cgImage.colorSpace else { return nil }
// create a source buffer
var format = vImage_CGImageFormat(bitsPerComponent: numericCast(cgImage.bitsPerComponent),
bitsPerPixel: numericCast(cgImage.bitsPerPixel),
colorSpace: Unmanaged.passUnretained(colorSpace),
bitmapInfo: cgImage.bitmapInfo,
version: 0,
decode: nil,
renderingIntent: .absoluteColorimetric)
var sourceBuffer = vImage_Buffer()
defer {
sourceBuffer.data.deallocate()
}
var error = vImageBuffer_InitWithCGImage(&sourceBuffer, &format, nil, cgImage, numericCast(kvImageNoFlags))
guard error == kvImageNoError else { return resultImage }
// create a destination buffer
let destWidth = Int(newSize.width)
let destHeight = Int(newSize.height)
let bytesPerPixel = cgImage.bitsPerPixel
let destBytesPerRow = destWidth * bytesPerPixel
let destData = UnsafeMutablePointer<UInt8>.allocate(capacity: destHeight * destBytesPerRow)
defer {
destData.deallocate()
}
var destBuffer = vImage_Buffer(data: destData, height: vImagePixelCount(destHeight), width: vImagePixelCount(destWidth), rowBytes: destBytesPerRow)
// scale the image
error = vImageScale_ARGB8888(&sourceBuffer, &destBuffer, nil, numericCast(kvImageHighQualityResampling))
guard error == kvImageNoError else { return resultImage }
// create a CGImage from vImage_Buffer
let destCGImage = vImageCreateCGImageFromBuffer(&destBuffer, &format, nil, nil, numericCast(kvImageNoFlags), &error)?.takeRetainedValue()
guard error == kvImageNoError else { return resultImage }
// create a UIImage
if let scaledImage = destCGImage.flatMap({ UIImage(cgImage: $0) }) {
resultImage = scaledImage
}
return resultImage
}
}
獲取圖像大小
import UIKit
// https://stackoverflow.com/a/55765409/4488252
extension UIImage {
func getFileSizeInfo(allowedUnits: ByteCountFormatter.Units = .useMB,
countStyle: ByteCountFormatter.CountStyle = .memory,
compressionQuality: CGFloat = 1.0) -> String? {
// https://developer.apple.com/documentation/foundation/bytecountformatter
let formatter = ByteCountFormatter()
formatter.allowedUnits = allowedUnits
formatter.countStyle = countStyle
return getSizeInfo(formatter: formatter, compressionQuality: compressionQuality)
}
func getSizeInfo(formatter: ByteCountFormatter, compressionQuality: CGFloat = 1.0) -> String? {
guard let imageData = jpegData(compressionQuality: compressionQuality) else { return nil }
return formatter.string(fromByteCount: Int64(imageData.count))
}
}
測試功能
private func test() {
guard let img = UIImage(named: "img") else { return }
printInfo(of: img, title: "original image |")
let dimension: CGFloat = 2000
var framework: UIImage.ResizeFramework = .accelerate
var startTime = Date()
if let img = img.resizeWithScaleAspectFitMode(to: dimension, resizeFramework: framework) {
printInfo(of: img, title: "resized image |", with: framework, startedTime: startTime)
}
framework = .coreGraphics
startTime = Date()
if let img = img.resizeWithScaleAspectFitMode(to: dimension, resizeFramework: framework) {
printInfo(of: img, title: "resized image |", with: framework, startedTime: startTime)
}
framework = .coreImage
startTime = Date()
if let img = img.resizeWithScaleAspectFitMode(to: dimension, resizeFramework: framework) {
printInfo(of: img, title: "resized image |", with: framework, startedTime: startTime)
}
framework = .imageIO
startTime = Date()
if let img = img.resizeWithScaleAspectFitMode(to: dimension, resizeFramework: framework) {
printInfo(of: img, title: "resized image |", with: framework, startedTime: startTime)
}
framework = .uikit
startTime = Date()
if let img = img.resizeWithScaleAspectFitMode(to: dimension, resizeFramework: framework) {
printInfo(of: img, title: "resized image |", with: framework, startedTime: startTime)
}
}
private func printInfo(of image: UIImage, title: String, with resizeFramework: UIImage.ResizeFramework? = nil, startedTime: Date? = nil) {
var description = "\(title) \(image.size)"
if let startedTime = startedTime { description += ", execution time: \(Date().timeIntervalSince(startedTime))" }
if let fileSize = image.getFileSizeInfo(compressionQuality: 0.9) { description += ", size: \(fileSize)" }
if let resizeFramework = resizeFramework { description += ", framework: \(resizeFramework)" }
print(description)
}
original image | (5790.0, 8687.0), size: 17.1 MB
resized image | (1333.0, 2000.0), execution time: 0.8192930221557617, size: 1.1 MB, framework: accelerate
resized image | (1333.0, 2000.0), execution time: 0.44696998596191406, size: 1 MB, framework: coreGraphics
resized image | (1334.0, 2000.0), execution time: 54.172922015190125, size: 1.1 MB, framework: coreImage
resized image | (1333.0, 2000.0), execution time: 1.8765920400619507, size: 1.1 MB, framework: imageIO
resized image | (1334.0, 2000.0), execution time: 0.4638739824295044, size: 1 MB, framework: uikit
對於 Swift 4,我只會在 UIImage 上進行擴展,並引用 self.
import UIKit
extension UIImage {
func resizeImage(targetSize: CGSize) -> UIImage {
let size = self.size
let widthRatio = targetSize.width / size.width
let heightRatio = targetSize.height / size.height
let newSize = widthRatio > heightRatio ? CGSize(width: size.width * heightRatio, height: size.height * heightRatio) : CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
self.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
}
也可以使用 AlamofireImage ( https://github.com/Alamofire/AlamofireImage )
let size = CGSize(width: 30.0, height: 30.0)
let aspectScaledToFitImage = image.af_imageAspectScaled(toFit: size)
上一篇文章中的函數給了我一個模糊的結果。
適用於 Swift 5.0 和 iOS 12
extension UIImage {
func imageResized(to size: CGSize) -> UIImage {
return UIGraphicsImageRenderer(size: size).image { _ in
draw(in: CGRect(origin: .zero, size: size))
}
}
}
用:
let image = #imageLiteral(resourceName: "ic_search")
cell!.search.image = image.imageResized(to: cell!.search.frame.size)
Swift 3 版本和擴展風格
這個答案來自@Kirit Modi。
extension UIImage {
func resizeImage(targetSize: CGSize) -> UIImage {
let size = self.size
let widthRatio = targetSize.width / size.width
let heightRatio = targetSize.height / size.height
// Figure out what our orientation is, and use that to form the rectangle
var newSize: CGSize
if(widthRatio > heightRatio) {
newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
} else {
newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
}
// This is the rect that we've calculated out and this is what is actually used below
let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
// Actually do the resizing to the rect using the ImageContext stuff
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
self.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
}
Swift 4,擴展版,邊緣無白線。
似乎沒有人提到如果使用非整數值調用image.draw()
,則生成的圖像可能會在右側或底部邊緣顯示白線偽影。
extension UIImage {
func scaled(with scale: CGFloat) -> UIImage? {
// size has to be integer, otherwise it could get white lines
let size = CGSize(width: floor(self.size.width * scale), height: floor(self.size.height * scale))
UIGraphicsBeginImageContext(size)
draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
斯威夫特 4 版本
extension UIImage {
func resizeImage(_ newSize: CGSize) -> UIImage? {
func isSameSize(_ newSize: CGSize) -> Bool {
return size == newSize
}
func scaleImage(_ newSize: CGSize) -> UIImage? {
func getScaledRect(_ newSize: CGSize) -> CGRect {
let ratio = max(newSize.width / size.width, newSize.height / size.height)
let width = size.width * ratio
let height = size.height * ratio
return CGRect(x: 0, y: 0, width: width, height: height)
}
func _scaleImage(_ scaledRect: CGRect) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(scaledRect.size, false, 0.0);
draw(in: scaledRect)
let image = UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()
UIGraphicsEndImageContext()
return image
}
return _scaleImage(getScaledRect(newSize))
}
return isSameSize(newSize) ? self : scaleImage(newSize)!
}
}
更新的Swift 5版本使用最新的UIGraphicsImageRenderer
API。
extension UIImage {
public func resized(to target: CGSize) -> UIImage {
let ratio = min(
target.height / size.height, target.width / size.width
)
let new = CGSize(
width: size.width * ratio, height: size.height * ratio
)
let renderer = UIGraphicsImageRenderer(size: new)
return renderer.image { _ in
self.draw(in: CGRect(origin: .zero, size: new))
}
}
}
UIImage 擴展Swift 5
extension UIImage {
func resize(_ width: CGFloat, _ height:CGFloat) -> UIImage? {
let widthRatio = width / size.width
let heightRatio = height / size.height
let ratio = widthRatio > heightRatio ? heightRatio : widthRatio
let newSize = CGSize(width: size.width * ratio, height: size.height * ratio)
let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
self.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
使用: UIImage().resize(200, 300)
到目前為止,所有列出的答案似乎都會導致圖像尺寸縮小,但是尺寸不是以像素為單位測量的。 這是一個Swift 5,基於像素的 resize 。
extension UIImage {
func resize(_ max_size: CGFloat) -> UIImage {
// adjust for device pixel density
let max_size_pixels = max_size / UIScreen.main.scale
// work out aspect ratio
let aspectRatio = size.width/size.height
// variables for storing calculated data
var width: CGFloat
var height: CGFloat
var newImage: UIImage
if aspectRatio > 1 {
// landscape
width = max_size_pixels
height = max_size_pixels / aspectRatio
} else {
// portrait
height = max_size_pixels
width = max_size_pixels * aspectRatio
}
// create an image renderer of the correct size
let renderer = UIGraphicsImageRenderer(size: CGSize(width: width, height: height), format: UIGraphicsImageRendererFormat.default())
// render the image
newImage = renderer.image {
(context) in
self.draw(in: CGRect(x: 0, y: 0, width: width, height: height))
}
// return the image
return newImage
}
}
用法:
image.resize(500)
Swift 4 解決方案-
使用這個功能
func image(with image: UIImage, scaledTo newSize: CGSize) -> UIImage {
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
image.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
drawingImageView.image = newImage
return newImage ?? UIImage()
}
調用函數:-
image(with: predictionImage, scaledTo: CGSize(width: 28.0, height: 28.0)
這里 28.0 是您要設置的像素大小
Swift 4.2 版本的@KiritModi 答案
func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage {
let size = image.size
let widthRatio = targetSize.width / size.width
let heightRatio = targetSize.height / size.height
var newSize: CGSize
if(widthRatio > heightRatio) {
newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
} else {
newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
}
let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
image.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
這是縮小圖像以適應尺寸的通用方法(在 Swift 5 中)。 生成的圖像可以與原始圖像具有相同的縱橫比,也可以是目標尺寸,原始圖像居中。 如果圖像小於目標尺寸,則不會調整其大小。
extension UIImage {
func scaledDown(into size:CGSize, centered:Bool = false) -> UIImage {
var (targetWidth, targetHeight) = (self.size.width, self.size.height)
var (scaleW, scaleH) = (1 as CGFloat, 1 as CGFloat)
if targetWidth > size.width {
scaleW = size.width/targetWidth
}
if targetHeight > size.height {
scaleH = size.height/targetHeight
}
let scale = min(scaleW,scaleH)
targetWidth *= scale; targetHeight *= scale
let sz = CGSize(width:targetWidth, height:targetHeight)
if !centered {
return UIGraphicsImageRenderer(size:sz).image { _ in
self.draw(in:CGRect(origin:.zero, size:sz))
}
}
let x = (size.width - targetWidth)/2
let y = (size.height - targetHeight)/2
let origin = CGPoint(x:x,y:y)
return UIGraphicsImageRenderer(size:size).image { _ in
self.draw(in:CGRect(origin:origin, size:sz))
}
}
}
這里有兩個簡單的UIImage
擴展功能:
func scaledWithMaxWidthOrHeightValue(value: CGFloat) -> UIImage? {
let width = self.size.width
let height = self.size.height
let ratio = width/height
var newWidth = value
var newHeight = value
if ratio > 1 {
newWidth = width * (newHeight/height)
} else {
newHeight = height * (newWidth/width)
}
UIGraphicsBeginImageContextWithOptions(CGSize(width: newWidth, height: newHeight), false, 0)
draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
func scaled(withScale scale: CGFloat) -> UIImage? {
let size = CGSize(width: self.size.width * scale, height: self.size.height * scale)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
調用resizeimage方法
let image1 = resizeimage(image: myimage.image!, withSize: CGSize(width:200, height: 200))
調整圖像大小的方法
func resizeimage(image:UIImage,withSize:CGSize) -> UIImage {
var actualHeight:CGFloat = image.size.height
var actualWidth:CGFloat = image.size.width
let maxHeight:CGFloat = withSize.height
let maxWidth:CGFloat = withSize.width
var imgRatio:CGFloat = actualWidth/actualHeight
let maxRatio:CGFloat = maxWidth/maxHeight
let compressionQuality = 0.5
if (actualHeight>maxHeight||actualWidth>maxWidth) {
if (imgRatio<maxRatio){
//adjust width according to maxHeight
imgRatio = maxHeight/actualHeight
actualWidth = imgRatio * actualWidth
actualHeight = maxHeight
}else if(imgRatio>maxRatio){
// adjust height according to maxWidth
imgRatio = maxWidth/actualWidth
actualHeight = imgRatio * actualHeight
actualWidth = maxWidth
}else{
actualHeight = maxHeight
actualWidth = maxWidth
}
}
let rec:CGRect = CGRect(x:0.0,y:0.0,width:actualWidth,height:actualHeight)
UIGraphicsBeginImageContext(rec.size)
image.draw(in: rec)
let image:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
let imageData = UIImageJPEGRepresentation(image, CGFloat(compressionQuality))
UIGraphicsEndImageContext()
let resizedimage = UIImage(data: imageData!)
return resizedimage!
}
Swift 5 版本尊重比例(scaleToFill)和居中圖像:
extension UIImage {
func resized(to newSize: CGSize) -> UIImage {
return UIGraphicsImageRenderer(size: newSize).image { _ in
let hScale = newSize.height / size.height
let vScale = newSize.width / size.width
let scale = max(hScale, vScale) // scaleToFill
let resizeSize = CGSize(width: size.width*scale, height: size.height*scale)
var middle = CGPoint.zero
if resizeSize.width > newSize.width {
middle.x -= (resizeSize.width-newSize.width)/2.0
}
if resizeSize.height > newSize.height {
middle.y -= (resizeSize.height-newSize.height)/2.0
}
draw(in: CGRect(origin: middle, size: resizeSize))
}
}
}
示例是將圖像最小化到 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
}
}
您可以在Swift 3 中將其用於適合圖像;
extension UIImage {
func resizedImage(newSize: CGSize) -> UIImage {
// Guard newSize is different
guard self.size != newSize else { return self }
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0);
self.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return newImage
}
func resizedImageWithinRect(rectSize: CGSize) -> UIImage {
let widthFactor = size.width / rectSize.width
let heightFactor = size.height / rectSize.height
var resizeFactor = widthFactor
if size.height > size.width {
resizeFactor = heightFactor
}
let newSize = CGSize(width: size.width/resizeFactor, height: size.height/resizeFactor)
let resized = resizedImage(newSize: newSize)
return resized
}
}
用法;
let resizedImage = image.resizedImageWithinRect(rectSize: CGSize(width: 1900, height: 1900))
SWIFT 5 - XCODE 12 - 調整圖像大小和無白線
我在上面為 Swift 5 使用了一個很好的解決方案。我改變了一點以包含術語“地板”,因為我在調整大小的圖像周圍出現了一條白線。 這會將它四舍五入到最近的像素或其他東西,所以它看起來很棒! 我還必須在調用函數時更改圖像名稱周圍的語法(最后一行)。
//調整圖片大小的方法
func resizeimage(image:UIImage,withSize:CGSize) -> UIImage {
var actualHeight:CGFloat = image.size.height
var actualWidth:CGFloat = image.size.width
let maxHeight:CGFloat = withSize.height
let maxWidth:CGFloat = withSize.width
var imgRatio:CGFloat = actualWidth/actualHeight
let maxRatio:CGFloat = maxWidth/maxHeight
let compressionQuality = 0.5
if (actualHeight>maxHeight||actualWidth>maxWidth) {
if (imgRatio<maxRatio){
//adjust width according to maxHeight
imgRatio = maxHeight/actualHeight
actualWidth = floor(imgRatio * actualWidth)
actualHeight = maxHeight
}else if(imgRatio>maxRatio){
// adjust height according to maxWidth
imgRatio = maxWidth/actualWidth
actualHeight = imgRatio * actualHeight
actualWidth = maxWidth
}else{
actualHeight = maxHeight
actualWidth = maxWidth
}
}
let rec:CGRect = CGRect(x:0.0,y:0.0,width:actualWidth,height:actualHeight)
UIGraphicsBeginImageContext(rec.size)
image.draw(in: rec)
let image:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
let imageData = UIImageJPEGRepresentation(image, CGFloat(compressionQuality))
UIGraphicsEndImageContext()
let resizedimage = UIImage(data: imageData!)
return resizedimage!
}
//調用resizeimage方法:
讓 myimage = UIImage(named: "imagename")
讓 image1 = resizeimage(image: myimage!, withSize: CGSize(width:50, height: 50)).withRenderingMode(.alwaysOriginal)
我正在使用Swift和Parse.com開發適用於iOS的應用程序
我試圖讓用戶從圖像選擇器中選擇一張圖片,然后將所選圖像的大小調整為200x200像素,然后再上傳到我的后端。
Parse.com有一個用於Instagram復制應用程序的教程,名為“ AnyPic”,其中提供了用於調整圖像大小的代碼,但它位於Objective-C中。
// Resize the image to be square (what is shown in the preview)
UIImage *resizedImage = [anImage resizedImageWithContentMode:UIViewContentModeScaleAspectFit
bounds:CGSizeMake(560.0f, 560.0f)
interpolationQuality:kCGInterpolationHigh];
// Create a thumbnail and add a corner radius for use in table views
UIImage *thumbnailImage = [anImage thumbnailImage:86.0f
transparentBorder:0.0f
cornerRadius:10.0f
interpolationQuality:kCGInterpolationDefault];
如何在Swift中為所選圖片創建200x200px版本(然后上傳)?
而且,thumbnailImage函數在做什么?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.