前言:

ID作为一款以IM为基础的办公软件,在用户使用过程中,经常会遇到一些超大的或者超高分辨率的图片(以下统一称:大图)。基于SDWebImage为基础的图片加载控件,在遇到此情况时,并没有提供十分有效的解决方法(如果你谷歌或者百度,有很多回答,但实际并未能解决此问题)。曾经一度困扰许久。现在将我的解决方式写下来,希望可以对你有所帮助。

参考:

作为IM软件的领军,QQ与微信无疑给IM行业树立了一个很好的榜样。那我们就来看看它们是如何处理的(以下简单描述,自己可以实际体验):

QQ:
点击大图浏览时,会有一个转圈等待操作,对图片放大的大小无限制。在放大过程中,图片会模糊,停止操作后,一张清晰的高清图渲染出来。如果图片过大并分辨率超高(上万),会出现崩溃。

微信:
点击大图浏览时,直接展示。但是对图片展示大小有限制。放大到一定程度,无法继续放大查看。

做为办公软件,无需解释,很明显QQ的方式更符合需求。

实现:

对于大图,压缩肯定使我们需要的,QQ转圈等待同样我猜测也是压缩操作。

压缩:
压缩图片我们希望可以保证压缩的速度够快及内存消耗的尽可能小。在此感谢github上的OTLargeImageReader的作者,压缩过程中内存控制和速度都很好。

关键代码:

//先从内存中查找,查找不到再解码,避免重复解码
UIImage *cacheImage = [self.photoBrowser cacheImageWithPhoto:_photo];
if (cacheImage == nil) {//不存在,解码[self.photoBrowser showHUDWithSuperBigPhoto];dispatch_async(dispatch_get_global_queue(0, 0), ^{CGSize compressSize = CGSizeMake(XXPhotoCompressPixelMax, XXPhotoCompressPixelMax);if (image.size.width > image.size.height) {compressSize = CGSizeMake(XXPhotoCompressPixelMax, XXPhotoCompressPixelMax*image.size.height/image.size.width);}else {compressSize = CGSizeMake(XXPhotoCompressPixelMax*image.size.width/image.size.height, XXPhotoCompressPixelMax);}UIImage *compressedImage = [image imageByScalingProportionallyToSize:compressSize];dispatch_async(dispatch_get_main_queue(), ^{[self.photoBrowser cacheImageWithPhoto:_photo image:compressedImage];self.showImageView.image = compressedImage;[self.photoBrowser hideHUDWithSuperBigPhoto];[self resetSize];});});
}
else {//直接使用self.showImageView.image = cacheImage;
}

通过以上方式,加上参考QQ的交互方式,此时,一张分辨率有限的大图在经过短暂压缩处理后,已经可以非常安全的在app中展示浏览了(缓存压缩图片避免重复压缩)。但是,压缩过的图片放大后,模糊不清了!这不能忍,继续搞。
当在QQ中浏览图片进行放大时,可以很轻易的发现,此时的图片也是模糊的(这就印证了转圈过程中对图片的压缩操作),然而当我们停止放大操作后,当前展示的模糊图被重新渲染展示给我们,清晰,完美!
此时,如果你遇到过这个问题,并且尝试过解决,你肯定找到了苹果官方提供的Demo以及一些分块加载的方式。这个成本太高,不建议。
思来想去,一个新的方式出现了:用户在这个大图中,关注的只有当前屏幕中展示的这一区域的图片,当用户不操作图片时,拿到图片在手机屏幕上的元素覆盖展示出来。用户操作时,移除覆盖图层,停止后重新操作。

裁剪图片:
裁剪当前屏幕中展示对应原图中的位置

