2013-11-16 3 views
17

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

enter image description here

+1

Не должно быть закрыто ИМО. Вопрос хорошо определен и полезен. – sjwarner

ответ

19

создается новый контекст изображения, которое 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(); 
+0

Уважаемый DrummerB! Большое спасибо за публикацию рабочего решения. Только исправление было заменено CGPoint origin = CGRectMake ((width - oldImage.size.width)/2.0f, (height - oldImage.size.height)/2.0f); с CGPoint origin = CGPointMake ((width - oldImage.size.width)/2.0f, (высота - oldImage.size.height)/2.0f); –

+1

@DrummerB Вы не хотите, чтобы аргумент 'opaque' в' UIGraphicsBeginImageContextWithOptions' был NO, поскольку он хочет прозрачное пространство? – Marty

21

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

Swift 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 
    } 
} 

OLD ОТВЕТ:

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 
    } 
} 
+0

любая идея, почему иногда это может вернуть нуль? – Happiehappie

+0

См. Https://developer.apple.com/reference/uikit/1623924-uigraphicsgetimagefromcurrentima: вы должны вызывать эту функцию только в том случае, когда графический контекст на основе растровых изображений является текущим графическим контекстом. Если текущий контекст равен нулю или не был создан вызовом UIGraphicsBeginImageContext (_ :), эта функция возвращает nil. – mixel

+0

@mixel Просто небольшое предложение: оно должно быть 'return imageWithInsets? .WithRenderingMode (renderMode)' для поддержки изображений шаблонов – alexburtnik

1

сделать категорию на 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; 
} 
8

Это решение в 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 opaque to false)
Смежные вопросы