猫猫学iOS(五十一)多线程网络之GCD下载合并图片_队列组的使用

猫猫分享,必须精品

原创文章,欢迎转载。转载请注明:翟乃玉的博客

地址:http://blog.csdn.net/u013357243?viewmode=contents

合并图片(图片水印)第一种方法

效果

实现:

思路:

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();
时间: 2024-08-05 16:02:06

猫猫学iOS(五十一)多线程网络之GCD下载合并图片_队列组的使用的相关文章

猫猫学IOS(十八)UI之QQ聊天布局_键盘通知实现自动弹出隐藏_自动回复

猫猫分享,必须精品 素材代码地址:http://blog.csdn.net/u013357243/article/details/45000699 原文地址:http://blog.csdn.net/u013357243?viewmode=contents 先看图片 第一步完成tableView和Cell的架子的图 完善图片 键盘弹出设置后图片: 自动回复图: 粗狂的架子 tableView和Cell的创建 首相tableView为了学习方便就直接用stroyBoard拖拽了,包括一些学习意义不

猫猫学iOS之小知识之xcode6自己主动提示图片插件 KSImageNamed的安装

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 一:首先看效果 KSImageNamed是让XCode能预览项目中图片的插件 非常牛逼,据说写这个插件的牛人在日本~ 主要针对imageNamed:方法 效果如图: 安装: 首先须要到githup去下载(随便百度下下载地址一堆. . ) 项目地址为 https://github.com/ksuther/KSImageNamed-Xcode 下载好后是一个项目 点

猫猫学iOS之小知识之_xcode插件的删除方法_自己主动提示图片插件KSImageNamed有时不灵_分类或宏之类不能自己主动提示,

猫猫分享,必须精品 原创文章.欢迎转载. 转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 一:解决解决自己主动提示图片插件KSImageNamed有时不灵_分类或宏之类不能自己主动提示 事实上.插件神马的我们自己也能写.并没有想象中的那么难,只是眼下我们还是先解决当前问题 在做微博项目时候.抽取的分类有一个 +(instancetype)imageWithOriginalName:(NSString *)imageName; 可是调用的时候,当中字

猫猫学iOS 之微博项目实战(10)微博cell中图片的显示以及各种填充模式简介

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 :一效果 如果直接设置会有拉伸等等的状况,这里主要介绍图片显示的一些细节 二:代码 代码实现其实很简单,微博当中用了一个photos来存放九宫格这些图片,然后用了一个photo类来做每个photo,并且在上面显示gif等的样式,很多很多小技巧,直接上代码 九宫格根据行列设置等算法,不难 #import "HWStatusPhotosView.h" #i

(素材源码)猫猫学IOS(十八)UI之QQ聊天布局_键盘通知实现自动弹出隐藏_自动回复

猫猫分享,必须精品 素材代码地址:http://download.csdn.net/detail/u013357243/8585703 原文地址:http://blog.csdn.net/u013357243?viewmode=contents 先看图片 第一步完成tableView和Cell的架子的图 完善图片 键盘弹出设置后图片: 自动回复图: 粗狂的架子 tableView和Cell的创建 首相tableView为了学习方便就直接用stroyBoard拖拽了,包括一些学习意义不大的图片等等

(素材_源码) 猫猫学IOS(五)UI之360等下载管理器九宫格UI

猫猫分享,必须精品 先看效果 代码学习地址: 猫猫学IOS(五)UI之360等下载管理器九宫格UI 猫猫学IOS(五)UI之360等下载管理器九宫格UI http://blog.csdn.net/u013357243/article/details/44486609 下载地址:http://download.csdn.net/detail/u013357243/8516817 ps1:有想要源码的可以加猫猫微信znycat QQ也可以:1764541256 --视频学习资料素材免费分析,哎自己一

猫猫学IOS(四)UI之半小时搞定Tom猫

话不多说 先上效果 项目源码素材下载地址: Tom猫游戏代码iOS 素材http://blog.csdn.net/u013357243/article/details/44457357 效果图 曾经风靡一时的tom猫其实制作起来那是叫一个相当的easy啊 功能全部实现,(关键是素材,没有素材的可以加我微信) 新手也可以很快的完成tom这个很拉轰的ios应用哦 做过android的我表示,android党默哀下把,那个做起来真心痛苦.... 然后呢你需要准备这些素材... 拖拽控件吧,因为这一个项

猫猫学iOS(五十五)多线程网络之图片下载框架之SDWebImage

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 效果: 代码: - (NSArray *)apps { if (!_apps) { NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"apps.plist" ofType:nil

猫猫学iOS 之微博项目实战(2)微博主框架-自己定义导航控制器NavigationController

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 一:加入导航控制器 上一篇博客完毕了对底部的TabBar的设置,这一章我们完毕自己定义导航控制器(NYNavigationController). 为啥要做自己定义呢.由于为了更好地封装代码,而且系统的UINavigationController不能满足我们的需求了,所以得自己定义. 首先,我们在NYTabBarViewCon