Программно создать образ из UILabel - PullRequest
6 голосов
/ 02 апреля 2011

Я хочу использовать UILabel для программного представления RGBA-потока байтовых изображений (во время выполнения).

Например, я хочу создать UILabel с определенным шрифтом и с определенным текстом, превратить это в NSData байтов без знака RGBA, а затем с этого момента я могу легко превратить его в текстуру OpenGLи отображать его так, как я хочу.

Важно, чтобы я мог знать размеры получающегося изображения, хотя при необходимости я могу создать очень широкий «пустой» холст для его визуализации, а затем во время выполненияопределить ширину и высоту самостоятельно, проверив байты.

Если я смогу добиться этого с помощью UIImage / CG, это явный плюс - и решение с несколькими целями рендеринга не является разумным / желательным.

Редактировать: Поместитьщедрот;Изначально я получил этот красивый ответ ниже от meronix, но теперь у меня есть время попробовать его, и он не работает должным образом.Мне нужно, чтобы это работало "вчера", и я очень расстроен.Здесь есть какой-то нюанс, который тот, кто знает состояние рисования Какао лучше меня, наверняка сможет уловить.

Ответы [ 3 ]

7 голосов
/ 02 апреля 2011

Вы можете «захватить» (сделать снимок) вашу UILabel, это подкласс UIView, так что вы можете получить его изображение.

используйте этот класс "CaptureView":

CaptureView.h

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import <QuartzCore/CALayer.h>


@interface CaptureView : UIView {
@private
    UIImage *_imageCapture;
}

@property(nonatomic, retain) UIImage *imageCapture;

// Init
- (id)initWithView:(UIView *)view;

@end

CaptureView.m

#import "CaptureView.h"

// Private
@interface CaptureView (/* Private */)
- (void)settingImageFromView:(UIView *)view;
@end

// Public
@implementation CaptureView

@synthesize imageCapture = _imageCapture;

// Standard // UILabel
- (id)initWithFrame:(CGRect)frame {

    if ((self = [super initWithFrame:frame])) {
        // Initialization code.
    }
    return self;
}

// Init
- (id)initWithView:(UIView *)view {
    if ((self = [super initWithFrame:[view frame]])) {
//  if ((self = [super initWithFrame: CGRectMake(0, 0, 100, 100)])) {
        // Initialization code.
        [self settingImageFromView:view];
    }
    return self;  
}

/*!
 @method     imageFromView:view
 @abstract   Esegue una Grab di una intera view
 @discussion Imposta l'immagine catturata eseguendo una copia dell'intera view 
 */
- (void)settingImageFromView:(UIView *)view {
    CGRect rect = [view bounds];  
 //   CGRect rect = CGRectMake(20, 30, 100, 100);  
    UIGraphicsBeginImageContext(rect.size);  
    CGContextRef context = UIGraphicsGetCurrentContext();  
    [view.layer renderInContext:context];  
    UIImage *imageCaptureRect;

    imageCaptureRect = UIGraphicsGetImageFromCurrentImageContext();  
    _imageCapture = imageCaptureRect;
//    _imageCapture = UIGraphicsGetImageFromCurrentImageContext();  
//    [_imageCapture retain];
    UIGraphicsEndImageContext();   
}


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code.
    CGPoint accPoint = CGPointMake(0,0);
    [_imageCapture drawAtPoint:accPoint];
}


- (void)dealloc {
    [_imageCapture release];
    [super dealloc];
}

@end

поэтому просто инициируйте его, передав ему UILabel, и вы получите класс с свойство UIImage * imageCapture, так что просто получите его и используйте его ...

// in your class which wanna manage the captured image:
// in .h : #import "CaptureView.h"
CaptureView *cloneView = [[CaptureView alloc] initWithView:aUILabel];
//  [yourUIView addSubview:cloneView]; // eventually, to see it...
UIImage *myCapt = cloneView.imageCapture;
// ... your code to use myCapt
[cloneView release];

EDIT:

скачать этот проект:

http://meronix.altervista.org/captureUILabel.zip

центрированный текст black-backGround - это захват (экземпляр класса: CaptureView) текста Gray-BackGround (UILabel) сверху

5 голосов
/ 13 июля 2011

Это должно работать:

UIGraphicsBeginImageContext(yourLabel.bounds.size);
[yourLabel.layer renderInContext:UIGraphicsGetCurrentContext()];
CGImageRef viewImage = [UIGraphicsGetImageFromCurrentImageContext() CGImage];
UIGraphicsEndImageContext();

UIGraphicsGetImageFromCurrentImageContext() возвращает экземпляр UIImage.

1 голос
/ 08 июля 2011
CGFloat scale  = [[[view window] screen] scale];
CGRect  bounds = [view bounds];

CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(NULL, CGRectGetWidth(bounds) * scale, CGRectGetHeight(bounds) * scale, 8, CGRectGetWidth(bounds) *
scale * 4, space, kCGImageAlphaPremultipliedLast);
CGContextTranslateCTM(ctx, 0.0, CGRectGetHeight(bounds) * scale);
CGContextScaleCTM(ctx, scale, -scale);
[[view layer] renderInContext:ctx];

Затем используйте байты через CGBitmapContextGetData(myContext). Нет причин возиться с UIImage

...