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 项目,只添加了上面的几行代码和一些只显示图像的代码,它也是完全空白的。因此,要么是该代码无法处理 UIViews 上的自绘内容的问题,要么是我遗漏的任何内容。

我对这个问题基本上没有想法,希望有人能帮助我。

最好的问候 费利克斯

【问题讨论】:

【参考方案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?

用c/c++混合编程方式为ios/android实现一个自绘日期选择控件

如何在 iOS 中将 UIView 转换为 PDF?

如何在 iOS 中将 UIView 转换为 PDF?

如何在 iOS 上将文本转换为图像?