1. 程式人生 > >美女圖片採集器 (源代碼+解析)

美女圖片採集器 (源代碼+解析)

關鍵代碼段 i++ 換圖 capi rdo -a 般的 bottom center

前言:


有一段時間沒寫博客了, "持之以恒"徽章都暗了, 實在不該。 前一段確實比較忙, ...小小地給自己的懶找個借口吧。

大二即將結束, 學習iOS也有一段時間了。今天抽點時間, 開源一個前幾天剛上傳的App裏面的一個功能, RT, 美女圖片採集器。 ? 美女.. 相信沒有人不喜歡吧, 基於此, 這個小Demo應運而生。


註:?


本文正在參加博客大賽。 假設認為對你有所幫助, 還望幫忙投下票。 多謝。

?

投票鏈接:?http://vote.blog.csdn.net/Article/Details?articleid=37825177 (投票button在最下方)

效果演示:


技術分享圖片技術分享圖片技術分享圖片技術分享圖片技術分享圖片


看到這裏, 假設還有興趣學習的話, 能夠先到我的git中下載源代碼, 然後配合著源代碼看我以下的解析。相信, 會讓你有所收獲的。

git下載鏈接:?BeautyPickDemo.git


涉及內容:


  1. 百度圖片API的使用
  2. JSON格式數據解析
  3. 圖片異步下載 + 離線緩存
  4. 圖片基本操作(縮放, 刪除, 加入, 保存到本地)
  5. 下拉刷新, 上提載入
  6. 幻燈片放映
  7. 自己定義後臺顯示圖片

源代碼解析:



一。百度圖片API的使用

首先, 我們知道百度是沒有對外開放圖片API的, 可是我們能夠通過谷歌瀏覽器來捕捉到訪問過程中它調用的API。有興趣的, 能夠了解下谷歌瀏覽器Network選項的使用, 也能夠參考下這篇文章:?百度圖片api這裏, 我們主要介紹怎樣使用就可以。
1.百度圖片通用API:http://image.baidu.com/i?

tn=resultjsonavstar&ie=utf-8&word=劉德華&pn=0&rn=60
說明:
返回格式為json
word為查詢的內容
pn為第幾頁
rn為一頁返回的圖片數量
用法:大家在瀏覽器地址欄輸入上述地址,回車就可以看到返回的圖片地址

2.百度圖片分類API (我們使用的就是這個)http://image.baidu.com/channel/listjson?pn=0&rn=30&tag1=美女&tag2=所有&ie=utf8
http://image.baidu.com/channel/listjson?

pn=0&rn=30&tag1=美女&tag2=所有&ftags=校花&ie=utf8

至於其它的, 按照這種方法都能獲取到. 就不反復說明了。
至於怎樣調用API, 涉及到網絡編程。開源的ASI類庫做的比較好(盡管挺老的一個東西了, 也有一段時間沒更新了, 可是能滿足我們需求)。從源代碼中, 能夠找到 網絡請求ASI目錄。裏面有須要的文件
1。導入這裏的文件2。導入必須的框架, 包含:SystemConfiguration.framework
MobileCoreServices.framework
CFNetwork.framework
libz.dylib
3。調用API (參見 主界面-->picVC)

@property (nonatomic,strong) ASIHTTPRequest *testRequest;

NSString* urlString = [NSString stringWithFormat:@"http://image.baidu.com/channel/listjson?pn=%d&rn=10&tag1=美女&tag2=%@", nowPage, [chooseArr objectAtIndex:nowChoose]];

urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlString];
testRequest = [ASIHTTPRequest requestWithURL:url];
[testRequest setDelegate:self];
[testRequest startAsynchronous];

就可以正常調用API。

至於怎樣處理返回的數據, 以下再詳細講。

二。

JSON格式數據解析

一般的數據格式有XMLJSON, 這裏由於調用百度圖片API返回的數據格式是JSON, 所以我們僅僅要解析JSON就可以。調用API成功後, 它會自己主動運行這個函數
#pragma mark - 載入數據完成
- (void)requestFinished:(ASIHTTPRequest *)request
我們僅僅須要在這裏解析數據, 使用數據就可以。
這種方法返回的數據是二進制格式的NSData, 我們須要手動轉為UTF8編碼。能夠這樣獲取:
//當以二進制讀取返回內容時用這種方法
    NSData *responseData = [request responseData];
    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];

