貓貓學iOS(五十一)多線程網路之GCD下載合并圖片_隊列組的使用

來源:互聯網
上載者:User

標籤:下載   ios   多線程   網路   圖片   

貓貓分享,必須精品

原創文章,歡迎轉載。轉載請註明:翟乃玉的部落格
地址: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();

貓貓學iOS(五十一)多線程網路之GCD下載合并圖片_隊列組的使用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.