本文为CocoaChina网友xxg90s投稿

前言:

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 加载大量图片崩溃_iOS超高分辨率图片崩溃解决方法相关推荐

  1. iOS 加载本地HTML文件,图片没显示出来的问题

    iOS 加载本地HTML文件,图片没显示出来的问题,一般都是路径的问题.在HTML中,用的是绝对路径类似,而在项目中,一般 都是相对路径.例如:在HTML中, src="images/qq. ...

  2. Matlab在win10运行不出图片,win10系统网页图片加载不出来的六种原因及解决方法...

    大家经常会使用浏览器来浏览一些站点查看图片,最近有的用户说win10系统打开网页时发现页面图片加载不出来,只显示一个×标志,让人百思不得其解,其实出现此问题可能是网速过低,或者浏览器设置里面没有开启相 ...

  3. vue本地项目配置图片加载失败_vue图片加载失败时用默认图片替换的方法

    vue图片加载失败时用默认图片替换的方法 前言 本文主要给大家介绍的关于vue实现图片加载失败时用默认图片替换的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 方法如下 原理 ...

  4. 未来教育c语言加载不出来图片,win10系统网页图片加载不出来的六种原因及解决方法[多图]...

    大家经常会使用浏览器来浏览一些站点查看图片,最近有的用户说win10系统打开网页时发现页面图片加载不出来,只显示一个×标志,让人百思不得其解,其实出现此问题可能是网速过低,或者浏览器设置里面没有开启相 ...

  5. IDEA——找不到或无法加载主类的一种暴力解决方法

    IDEA--找不到或无法加载主类的一种暴力解决方法 参考文章: (1)IDEA--找不到或无法加载主类的一种暴力解决方法 (2)https://www.cnblogs.com/jsjliyang/p/ ...

  6. PS中添加插件 无法加载扩展,未经正确签署的解决方法

    为什么会出现PS无法加载扩展,未经正确签署的解决方法 因为PS没有在注册表中注册 我们如何解决呢? 打开注册表 添加字符串 这样就行了

  7. VS2013出现未能正确加载 microsoft.visualstudio.editor.implementation.editorpackage的解决方法

    出现这个问题的原因可能是配置更改或安装了另一个扩展,幸好之前用的不多,重新进行用户配置代价也不高,打开Visual Studio Tools: 选择VS2013 开发人员命令提示: 输入devenv ...

  8. 卸载Axmath 后,word加载项中还是有 Axmath 的解决方法

    我是自己之前不知道装什么的时候装了axmath,不是破解版.当我卸载重装时发现,卸不干净问题.找了很多方法,最后根据一位大佬卸载mathtype的方法给解决了.解决方法如下. 解决方法 在" ...

  9. spring boot启动类启动 错误: 找不到或无法加载主类 xxx.xxxx.Application 的解决方法

    spring boot启动类启动 错误: 找不到或无法加载主类 xxx.xxxx.Application 的解决方法 导入的一个外部的spring boot项目,运行启动类,忽然提示找不到或者无法加载 ...

最新文章

  1. cs怎么加电脑人_怎么给电脑文件夹加密码?
  2. JetBrains产品永久破解
  3. VHDL | 音乐盒设计(代码类)
  4. 【thymeleaf】data-*
  5. 关联挖掘算法Apriori和FP-Tree学习
  6. LeetCode Hot100 ---- 二分查找专题
  7. 递归函数基例和链条_链条和叉子
  8. scrapy-redis 使 redis 不止保存 url(例如:json)
  9. ASCII码表 0-255完整版 附详细注释
  10. Python Imaging Library: ImageGrab Module(图像采集模块)
  11. subtype,supertype 与 subclass,superclass 的异同
  12. 【免费个人网站制作】免费个人网站如何制作?
  13. HTML结构及常用的标签
  14. 【操作系统】BIOS篇
  15. Teams中阻止上传文件--详解
  16. r5 7600x和r7 7700x差距
  17. 微信小程序退出功能(退回到微信)
  18. 如何把密度函数化为标准正态二维分布_高中就开始学的正态分布,原来如此重要...
  19. 抖音测试小程序功能开发
  20. 软件版本号规则和命名规则

热门文章

  1. Python时序预测_第一篇
  2. Java生成PDF文档(表格)
  3. 苹果屏蔽更新_iPhone 不想更新系统怎么办?一招屏蔽
  4. VR全景创业为什么要选择加盟?
  5. ilruntime介绍
  6. Java操作json数据导入Excel
  7. 6个一描述初中这个叛逆年龄段的青少年
  8. 软件工程毕业设计 SSM共享充电宝管理系统(源码+论文)
  9. C++顺序结构——对角线
  10. java的引用数据类型