接下去就是奇妙的時候了, 對於這種一個字符串, 假設直接打印, 你可能會看得雲裏霧裏的, json格式而且沒有又一次排列。可是我們能夠使用JsonKit來直接解析。(文件在json解析目錄中)
僅僅需這樣一條語句就可以:
self.testDic = [responseString objectFromJSONString];

打印解析後的數據例如以下:
技術分享圖片

至於須要哪些, 直接取就好了。比方. 我們這裏須要獲取到圖片的標題. url, 寬度, 高度
NSMutableDictionary *nowDic = [[NSMutableDictionary alloc]init];
[nowDic setObject:[[array objectAtIndex:i]objectForKey:@"image_url"] forKey:@"image_url"];
[nowDic setObject:[[array objectAtIndex:i]objectForKey:@"image_width"] forKey:@"image_width"];
[nowDic setObject:[[array objectAtIndex:i]objectForKey:@"image_height"] forKey:@"image_height"];
[nowDic setObject:[[array objectAtIndex:i]objectForKey:@"desc"] forKey:@"desc"];

[picArray addObject:nowDic];


三。圖片異步下載+離線緩存


這裏提一下SDWebImage, 我們將會使用它來實現。

詳細使用參見:SDWebImage 筆記在解析完json數據後, 我們會獲取到圖片相應的url。我們能夠通過訪問url獲取圖片。?

- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;
這是SDWebImage給我們提供的一個函數. 通過調用它, 我們能夠實現異步下載和離線緩存。


用法:

UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(SPACE / 2 , SPACE / 2 , width, height)];
NSURL *url = [NSURL URLWithString:imageInfo.thumbURL];
[imageView setImageWithURL:url placeholderImage:nil];
imageView.backgroundColor = [UIColor palePurpleColor];
[self addSubview:imageView];


異步下載,離線緩存效果:(離線緩存能夠到應用沙盒中查看)
技術分享圖片技術分享圖片


四。

圖片基本操作(縮放, 刪除, 加入, 保存到本地)


這裏涉及的主要是一些常規操作, 包含縮放, 刪除, 加入, 保存到本地等。至於刪除, 通常是長按刪除, 僅僅要在圖片上加上長按手勢響應就可以。然後彈出一個對話框, 提示用戶是否刪除。確定刪除後, 從沙盒中清除緩存就可以。加入手勢方法:
//長按
UILongPressGestureRecognizer *longRecognizer;
longRecognizer = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(handleSingleLongFrom:)];
[self addGestureRecognizer:longRecognizer];

從視圖和沙盒中刪除
        //從當前視圖中刪除
        [testArr removeObject:data];
        //刷新數據
        __weak picVC *blockSelf = self;
        [blockSelf.waterView refreshView:testArr];
        [blockSelf.waterView.infiniteScrollingView stopAnimating];
        
        //從沙盒中刪除
        //打開沙盒
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString * namePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"savedPicInfo_%d.plist",nowChoose]];
        NSMutableArray *picArray = [[NSMutableArray alloc] initWithContentsOfFile:namePath];
        
        for (int i=0; i<[picArray count]; i++)
        {
            if ([[[picArray objectAtIndex:i]objectForKey:@"image_url"] isEqualToString:data.thumbURL])
            {
                [picArray removeObjectAtIndex:i];
                break;
            }
        }
        [picArray writeToFile:namePath atomically:YES];

至於縮放, 首先要彈出一個全屏顯示的視圖。像這樣:
//單擊, 顯示大圖
-(void)showImage:(ImageInfo*)data
{
    NSURL *url = [NSURL URLWithString:data.thumbURL];
    [clickImage setImageWithURL:url placeholderImage:nil];
    TGRImageViewController *viewController = [[TGRImageViewController alloc] initWithImage:clickImage.image setImageInfo:data];
    viewController.transitioningDelegate = self;
    [self presentViewController:viewController animated:YES completion:nil];
}

