iOS:如何将UIView的自画内容转换为图像(通用解决方案返回空白图像)?

iOS:如何将UIView的自画内容转换为图像(通用解决方案返回空白图像)?,ios,ios5,uiview,uiimage,signature,Ios,Ios5,Uiview,Uiimage,Signature,“我的商业应用程序”需要一项功能,允许用户用手指在UIView上绘制签名并保存(通过工具栏中的按钮单击),以便将其连接到设备上。一旦工作完成,这些装置将被上传到服务器,并且已经支持通过Base64上传的摄像头图片附件,因此我只想将签名转换为UIImage 首先,我需要一个解决方案来绘制签名,我很快从苹果公司找到了一些似乎符合我要求的示例代码: 我将这个示例代码集成到我的项目中,只做了一些轻微的修改,因为我使用的是ARC和故事板,不需要音效和调色板等,但绘图代码是一个直接副本 集成似乎是成功的,因

“我的商业应用程序”需要一项功能,允许用户用手指在
UIView
上绘制签名并保存(通过工具栏中的按钮单击),以便将其连接到设备上。一旦工作完成,这些装置将被上传到服务器,并且已经支持通过Base64上传的摄像头图片附件,因此我只想将签名转换为
UIImage

首先,我需要一个解决方案来绘制签名,我很快从苹果公司找到了一些似乎符合我要求的示例代码:

我将这个示例代码集成到我的项目中,只做了一些轻微的修改,因为我使用的是ARC和故事板,不需要音效和调色板等,但绘图代码是一个直接副本

集成似乎是成功的,因为我能够在视图上绘制签名。因此,下一步是为绘制的签名添加保存/图像转换函数

我进行了无休止的搜索,并滚动了数十个线程,其中大部分都指向了完全相同的解决方案:

(假设)

  • drawingView:子类化的
    UIView
    ,在该视图上进行绘图。)
  • 包括
    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上的自画内容的问题,要么是我缺少的任何东西

在这个问题上我基本上没有什么想法,希望有人能帮助我

致意
Felix

我相信您的问题可能是您试图从GL上下文中获取图像。你们可以在网上搜索,但通常你们只需要在所有的“绘制”调用完成后调用“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\u t*iData=new uint8\u t[…]
更改为
GLuint*iData=(GLuint*)malloc(…)
。“delete[]iData”一行是我不理解的语法。