Как изменить размер растрового изображения на 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)
    }

}
Другие вопросы по тегам