本質就是調用presentViewController:viewController。當然。我們能夠給新視圖的顯示加上動畫效果, 例如以下:
#pragma mark - UIViewControllerTransitioningDelegate methods
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
    if ([presented isKindOfClass:TGRImageViewController.class]) {
        return [[TGRImageZoomAnimationController alloc] initWithReferenceImageView:clickImage];
    }
    return nil;
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
    if ([dismissed isKindOfClass:TGRImageViewController.class]) {
        return [[TGRImageZoomAnimationController alloc] initWithReferenceImageView:clickImage];
    }
    return nil;
}


然後, 在新視圖中, 加入點擊移除, 長按彈出新操作, 雙指移動縮放手勢就可以。

詳細實現例如以下:

#pragma mark - Private methods

- (void)longPress:(UITapGestureRecognizer *)tapGestureRecognizer
{
    
    if(tapGestureRecognizer.state == UIGestureRecognizerStateBegan)
    {
        [self popupActionSheet];
    }
}

- (IBAction)handleSingleTap:(UITapGestureRecognizer *)tapGestureRecognizer {
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (IBAction)handleDoubleTap:(UITapGestureRecognizer *)tapGestureRecognizer {
    if (self.scrollView.zoomScale == self.scrollView.minimumZoomScale) {
        // Zoom in
        CGPoint center = [tapGestureRecognizer locationInView:self.scrollView];
        CGSize size = CGSizeMake(self.scrollView.bounds.size.width / self.scrollView.maximumZoomScale,
                                 self.scrollView.bounds.size.height / self.scrollView.maximumZoomScale);
        CGRect rect = CGRectMake(center.x - (size.width / 2.0), center.y - (size.height / 2.0), size.width, size.height);
        [self.scrollView zoomToRect:rect animated:YES];
    }
    else {
        // Zoom out
        [self.scrollView zoomToRect:self.scrollView.bounds animated:YES];
    }
}



五。

下拉刷新, 上提載入

這個功能詳細在瀏覽圖片的時候使用。 代碼在picVC中。

可是由於我之前專門寫過一篇這種博客。 就不再反復了。詳細能夠看這裏:?iOS開發-ios7下拉刷新,上提載入高速集成

六。幻燈片放映

顧名思義, 就是能夠自己主動播放收藏過的美女圖片.. ?這裏的原理是利用UIView的動畫, 不斷切換顯示圖片和顯示效果。
切換效果例如以下:
    _transitionOptions= @[[NSNumber numberWithInteger:UIViewAnimationOptionTransitionFlipFromLeft],
                          [NSNumber numberWithInteger:UIViewAnimationOptionTransitionFlipFromRight],
                          [NSNumber numberWithInteger:UIViewAnimationOptionTransitionCurlUp],
                          [NSNumber numberWithInteger:UIViewAnimationOptionTransitionCurlDown],
                          [NSNumber numberWithInteger:UIViewAnimationOptionTransitionCrossDissolve],
                          [NSNumber numberWithInteger:UIViewAnimationOptionTransitionFlipFromTop],
                          [NSNumber numberWithInteger:UIViewAnimationCurveEaseIn],
                          [NSNumber numberWithInteger:UIViewAnimationCurveEaseOut],
                          [NSNumber numberWithInteger:UIViewAnimationCurveLinear],
                          [NSNumber numberWithInteger:UIViewAnimationOptionAllowAnimatedContent],
                          [NSNumber numberWithInteger:UIViewAnimationOptionOverrideInheritedCurve],
                          [NSNumber numberWithInteger:UIViewAnimationOptionTransitionFlipFromTop],
                          [NSNumber numberWithInteger:UIViewAnimationOptionTransitionFlipFromBottom]];

然後切換圖片的時候, 實現例如以下代碼就可以。

?(詳細參見PhotoStackView)

-(void)reloadData {
    
    if (!self.dataSource) {
        //exit if data source has not been set up yet
        self.photoViews = nil;
        return;
    }
    
    NSInteger numberOfPhotos = [self.dataSource numberOfPhotosInPhotoStackView:self];
    NSInteger topPhotoIndex  = [self indexOfTopPhoto]; // Keeping track of current photo‘s top index so that it remains on top if new photos are added
    
    if(numberOfPhotos > 0) {

        NSMutableArray *photoViewsMutable   = [[NSMutableArray alloc] initWithCapacity:numberOfPhotos];
        UIImage *borderImage                = [self.borderImage resizableImageWithCapInsets:UIEdgeInsetsMake(self.borderWidth, self.borderWidth, self.borderWidth, self.borderWidth)];
        
        for (NSUInteger index = 0; index < numberOfPhotos; index++) {

            UIImage *image = [self.dataSource photoStackView:self photoForIndex:index];
            CGSize imageSize = image.size;
            if([self.dataSource respondsToSelector:@selector(photoStackView:photoSizeForIndex:)]){
                imageSize = [self.dataSource photoStackView:self photoSizeForIndex:index];
            }
            UIImageView *photoImageView     = [[UIImageView alloc] initWithFrame:(CGRect){CGPointZero, imageSize}];
            photoImageView.image            = image;
            UIView *view                    = [[UIView alloc] initWithFrame:photoImageView.frame];
            view.layer.rasterizationScale   = [[UIScreen mainScreen] scale];            
            view.layer.shouldRasterize      = YES; // rasterize the view for faster drawing and smooth edges

            if (self.showBorder) {
                
                // Add the background image
                if (borderImage) {
                    // If there is a border image, we need to add a background image view, and add some padding around the photo for the border

                    CGRect photoFrame                = photoImageView.frame;
                    photoFrame.origin                = CGPointMake(self.borderWidth, self.borderWidth);
                    photoImageView.frame             = photoFrame;

                    view.frame                       = CGRectMake(0, 0, photoImageView.frame.size.width+(self.borderWidth*2), photoImageView.frame.size.height+(self.borderWidth*2));
                    UIImageView *backgroundImageView = [[UIImageView alloc] initWithFrame:view.frame];
                    backgroundImageView.image        = borderImage;
                    
                    [view addSubview:backgroundImageView];
                } else {
                    // if there is no boarder image draw one with the CALayer
                    view.layer.borderWidth        = self.borderWidth;
                    view.layer.borderColor        = [[UIColor whiteColor] CGColor];
                    view.layer.shadowOffset       = CGSizeMake(0, 0);
                    view.layer.shadowOpacity      = 0.5;
                }
            }

            [view addSubview:photoImageView];

            view.tag    = index;
            view.center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));

            [photoViewsMutable addObject:view];
            
        }

        // Photo views are added to subview in the photoView setter
        self.photoViews = photoViewsMutable; photoViewsMutable = nil;
        [self goToPhotoAtIndex:topPhotoIndex];
        
    }
    
}



七。自己定義後臺顯示圖片

這個功能就是演示效果裏面, 當應用切換到後臺後, 我們雙擊home鍵後顯示後臺程序時候, 該應用的顯示效果。比方.. ?有時候我們瀏覽的圖片尺度比較大.. 然後切到後臺的時候, 就希望把它隱藏起來.. ?
這就涉及到了Background Fetch的應用。之前也寫過一篇博客專門介紹。 這裏就不反復了。

詳細參見:?iOS開發-自己定義後臺顯示圖片(iOS7-Background Fetch的應用)



好了。 到這裏最終是介紹的幾乎相同了。當然。 我這裏的解析都比較概括, 列舉的都是幾個關鍵代碼段。更加詳細的還是須要自己去看代碼。 凝視也寫了, 預計沒什麽問題。 假設有問題, 歡迎聯系我。
一口氣寫了3個小時的博客... ?累的夠嗆的。也希望, 能對你有所幫助。


本文正在參加博客大賽。

假設認為對你有所幫助, 還望幫忙投下票。

多謝。?

投票鏈接:?http://vote.blog.csdn.net/Article/Details?

articleid=37825177 (投票button在最下方)



學習的路上, 與君共勉。

美女圖片採集器 (源代碼+解析)