我想使用UILabel以编程方式(在运行时)创建RGBA字节流图像表示。
例如,我想创建一个特定字体和特定文本的UILabel,将其转换为RGBA无符号字节的NSData,然后从那一点我可以轻松地将其转换为OpenGL纹理并显示它但是我想要。
重要的是我可以知道结果图像的尺寸,尽管如果绝对必要,我可以创建一个非常宽的“空白”画布来渲染它,然后在运行时通过检查字节来检测宽度和高度。
如果我能通过UIImage / CG实现这一点,那将是一个明确的优势 - 并且具有多个渲染目标的解决方案是不合理/期望的。
编辑:放置赏金;我最初从meronix那里得到了这个好看的答案,但现在我有时间试试它并且它无法正常工作。我需要这个“昨天”工作,我非常沮丧。这里有一些细微差别,那些知道Cocoa绘画状态比我更好的人肯定能抓住。
答案 0 :(得分:7)
你可以“捕捉”你的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传递给它,这样你就可以获得一个Class 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];
修改
下载此项目:
http://meronix.altervista.org/captureUILabel.zip
居中的black-backGround文本是顶部的Gray-BackGround文本(UILabel)的捕获(类的实例:CaptureView)
答案 1 :(得分:5)
这应该有效:
UIGraphicsBeginImageContext(yourLabel.bounds.size);
[yourLabel.layer renderInContext:UIGraphicsGetCurrentContext()];
CGImageRef viewImage = [UIGraphicsGetImageFromCurrentImageContext() CGImage];
UIGraphicsEndImageContext();
UIGraphicsGetImageFromCurrentImageContext()
会返回UIImage
的实例。
答案 2 :(得分:1)
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