Добавить прозрачное пространство вокруг UIImage

Допустим, у нас есть изображение 600X400, и мы хотим получить новое изображение 1000X100, которое содержит начальное изображение в центре и прозрачное пространство вокруг него. Как я могу добиться этого в коде?

4 ответа

Решение

Вы создаете новый контекст изображения, размером 1000x1000, рисуете свое старое изображение посередине, затем получаете новый UIImage из контекста.

// Setup a new context with the correct size
CGFloat width = 1000;
CGFloat height = 1000;
UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, height), NO, 0.0);        
CGContextRef context = UIGraphicsGetCurrentContext();       
UIGraphicsPushContext(context);                             

// Now we can draw anything we want into this new context.
CGPoint origin = CGPointMake((width - oldImage.size.width) / 2.0f,
                            (height - oldImage.size.height) / 2.0f);
[oldImage drawAtPoint:origin];

// Clean up and get the new image.
UIGraphicsPopContext();                             
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

В Swift вы можете написать расширение для UIImage, которое рисует изображение с вставками вокруг него.

Свифт 3:

import UIKit

extension UIImage {
    func imageWithInsets(insets: UIEdgeInsets) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(
            CGSize(width: self.size.width + insets.left + insets.right,
                   height: self.size.height + insets.top + insets.bottom), false, self.scale)
        let _ = UIGraphicsGetCurrentContext()
        let origin = CGPoint(x: insets.left, y: insets.top)
        self.draw(at: origin)
        let imageWithInsets = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return imageWithInsets
    }
}

СТАРЫЙ ОТВЕТ:

import UIKit

extension UIImage {
    func imageWithInsets(insets: UIEdgeInsets) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(
            CGSizeMake(self.size.width + insets.left + insets.right,
                self.size.height + insets.top + insets.bottom), false, self.scale)
        let context = UIGraphicsGetCurrentContext()
        let origin = CGPoint(x: insets.left, y: insets.top)
        self.drawAtPoint(origin)
        let imageWithInsets = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return imageWithInsets
    }
}

Это решение в Swift 4, вдохновленное ответом DrummerB:

import UIKit

extension UIImage {

    func addImagePadding(x: CGFloat, y: CGFloat) -> UIImage? {
        let width: CGFloat = size.width + x
        let height: CGFloat = size.height + y
        UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), false, 0)
        let origin: CGPoint = CGPoint(x: (width - size.width) / 2, y: (height - size.height) / 2)
        draw(at: origin)
        let imageWithPadding = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return imageWithPadding
    }
}

Как подать заявку:

let image = UIImage(named: "your-image")!
let imageView = UIImageView(image: image.addImagePadding(x: 50, y: 50))
imageView.backgroundColor = UIColor.gray
view.addSubview(imageView)

Особенности:

  • Просто передайте значения заполнения через параметры
  • Цветное заполнение (установив для непрозрачного параметра UIGraphicsBeginImageContextWithOptions значение false)

Исправление для ответа appsunited с улучшенным соглашением об именах. Чтобы не путать, функция мутирует или нет:

extension UIImage {
    func withPadding(_ padding: CGFloat) -> UIImage? {
        return withPadding(x: padding, y: padding)
    }

    func withPadding(x: CGFloat, y: CGFloat) -> UIImage? {
        let newWidth = size.width + 2 * x
        let newHeight = size.height + 2 * y
        let newSize = CGSize(width: newWidth, height: newHeight)
        UIGraphicsBeginImageContextWithOptions(newSize, false, 0)
        let origin = CGPoint(x: (newWidth - size.width) / 2, y: (newHeight - size.height) / 2)
        draw(at: origin)
        let imageWithPadding = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return imageWithPadding
    }
}

Создайте категорию на UIImage и попробуйте это:

+ (UIImage *)imageWithInsets:(CGRect)insetRect image:(UIImage *)image {
    CGRect newRect = CGRectMake(0.0, 0.0, insetRect.origin.x+insetRect.size.width+image.size.width, insetRect.origin.y+insetRect.size.height+image.size.height);
    // Setup a new context with the correct size
    UIGraphicsBeginImageContextWithOptions(newRect.size, NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    UIGraphicsPushContext(context);

    // Now we can draw anything we want into this new context.
    CGPoint origin = CGPointMake(insetRect.origin.x, insetRect.origin.y);
    [image drawAtPoint:origin];

    // Clean up and get the new image.
    UIGraphicsPopContext();
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}
Другие вопросы по тегам