- (void)didCutImage {if (_orImage) {if (self.scrollView.contentSize.width >= kScreenWidth &&self.scrollView.contentSize.height >= kScreenHeight) {CGFloat multipleF = _orImage.size.width/self.scrollView.contentSize.width;CGFloat width = kScreenWidth*multipleF;CGFloat height = kScreenHeight *multipleF;//如果剪切的尺寸过大,不处理if (width > XXPhotoPixelMax ||height > XXPhotoPixelMax) {return;}//如果剪切的尺寸过大,不处理//裁剪展示视图if (_bigCupImageView) {_bigCupImageView.frame = CGRectMake(self.scrollView.contentOffset.x, self.scrollView.contentOffset.y, kScreenWidth, kScreenHeight);}else {[self.scrollView addSubview:self.bigCupImageView];}//裁剪展示视图CGImageRef cgRef = _orImage.CGImage;CGImageRef imageRef = CGImageCreateWithImageInRect(cgRef, CGRectMake(self.scrollView.contentOffset.x *multipleF   ,self.scrollView.contentOffset.y *multipleF, width, height));UIImage *thumbScale = [UIImage imageWithCGImage:imageRef];CGImageRelease(imageRef);self.bigCupImageView.image = thumbScale;}}
}

在这个过程中,仍需要注意的是,何时展示与隐藏剪切出来的图片。
覆盖图片的添加与移除:
添加:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {[NSObject cancelPreviousPerformRequestsWithTarget:self];[self performSelector:@selector(didCutImage) withObject:nil afterDelay:.5];
}

移除:

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(nullable UIView *)view {if (_bigCupImageView) {[_bigCupImageView removeFromSuperview];_bigCupImageView = nil;}
}

结语:

此解决方式在实现上非常简单,开始只是困于思路。如果你有其他的方式,那我们就开始一段愉快的交流吧!

iOS展示超大图片或超高分辨率图片崩溃解决方法相关推荐

  1. html图片在wps中不显示文字大小,WPS文字插入图片显示不全怎么办 WPS文字插入图片显示不完整的解决方法...

    在wps文字编辑文档时,如果我们在使用时插入图片显示不全,这种情况我们该怎么解决呢?想必有不少的用户遇到过这种问题,下面教程之家网为大家带来WPS文字插入图片显示不完整的解决方法,不知道怎么解决的朋友 ...

  2. html页面整体偏移了怎么办,html2canvas生成的图片偏移不完整的解决方法

    情景一: 问题背景:生成的图片在一个弹窗里面,如果页面没有滚动条就是正常的,但是一旦出现滚动条并且页面发生滚动时html2canvas绘制成的图片就会偏移出对应滚动高度的白边,如下: 解决办法: 楼主 ...

  3. win7系统不显示图片的缩略图的终极解决方法

    win7系统不显示图片的缩略图的终极解决方法 参考文章: (1)win7系统不显示图片的缩略图的终极解决方法 (2)https://www.cnblogs.com/senior-engineer/p/ ...

  4. Win11图片不显示缩略图怎么办?Win11图片不显示缩略图的解决方法

    正常情况下我们在点击打开文件夹的时候是可以看到图片的缩略图的,但也有一些小伙伴出现无法看到缩略图的情况,遇到这种情况应该如何解决呢?下面就和小编一起来看看有什么解决方法.更多教程参考小白一键装机网 W ...

  5. 图片放大不模糊的解决方法

    图片放大不模糊的解决方法!小编作为一名互联网运营人员,每天要使用很多的图片素材,也要处理很多的图片素材,比如转换图片格式,修改图片尺寸大小等.将图片尺寸放大虽然是一个比较简单的操作,却有一个难以解决的 ...

  6. CSS图片的下边有间隙解决方法

    CSS图片的下边有间隙解决方法 方法1:设置图片为块元素 img{display:block; } 方法2:给图片设置垂直对齐 图片行内块元素 他在对齐的时候默认的对齐方式与基线对齐 vertical ...

  7. vue动图加载图片不能正确显示的解决方法

    vue动图加载图片不能正确显示的解决方法 解决核心 代码 运行结果 上次解决过一次,没有记录,后来发现有小伙伴问我这个问题,我今天就顺手记录一下,具体的原因我这里就不详细说, 加载不出来简略的原因是v ...

  8. Windows Live Mail不能发送图片附件的2种解决方法

    Windows Live Mail不能发送图片附件的2种解决方法 1,打开注册表项HKEY_CURRENT_USER\Software\Microsoft\Windows Live Mail\mail ...

  9. html中图片之间有缝隙,科技常识:HTML5中图片之间的缝隙完美解决方法

    今天小编跟大家讲解下有关HTML5中图片之间的缝隙完美解决方法 ,相信小伙伴们对这个话题应该有所关注吧,小编也收集到了有关HTML5中图片之间的缝隙完美解决方法 的相关资料,希望小伙伴们看了有所帮助. ...

  10. 图片无法显示因计算机内存可能不足,Windows照片查看器无法显示此图片,内存可能不足的解决方法...

    最近在Windows10系统下使用Windows照片查看器打开一个JPG格式的图片,打开之后提示"Windows 照片查看器无法显示此图片,因为计算机上的可用内存可能不足.请关闭一些目前没有 ...

最新文章

  1. Hystrix熔断器功能测试示例数据
  2. 监听列表事件的监控核心技术(编写代码)
  3. JBoss核心Java Web服务
  4. react中使用构建缓存_使用React和Netlify从头开始构建电子商务网站
  5. obs命令行工具obsutil的使用测试
  6. linux共享内存变量 tiaojianbianliang,低压集抄系统中Linux共享内存使用分析
  7. Android Sensor Driver(四)——IIC总线和驱动
  8. 点云应用于电力行业助力输配电安全距离检测分析以及精细化巡检
  9. dep指定版本 go_Golang官方依赖管理工具:dep
  10. 支付宝二维码可以抓包更改金额_支付宝到账铃声,金额可以随意改。
  11. FileZillaClient连接虚拟机教程
  12. 疫情之下,企业如何突围?
  13. WordPress评论摘要标签:comment_excerpt
  14. js将网页保存成图片
  15. ggplot2设置坐标轴范围_ggplot2|详解八大基本绘图要素
  16. SpringCloud 微服务开放平台接口
  17. 阿里云短信服务与微信小程序对接进行注册
  18. linux安装和配置 MariaDB (ubuntu20.04)
  19. 联想Y700笔记本:硬盘突然不见了
  20. 程序Crash(奔溃)记录和分析工具——Crashlytics

热门文章

  1. 2021,我的海内外博士申请总结!
  2. Android Intent 机制解析 - Intent 是什么?作用是什么?
  3. c语言一个数平方表示,C语言 - 利用 汇编思想 写一个数的平方
  4. Unity XLua学习笔记(四):Hotfix热补丁
  5. TPS65217DRSLR 电源管理IC 设计用于便携式设备
  6. ARP报文抓包解析学习
  7. qq音乐网络异常获取音乐失败_QQ音乐无法播放_为什么qq音乐总是提示歌曲无效或网络连接失败?...
  8. 地震速度分析matlab程序,地震波频谱分析。。。。。
  9. 电脑tdr太低是什么意思_威猫解惑丨新版Substance Painter出现TDR值太低警告的解决办法...
  10. Linux的capability分析