Iphone 以编程方式从UILabel创建图像

Iphone 以编程方式从UILabel创建图像,iphone,opengl-es,uikit,core-graphics,uilabel,Iphone,Opengl Es,Uikit,Core Graphics,Uilabel,我想使用UILabel以编程方式(在运行时)创建RGBA字节流图像表示 例如,我想用特定字体和特定文本创建一个UILabel,将其转换为RGBA无符号字节的NSData,然后从那时起,我可以轻松地将其转换为OpenGL纹理并以我想要的方式显示 重要的是,我可以知道结果图像的尺寸,尽管如果绝对必要,我可以创建一个非常宽的“空白”画布来渲染它,然后在运行时通过检查字节来检测宽度和高度 如果我能通过UIImage/CG实现这一点,那肯定是一个加号——而使用多个渲染目标的解决方案是不合理/不理想的 编辑

我想使用UILabel以编程方式(在运行时)创建RGBA字节流图像表示

例如,我想用特定字体和特定文本创建一个UILabel,将其转换为RGBA无符号字节的NSData,然后从那时起,我可以轻松地将其转换为OpenGL纹理并以我想要的方式显示

重要的是,我可以知道结果图像的尺寸,尽管如果绝对必要,我可以创建一个非常宽的“空白”画布来渲染它,然后在运行时通过检查字节来检测宽度和高度

如果我能通过UIImage/CG实现这一点,那肯定是一个加号——而使用多个渲染目标的解决方案是不合理/不理想的

编辑:悬赏;我最初从meronix那里得到了下面这个漂亮的答案,但现在我有时间尝试一下,它不能正常工作。我需要这个工作“昨天”,我很沮丧。这里有一些细微差别,比我更了解Cocoa绘图状态的人肯定能抓住。

你可以“捕获”(拍摄)你的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
因此,只要启动它,并将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];
编辑:

下载此项目:

居中的黑色背景文本是顶部灰色背景文本(UILabel)的捕获(类的实例:CaptureView)

CGFloat比例=[[view window]screen]比例]; CGRect边界=[视图边界]; CGColorSpaceRef space=CGColorSpaceCreateDeviceRGB(); CGContextRef ctx=CGBitmapContextCreate(空,CGRectGetWidth(边界)*缩放,CGRectGetHeight(边界)*缩放,8,CGRectGetWidth(边界)* 比例尺*4,空格,kcGimageAlphaPremultipledLast); CGContextTranslateCTM(ctx,0.0,CGRectGetHeight(边界)*比例); CGContextScaleCTM(ctx,标度,-标度); [[view layer]renderContext:ctx]; 然后,通过
CGBitmapContextGetData(myContext)
使用字节。无需为UIImage费心这应该可以:

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

UIGraphicsGetImageFromCurrentImageContext()
返回
UIImage

的一个实例,我终于开始尝试这个方法,但它实际上不起作用。我首先尝试“调整”您的代码以在我的方法中内联运行,但后来意识到drawRect可能有其微妙之处:在正确的时间被Cocoa调用。不幸的是,我现在已经完全复制了您的代码,但它仍然不起作用。我的“…您使用myCapt的代码”是获取UIImage并使用
CGContextDrawImage
和朋友从中获取原始位图数据以立即创建OpenGL纹理的代码。但我只是在循环结束时遇到了一个崩溃。看来,也许使用您提出的技术,我必须首先创建您的图像,然后等待Cocoa调用的完整绘制周期,然后根据需要使用图像数据?这在实践中似乎非常困难。事实上,我尝试过,等待抽签周期进行几次都没有效果。这里肯定有个问题somewhere@Nektarios:那就把你的密码贴出来。我确信我在我的一些项目/样本中使用了它,它很有效,我可以搜索它们,如果我找到它们,也许会将样本/项目发送给你,但我不能保证,那是很久以前的事了…我没有找到我的项目。。。但是我看了一下我的代码:我试图解释它是如何工作的:当您使用:CaptureView*cloneView=[[CaptureView alloc]initWithView:aUILabel]初始化CaptureView时;您要求该类捕获UILabel的“图像”,并在其自身的图像中使用它(CaptureView是UIImage中的/hinerit)。。。要查看它是否有效,只需使用<[yourUIView addSubview:cloneView];>,因此,您可以看到捕获是否工作正常……它真的必须是UILabel,还是您只想将一些文本渲染成纹理以供OpenGL使用?@zpasternack我真的想使用UILabel,因为我想方便地使用Cocoa(Touch)的出色且已经提供的字体渲染功能 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];
UIGraphicsBeginImageContext(yourLabel.bounds.size);
[yourLabel.layer renderInContext:UIGraphicsGetCurrentContext()];
CGImageRef viewImage = [UIGraphicsGetImageFromCurrentImageContext() CGImage];
UIGraphicsEndImageContext();