iOS中如何获取某个视图的截图详析
程序员文章站
2022-05-25 22:22:58
前言
最近在做sdk的截图,想触发类似系统的截屏功能,找了一圈,总结一下靠谱的几种方式。
我写了个uiview 的category,将这几种方式封装和简化了一下。...
前言
最近在做sdk的截图,想触发类似系统的截屏功能,找了一圈,总结一下靠谱的几种方式。
我写了个uiview 的category,将这几种方式封装和简化了一下。
第一种情形截图
这种是最最普通的截图,针对一般的视图上添加视图的情况,基本都可以使用。
源码:
/** 普通的截图 该api仅可以在未使用layer和opengl渲染的视图上使用 @return 截取的图片 */ - (uiimage *)nomalsnapshotimage { uigraphicsbeginimagecontextwithoptions(self.frame.size, no, [uiscreen mainscreen].scale); [self.layer renderincontext:uigraphicsgetcurrentcontext()]; uiimage *snapshotimage = uigraphicsgetimagefromcurrentimagecontext(); uigraphicsendimagecontext(); return snapshotimage; }
第二种情形截图
如果一些视图是用opengl渲染出来的,那么使用上面的方式就无法截图到opengl渲染的部分,这时候就要用到改进后的截图方案:
/** 针对有用过opengl渲染过的视图截图 @return 截取的图片 */ - (uiimage *)openglsnapshotimage { cgsize size = self.bounds.size; uigraphicsbeginimagecontextwithoptions(size, no, [uiscreen mainscreen].scale); cgrect rect = self.frame; [self drawviewhierarchyinrect:rect afterscreenupdates:yes]; uiimage *snapshotimage = uigraphicsgetimagefromcurrentimagecontext(); uigraphicsendimagecontext(); return snapshotimage; }
第三种情形截图
有一些特殊的layer(比如:avcapturevideopreviewlayer 和 avsamplebufferdisplaylayer) 添加到某个view 上后,使用上面的几种方式都无法截取到layer上的内容,这个时候可以使用系统的一个api,但是该api只能返回一个uiview,返回的uiview 可以修改frame 等参数。
/** 截图 以uiview 的形式返回(_uireplicantview) @return 截取出来的图片转换的视图 */ - (uiview *)snapshotview { uiview *snapview = [self snapshotviewafterscreenupdates:yes]; return snapview; }
遗留问题:
通过方式三截取的uiview,无法转换为uiimage,我试过将返回的截图view写入位图再转换成uiimage,但是返回的uiimage 要么为空,要么没有内容。如果有人知道解决方案请告知我。
uiwebview的截图
去年在做蓝牙打印的时候,尝试过将uiwebview 的内容转换为uiimage,写过一个uiwebview的category,也算是对uiwebview 的截图,顺便也贴出来吧
- (uiimage *)imageforwebview { // 1.获取webview的宽高 cgsize boundssize = self.bounds.size; cgfloat boundswidth = boundssize.width; cgfloat boundsheight = boundssize.height; // 2.获取contentsize cgsize contentsize = self.scrollview.contentsize; cgfloat contentheight = contentsize.height; // 3.保存原始偏移量,便于截图后复位 cgpoint offset = self.scrollview.contentoffset; // 4.设置最初的偏移量为(0,0); [self.scrollview setcontentoffset:cgpointmake(0, 0)]; nsmutablearray *images = [nsmutablearray array]; while (contentheight > 0) { // 5.获取cgcontext 5.获取cgcontext uigraphicsbeginimagecontextwithoptions(boundssize, no, 0.0); cgcontextref ctx = uigraphicsgetcurrentcontext(); // 6.渲染要截取的区域 [self.layer renderincontext:ctx]; uiimage *image = uigraphicsgetimagefromcurrentimagecontext(); uigraphicsendimagecontext(); // 7.截取的图片保存起来 [images addobject:image]; cgfloat offsety = self.scrollview.contentoffset.y; [self.scrollview setcontentoffset:cgpointmake(0, offsety + boundsheight)]; contentheight -= boundsheight; } // 8 webview 恢复到之前的显示区域 [self.scrollview setcontentoffset:offset]; cgfloat scale = [uiscreen mainscreen].scale; cgsize imagesize = cgsizemake(contentsize.width * scale, contentsize.height * scale); // 9.根据设备的分辨率重新绘制、拼接成完整清晰图片 uigraphicsbeginimagecontext(imagesize); [images enumerateobjectsusingblock:^(uiimage *image, nsuinteger idx, bool *stop) { [image drawinrect:cgrectmake(0,scale * boundsheight * idx,scale * boundswidth,scale * boundsheight)]; }]; uiimage *fullimage = uigraphicsgetimagefromcurrentimagecontext(); uigraphicsendimagecontext(); return fullimage; }
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。
上一篇: ruby声明式语法的实现例子
下一篇: vue通过点击事件读取音频文件的方法