欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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;
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。