iOS:如何将 UIView 的自绘内容转换为图像(普遍的通用解决方案返回空白图像)?
Posted
技术标签:
【中文标题】iOS:如何将 UIView 的自绘内容转换为图像(普遍的通用解决方案返回空白图像)?【英文标题】:iOS: How to convert the self-drawn content of an UIView to an image (widespread general solution returns blank image)? 【发布时间】:2012-11-05 10:06:45 【问题描述】:我的业务应用程序需要一项功能,让用户用手指在UIView
上绘制签名并保存(通过单击工具栏中的按钮),以便将其附加到单元。这些单元将在工作完成后上传到服务器,并且已经支持通过 Base64 上传的相机图片附件,所以我只想将拍摄的签名转换为 UIImage
。
首先,我需要一个解决方案来绘制签名,我很快从 Apple 找到了一些似乎符合我要求的示例代码:GLPaint
由于我使用 ARC 和 Storyboards 并且不需要声音效果和调色板等,因此我将这个示例代码集成到我的项目中,并稍作修改,但绘图代码是直接复制的。
集成似乎是成功的,因为我能够在视图上绘制签名。因此,下一步是为绘制的签名添加保存/图像转换功能。
我进行了无休止的搜索并滚动了数十个主题,并提出了类似的问题,其中大多数都指向完全相同的解决方案:
(假设)
drawingView:子类化UIView
,在其中完成绘图。)
包括<QuartzCore/QuartzCore.h>
和QuartzCore.framework
包含CoreGraphics.framework
OpenGLES.framework
包括在内
- (void) saveAsImage:(UIView*) drawingView
UIGraphicsBeginImageContext(drawingView.bounds.size);
[drawingView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentContext();
UIGraphicsEndImageContext();
最后是我的问题:此代码对我不起作用,因为它总是返回空白图像。由于我已经集成了对使用 iPhone 相机拍摄的图片附件的支持,我最初假设图像处理代码也应该适用于签名图像。
但是.. 经过一番毫无结果的搜索后,我放弃了这个假设,采用了原始的 GLPaint 项目,只添加了上面的几行代码和一些只显示图像的代码,它也是完全空白的。因此,要么是该代码无法处理 UIView
s 上的自绘内容的问题,要么是我遗漏的任何内容。
我对这个问题基本上没有想法,希望有人能帮助我。
最好的问候 费利克斯
【问题讨论】:
【参考方案1】:我相信您的问题可能是您试图从 GL 上下文中获取图像。你可以在网上搜索,但通常你只需要在所有“draw”调用完成后调用“glReadPixels”。这样的东西应该可以工作:
BOOL createSnapshot;
int viewWidth, viewHeigth;
if(createSnapshot)
uint8_t *iData = new uint8_t[viewHeigth * viewWidth * 4];
glReadPixels(0, 0, viewWidth, viewHeigth, GL_RGBA, GL_UNSIGNED_BYTE, iData);
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, iData, (viewWidth * viewHeigth * 4), NULL);
CGColorSpaceRef cref = CGColorSpaceCreateDeviceRGB();
CGImageRef cgImage = CGImageCreate(viewWidth, viewHeigth, 8, 32, viewWidth*4, cref, kCGBitmapByteOrderDefault, provider, NULL, NO, kCGRenderingIntentDefault);
UIImage *ret = [UIImage imageWithCGImage:cgImage scale:1.0f]; //the image you need
CGImageRelease(cgImage);
CGDataProviderRelease(provider);
CGColorSpaceRelease(cref);
delete [] iData;
createSnapshot = NO;
如果您使用多重采样,则需要在解析缓冲区并绑定呈现帧缓冲区后调用此函数。
【讨论】:
感谢您的帮助!使用这种方法,我终于得到了一些回报。由于出现编译错误,我不得不对您的代码稍作更改:我将uint8_t *iData = new uint8_t[...]
更改为 GLuint *iData = (GLuint*) malloc(...)
。 “delete [] iData”这行是我不懂的语法。以上是关于iOS:如何将 UIView 的自绘内容转换为图像(普遍的通用解决方案返回空白图像)?的主要内容,如果未能解决你的问题,请参考以下文章
将 UIImageView 和覆盖的 UIView 保存为图像(xcode/iOS)
如何实现可以显示图像或作为输入属性提供的自定义 UIView 的 CollectionViewCell?