Как изменить размер растрового изображения на iOS
Я хочу изменить размер растрового изображения для проекта, который я делаю. Мне удалось сделать это, преобразовав cgbitmapcontextref в массив пикселей, а затем манипулируя массивом пикселей, а затем сгенерировал новое изображение из данных манипулированных пикселей. Этот способ чрезвычайно громоздок.
Я хочу знать, есть ли другой способ изменить размер CGBitmapContextRef. Благодарю.
1 ответ
Решение
Если вы не женаты на CGBitmapContextRef
Вот несколько простых процедур изменения размера изображений на основе UIKit. Это расширение предлагает изменение размера изображений путем обрезки, масштабирования, заливки и подгонки (аналогично некоторым основным режимам контента, которые предлагает UIImageView).
//
// UIImage+Resize.swift
//
// Image resizing extension
//
// Created by Robert Ryan on 5/19/11.
// Ported to Swift by Robert Ryan on 2/12/15.
// Modified for Swift 2 by Robert Ryan on 10/14/15
//
// 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 `UIViewContentMode` to be applied when resizing image.
/// Either `.ScaleToFill`, `.ScaleAspectFill`, or
/// `.ScaleAspectFit`.
///
/// - returns: Return `UIImage` of resized image.
func imageByScalingToSize(newSize: CGSize, contentMode: UIViewContentMode) -> UIImage? {
if contentMode == .ScaleToFill {
return imageByScalingToFillSize(newSize)
} else if contentMode == .ScaleAspectFill || contentMode == .ScaleAspectFit {
let horizontalRatio = size.width / newSize.width
let verticalRatio = size.height / newSize.height
var ratio: CGFloat!
if contentMode == .ScaleAspectFill {
ratio = min(horizontalRatio, verticalRatio)
} else {
ratio = max(horizontalRatio, verticalRatio)
}
let sizeForAspectScale = CGSizeMake(self.size.width / ratio, self.size.height / ratio)
let image = imageByScalingToFillSize(sizeForAspectScale)
if contentMode == .ScaleAspectFill {
let subRect = CGRectMake(
floor((sizeForAspectScale.width - newSize.width) / 2.0),
floor((sizeForAspectScale.height - newSize.height) / 2.0),
newSize.width,
newSize.height)
return image?.imageByCroppingToBounds(subRect)
}
return image
}
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 imageByScalingToFillSize(newSize: CGSize) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(newSize, false, scale)
drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
/// Crop the image to be the required size.
///
/// - parameter bounds: The bounds to which the new image should be cropped.
///
/// - returns: Cropped `UIImage`.
func imageByCroppingToBounds(bounds: CGRect) -> UIImage? {
var rect = bounds
rect.size.width *= scale
rect.size.height *= scale
if let imageRef = CGImageCreateWithImageInRect(CGImage, rect) {
return UIImage(CGImage: imageRef, scale: scale, orientation: imageOrientation)
} else {
return nil
}
}
/// 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 imageByScalingAspectFillSize(newSize: CGSize) -> UIImage? {
return imageByScalingToSize(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 imageByScalingAspectFitSize(newSize: CGSize) -> UIImage? {
return imageByScalingToSize(newSize, contentMode:.ScaleAspectFit)
}
}