AJ学IOS(51)多线程网络之GCD下载合并图片_队列组的使用
AJ分享,必须精品
合并图片(图片水印)第一种方法
效果
实现:
思路:
1.分别下载2张图片:大图片、LOGO
2.合并2张图片
3.显示到一个imageView身上
// 异步下载
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 1.下载第1张
NSURL *url1 = [NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee460de6182ff5e0fe99257e80.jpg"];
NSData *data1 = [NSData dataWithContentsOfURL:url1];
UIImage *image1 = [UIImage imageWithData:data1];
// 2.下载第2张
NSURL *url2 = [NSURL URLWithString:@"http://su.bdimg.com/static/superplus/img/logo_white_ee663702.png"];
NSData *data2 = [NSData dataWithContentsOfURL:url2];
UIImage *image2 = [UIImage imageWithData:data2];
// 3.合并图片
// 开启一个位图上下文
UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0.0);
// 绘制第1张图片
CGFloat image1W = image1.size.width;
CGFloat image1H = image1.size.height;
[image1 drawInRect:CGRectMake(0, 0, image1W, image1H)];
// 绘制第2张图片
CGFloat image2W = image2.size.width * 0.5;
CGFloat image2H = image2.size.height * 0.5;
CGFloat image2Y = image1H - image2H;
[image2 drawInRect:CGRectMake(0, image2Y, image2W, image2H)];
// 得到上下文中的图片
UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext();
// 结束上下文
UIGraphicsEndImageContext();
// 4.回到主线程显示图片
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image = fullImage;
});
});
但是这样虽然在异步线程中完成的,不过,当下载完第一个图的时候,第二个图还没下,在等待,我们想让每一个图都在一个单独的异步线程里面下载,于是我们用第二种方法。
:第二种方法
首先定义两个imageView
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (nonatomic, strong) UIImage *image1;
@property (nonatomic, strong) UIImage *image2;
然后实现这样实现
// 异步下载
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 1.下载第1张
NSURL *url1 = [NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee460de6182ff5e0fe99257e80.jpg"];
NSData *data1 = [NSData dataWithContentsOfURL:url1];
self.image1 = [UIImage imageWithData:data1];
[self bindImages];
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 2.下载第2张
NSURL *url2 = [NSURL URLWithString:@"http://su.bdimg.com/static/superplus/img/logo_white_ee663702.png"];
NSData *data2 = [NSData dataWithContentsOfURL:url2];
self.image2 = [UIImage imageWithData:data2];
[self bindImages];
});
工作原理是开两个异步线程来分别下载两个图片,下载结束后都会调用
【self bindImages】方法,这时候我们在s 方法中设置回到主界面刷新,不过首先要判断两张图是否有数据,如下:
- (void)bindImages
{
if (self.image1 == nil || self.image2 == nil) return;
// 3.合并图片
// 开启一个位图上下文
UIGraphicsBeginImageContextWithOptions(self.image1.size, NO, 0.0);
// 绘制第1张图片
CGFloat image1W = self.image1.size.width;
CGFloat image1H = self.image1.size.height;
[self.image1 drawInRect:CGRectMake(0, 0, image1W, image1H)];
// 绘制第2张图片
CGFloat image2W = self.image2.size.width * 0.5;
CGFloat image2H = self.image2.size.height * 0.5;
CGFloat image2Y = image1H - image2H;
[self.image2 drawInRect:CGRectMake(0, image2Y, image2W, image2H)];
// 得到上下文中的图片
UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext();
// 结束上下文
UIGraphicsEndImageContext();
// 4.回到主线程显示图片
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image = fullImage;
});
}
虽然我们通过我们自己的想法解决了问题,不过其实我们有更好的解决方案,那就是队列组
第三种方法:队列组完成
什么时候用队列组呢?
首先:分别异步执行2个耗时的操作
其次:等2个异步操作都执行完毕后,再回到主线程执行操作
如果想要快速高效地实现上述需求,可以考虑用队列组,用法如下:
// 1.创建队列组
dispatch_group_t group = dispatch_group_create();
// 2.1第一个队列组异步
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行1个耗时的异步操作
});
// 2.2第二个队列组异步
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行1个耗时的异步操作
});
// 3.所有队列组异步线程结束后
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 等前面的异步操作都执行完毕后,回到主线程...
});
那就让我们来用队列组完成他吧,代码如下:
// 1.队列组
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 2.下载图片1
__block UIImage *image1 = nil;
dispatch_group_async(group, queue, ^{
NSURL *url1 = [NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee460de6182ff5e0fe99257e80.jpg"];
NSData *data1 = [NSData dataWithContentsOfURL:url1];
image1 = [UIImage imageWithData:data1];
});
// 3.下载图片2
__block UIImage *image2 = nil;
dispatch_group_async(group, queue, ^{
NSURL *url2 = [NSURL URLWithString:@"http://su.bdimg.com/static/superplus/img/logo_white_ee663702.png"];
NSData *data2 = [NSData dataWithContentsOfURL:url2];
image2 = [UIImage imageWithData:data2];
});
// 4.合并图片 (保证执行完组里面的所有任务之后,再执行notify函数里面的block)
dispatch_group_notify(group, queue, ^{
// 开启一个位图上下文
UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0.0);
// 绘制第1张图片
CGFloat image1W = image1.size.width;
CGFloat image1H = image1.size.height;
[image1 drawInRect:CGRectMake(0, 0, image1W, image1H)];
// 绘制第2张图片
CGFloat image2W = image2.size.width * 0.5;
CGFloat image2H = image2.size.height * 0.5;
CGFloat image2Y = image1H - image2H;
[image2 drawInRect:CGRectMake(0, image2Y, image2W, image2H)];
// 得到上下文中的图片
UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext();
// 结束上下文
UIGraphicsEndImageContext();
// 5.回到主线程显示图片
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image = fullImage;
});
});
__block关键字
注意:这里我们用到了一个__block的关键字,这是因为如果不加的话,block里面的是不能访问block外面的东西的。
小小总结:
开启异步
(直接敲dispatch_a。。。就能出来一堆提示,然后选选填填,没啥难度,前面说过了)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
code
});
开启队列组:
首先建一个队列组:
dispatch_group_t group = dispatch_group_create();
然后把原来放队列的地方换成队列组 并且用dispatch_get_global_queue这个
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行1个耗时的异步操作
});
上面这段能多弄几个,弄几个就有几个线程
然后结束时候用这个:
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 等前面的异步操作都执行完毕后,回到主线程...
});
合并图片的过程
步骤:
1.开启一个位图上下文
2.1绘制第1张图片
2.2绘制第2张图片
3.得到上下文中的图片
4.结束上下文
// 1.开启一个位图上下文
UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0.0);
// 2.1绘制第1张图片
CGFloat image1W = image1.size.width;
CGFloat image1H = image1.size.height;
[image1 drawInRect:CGRectMake(0, 0, image1W, image1H)];
// 2.2绘制第2张图片
CGFloat image2W = image2.size.width * 0.5;
CGFloat image2H = image2.size.height * 0.5;
CGFloat image2Y = image1H - image2H;
[image2 drawInRect:CGRectMake(0, image2Y, image2W, image2H)];
// 3.得到上下文中的图片
UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext();
// 4.结束上下文
UIGraphicsEndImageContext();
AJ学IOS(51)多线程网络之GCD下载合并图片_队列组的使用的更多相关文章
- AJ学IOS(44)之网易彩票自定义图片在右边的Button_弹出view_ios6,7简单适配
AJ分享,必须精品 效果: 注意图里面了吗,其实那个效果做起来真的很简单,在iOS中苹果给我们封装的很好,关键是那个按钮 系统的按钮的图片是在左边的,这里我们需要把他调整到右边,然后呢需要我们自己做一 ...
- AJ学IOS 之小知识之xcode6自动提示图片插件 KSImageNamed的安装
AJ分享,必须精品 一:首先看效果 KSImageNamed是让XCode能预览项目中图片的插件 很牛逼,据说写这个插件的牛人在日本~ 主要针对imageNamed:方法 效果如图: 安装: 首先需要 ...
- AJ学IOS(36)UI之手势事件旋转_缩放_拖拽
AJ分享,必须精品 效果 完成一个图片的捏合缩放,拖拽,旋转动作. 设计思路 拖拽: 首先是最简单的拖拽 //拖拽 -(void)panTest { UIPanGestureRecognizer *p ...
- AJ学IOS(18)UI之QQ聊天布局_键盘通知实现自动弹出隐藏_自动回复
AJ分享,必须精品 先看图片 第一步完成tableView和Cell的架子的图 完善图片 键盘弹出设置后图片: 自动回复图: 粗狂的架子 tableView和Cell的创建 首相tableView为了 ...
- AJ学IOS(07)UI之UITextField代理事件_类似QQ登陆窗口的简单实现
AJ分享,必须精品 先看效果图: 学习代码 // // NYViewController.m // 05-UITextField事件_UIKit复习 // // Created by apple on ...
- AJ学IOS(55)多线程网络之图片下载框架之SDWebImage
AJ分享,必须精品 效果: 代码: - (NSArray *)apps { if (!_apps) { NSArray *dictArray = [NSArray arrayWithContentsO ...
- AJ学IOS(48)多线程网络之多线程简单了解
AJ分享,必须精品 一:进程和线程 1:什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内. 比如同时打开QQ.Xcode,系统就会分 ...
- iOS开发多线程篇 08 —GCD的常见用法
iOS开发多线程篇—GCD的常见用法 一.延迟执行 1.介绍 iOS常见的延时执行有2种方式 (1)调用NSObject的方法 [self performSelector:@selector(run) ...
- iOS开发多线程篇 07 —GCD的基本使用
iOS开发多线程篇—GCD的基本使用 一.主队列介绍 主队列:是和主线程相关联的队列,主队列是GCD自带的一种特殊的串行队列,放在主队列中得任务,都会放到主线程中执行. 提示:如果把任务放到主队列中进 ...
随机推荐
- EOS基础全家桶(一)开篇
简介 从今天开始我会在FishoPark上与大家分享EOS的一些技术经验和基础,如果大家在看文章的过程中有任何问题,欢迎在网站下方的评论里留言,我会尽力为大家解答,如果发现我内容中所写有错,欢迎指正, ...
- Spring Boot入门系列(八)整合定时任务Task,一秒搞定定时任务
前面介绍了Spring Boot 中的整合Redis缓存已经如何实现数据缓存功能.不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/categ ...
- 成为视频分析专家:自动生成视频集锦(Python实现)
介绍 我是个超级板球迷.从我记事起,我就迷上了这项运动,至今它仍在我的日常生活中起着重要的作用.我相信很多读到这篇文章的人都会点头! 但是自从我开始工作以来,要跟上所有的比赛就成了一件棘手的事.我不能 ...
- php 设置允许跨域请求
php 服务端代码 <?php header('Content-Type: text/html;charset=utf-8'); header('Access-Control-Allow-Ori ...
- Fiddler抓取数据包分析案例
案例:利用Fiddler抓取苏宁易购网站数据包分析 抓包软件:Fiddler4 请求名字:www.suning.com 详细内容: 一.了解数据包区域的字段含义 图1数据包区域 #:顺序号,按照抓包的 ...
- Premultiplied Alpha
Xcode 的工程选项里有一项 Compress PNG Files,会对 PNG 进行 Premultiplied Alpha.游戏开发中会更加关注这个格式,省一些运行时计算. Premultipl ...
- [vijos1120]花生采摘<贪心>
题目链接:https://vijos.org/p/1120 这怕是我打过最水的一道题了,但是这道隶属于普及组难度的题我竟然提交4次才过,这不禁让我有些后怕,所以还是含泪写下这篇博客,用来警示一下自己: ...
- 深入解读ES6系列(一)
ECMAScript 6(ES6)简介 前言: 哈喽小伙伴们,爱说'废'话的Z又回来了,欢迎来到Super IT曾的博客时间,我说啦这个月要带的福利,说了更的博客肯定不能水你们,要一起进步学习嘛,今天 ...
- DEV Chart控件鼠标选中某条曲线
this.Chart.ObjectSelected += new DevExpress.XtraCharts.HotTrackEventHandler(this.Chart_ObjectSelecte ...
- mysql 中UNIQUE KEY 到底是约束还是索引?
答案来自:https://zhidao.baidu.com/question/1863373387452612907.html 两者关系 unique索引包含了unique约束,因为unique约束是 ...