美女图片采集器 (源码+解析)[通俗易懂]

美女图片采集器 (源码+解析)[通俗易懂]前言:有一段时间没写博客了,”持之以恒”徽章都暗了,实在不该。前一段确实比较忙,…小小地给自己的懒找个借口吧。大二即将结束,学习iOS也有一段时间了。今天抽点时间,开源一个前几天刚上传的App里面的一个功能,RT,美女图片采集器。 美女..相信没有人不喜欢吧,基于此,这个小Demo应运而生。注: 本文正在参加博

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

前言:


有一段时间没写博客了, “持之以恒”徽章都暗了, 实在不该。 前一段确实比较忙, …小小地给自己的懒找个借口吧。 大二即将结束, 学习iOS也有一段时间了。今天抽点时间, 开源一个前几天刚上传的App里面的一个功能, RT, 美女图片采集器。   美女.. 相信没有人不喜欢吧, 基于此, 这个小Demo应运而生。

注: 

本文正在参加博客大赛。 如果觉得对你有所帮助, 还望帮忙投下票。 多谢。 

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

效果演示:

美女图片采集器 (源码+解析)[通俗易懂]美女图片采集器 (源码+解析)[通俗易懂]美女图片采集器 (源码+解析)[通俗易懂]美女图片采集器 (源码+解析)[通俗易懂]美女图片采集器 (源码+解析)[通俗易懂]

看到这里, 如果还有兴趣学习的话, 可以先到我的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)
[objc] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. @property (nonatomic,strongASIHTTPRequest *testRequest;  

[objc] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. NSString* urlString = [NSString stringWithFormat:@”http://image.baidu.com/channel/listjson?pn=%d&rn=10&tag1=美女&tag2=%@”, nowPage, [chooseArr objectAtIndex:nowChoose]];  
  2.   
  3. urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];  
  4. NSURL *url = [NSURL URLWithString:urlString];  
  5. testRequest = [ASIHTTPRequest requestWithURL:url];  
  6. [testRequest setDelegate:self];  
  7. [testRequest startAsynchronous];  

即可正常调用API。至于如何处理返回的数据, 下面再详细讲。

二。JSON格式数据解析

一般的数据格式有
XML
JSON, 这里因为调用百度图片API返回的数据格式是JSON, 所以我们只要解析JSON即可。
调用API成功后, 它会自动执行这个函数

[objc] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. #pragma mark – 加载数据完毕  
  2. – (void)requestFinished:(ASIHTTPRequest *)request  

我们只需要在这里解析数据, 使用数据即可。


这个方法返回的数据是二进制格式的NSData, 我们需要手动转为UTF8编码。可以这样获取:
[objc] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. //当以二进制读取返回内容时用这个方法  
  2.     NSData *responseData = [request responseData];  
  3.     NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];  

接下去就是神奇的时候了, 对于这样的一个字符串, 如果直接打印, 你可能会看得云里雾里的, json格式并且没有重新排列。

但是我们可以使用JsonKit来直接解析。(文件在json解析文件夹中)

只需这样一条语句即可:
[objc] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. self.testDic = [responseString objectFromJSONString];  

打印解析后的数据如下:

美女图片采集器 (源码+解析)[通俗易懂]


至于需要哪些, 直接取就好了。比如. 我们这里需要获取到图片的标题. url, 宽度, 高度
[objc] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. NSMutableDictionary *nowDic = [[NSMutableDictionary alloc]init];  
  2. [nowDic setObject:[[array objectAtIndex:i]objectForKey:@”image_url”] forKey:@”image_url”];  
  3. [nowDic setObject:[[array objectAtIndex:i]objectForKey:@”image_width”] forKey:@”image_width”];  
  4. [nowDic setObject:[[array objectAtIndex:i]objectForKey:@”image_height”] forKey:@”image_height”];  
  5. [nowDic setObject:[[array objectAtIndex:i]objectForKey:@”desc”] forKey:@”desc”];  
  6.   
  7. [picArray addObject:nowDic];  

三。图片异步下载+离线缓存


这里提一下SDWebImage, 我们将会使用它来实现。 具体使用参见:
SDWebImage 笔记
在解析完json数据后, 我们会获取到图片对应的url。
我们可以通过访问url获取图片。 
[objc] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. – (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;  

这是SDWebImage给我们提供的一个函数. 通过调用它, 我们可以实现异步下载和离线缓存。


使用方法:
[objc] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(SPACE / 2 , SPACE / 2 , width, height)];  
  2. NSURL *url = [NSURL URLWithString:imageInfo.thumbURL];  
  3. [imageView setImageWithURL:url placeholderImage:nil];  
  4. imageView.backgroundColor = [UIColor palePurpleColor];  
  5. [self addSubview:imageView];  
异步下载,离线缓存效果:(离线缓存可以到应用沙盒中查看)

美女图片采集器 (源码+解析)[通俗易懂]
美女图片采集器 (源码+解析)[通俗易懂]



四。图片基本操作(缩放, 删除, 添加, 保存到本地)


这里涉及的主要是一些常规操作, 包括缩放, 删除, 添加, 保存到本地等。
至于删除, 一般是长按删除, 只要在图片上加上长按手势响应即可。然后弹出一个对话框, 提示用户是否删除。确定删除后, 从沙盒中清除缓存即可。
添加手势方法:
[objc] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. //长按  
  2. UILongPressGestureRecognizer *longRecognizer;  
  3. longRecognizer = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(handleSingleLongFrom:)];  
  4. [self addGestureRecognizer:longRecognizer];  

从视图和沙盒中删除

[objc] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. //从当前视图中删除  
  2. [testArr removeObject:data];  
  3. //刷新数据  
  4. __weak picVC *blockSelf = self;  
  5. [blockSelf.waterView refreshView:testArr];  
  6. [blockSelf.waterView.infiniteScrollingView stopAnimating];  
  7.   
  8. //从沙盒中删除  
  9. //打开沙盒  
  10. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
  11. NSString *documentsDirectory = [paths objectAtIndex:0];  
  12. NSString * namePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@”savedPicInfo_%d.plist”,nowChoose]];  
  13. NSMutableArray *picArray = [[NSMutableArray alloc] initWithContentsOfFile:namePath];  
  14.   
  15. for (int i=0; i<[picArray count]; i++)  
  16. {  
  17.     if ([[[picArray objectAtIndex:i]objectForKey:@”image_url”] isEqualToString:data.thumbURL])  
  18.     {  
  19.         [picArray removeObjectAtIndex:i];  
  20.         break;  
  21.     }  
  22. }  
  23. [picArray writeToFile:namePath atomically:YES];  

至于缩放, 首先要弹出一个全屏显示的视图。

像这样:
[objc] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. //单击, 显示大图  
  2. -(void)showImage:(ImageInfo*)data  
  3. {  
  4.     NSURL *url = [NSURL URLWithString:data.thumbURL];  
  5.     [clickImage setImageWithURL:url placeholderImage:nil];  
  6.     TGRImageViewController *viewController = [[TGRImageViewController alloc] initWithImage:clickImage.image setImageInfo:data];  
  7.     viewController.transitioningDelegate = self;  
  8.     [self presentViewController:viewController animated:YES completion:nil];  
  9. }  

本质就是调用presentViewController:viewController。

当然,我们可以给新视图的显示加上动画效果, 如下:
[objc] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. #pragma mark – UIViewControllerTransitioningDelegate methods  
  2. – (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source  
  3. {  
  4.     if ([presented isKindOfClass:TGRImageViewController.class]) {  
  5.         return [[TGRImageZoomAnimationController alloc] initWithReferenceImageView:clickImage];  
  6.     }  
  7.     return nil;  
  8. }  
  9.   
  10. – (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {  
  11.     if ([dismissed isKindOfClass:TGRImageViewController.class]) {  
  12.         return [[TGRImageZoomAnimationController alloc] initWithReferenceImageView:clickImage];  
  13.     }  
  14.     return nil;  
  15. }  
然后, 在新视图中, 添加点击移除, 长按弹出新操作, 双指移动缩放手势即可。
具体实现如下:
[objc] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. #pragma mark – Private methods  
  2.   
  3. – (void)longPress:(UITapGestureRecognizer *)tapGestureRecognizer  
  4. {  
  5.       
  6.     if(tapGestureRecognizer.state == UIGestureRecognizerStateBegan)  
  7.     {  
  8.         [self popupActionSheet];  
  9.     }  
  10. }  
  11.   
  12. – (IBAction)handleSingleTap:(UITapGestureRecognizer *)tapGestureRecognizer {  
  13.     [self dismissViewControllerAnimated:YES completion:nil];  
  14. }  
  15.   
  16. – (IBAction)handleDoubleTap:(UITapGestureRecognizer *)tapGestureRecognizer {  
  17.     if (self.scrollView.zoomScale == self.scrollView.minimumZoomScale) {  
  18.         // Zoom in  
  19.         CGPoint center = [tapGestureRecognizer locationInView:self.scrollView];  
  20.         CGSize size = CGSizeMake(self.scrollView.bounds.size.width / self.scrollView.maximumZoomScale,  
  21.                                  self.scrollView.bounds.size.height / self.scrollView.maximumZoomScale);  
  22.         CGRect rect = CGRectMake(center.x – (size.width / 2.0), center.y – (size.height / 2.0), size.width, size.height);  
  23.         [self.scrollView zoomToRect:rect animated:YES];  
  24.     }  
  25.     else {  
  26.         // Zoom out  
  27.         [self.scrollView zoomToRect:self.scrollView.bounds animated:YES];  
  28.     }  
  29. }  

五。下拉刷新, 上提加载

这个功能具体在浏览图片的时候使用。 代码在picVC中。
但是因为我之前专门写过一篇这样的博客。 就不再重复了。


六。幻灯片放映

顾名思义, 就是能够自动播放收藏过的美女图片..  
这里的原理是利用UIView的动画, 不断切换显示图片和显示效果。

切换效果如下:
[objc] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. _transitionOptions= @[[NSNumber numberWithInteger:UIViewAnimationOptionTransitionFlipFromLeft],  
  2.                       [NSNumber numberWithInteger:UIViewAnimationOptionTransitionFlipFromRight],  
  3.                       [NSNumber numberWithInteger:UIViewAnimationOptionTransitionCurlUp],  
  4.                       [NSNumber numberWithInteger:UIViewAnimationOptionTransitionCurlDown],  
  5.                       [NSNumber numberWithInteger:UIViewAnimationOptionTransitionCrossDissolve],  
  6.                       [NSNumber numberWithInteger:UIViewAnimationOptionTransitionFlipFromTop],  
  7.                       [NSNumber numberWithInteger:UIViewAnimationCurveEaseIn],  
  8.                       [NSNumber numberWithInteger:UIViewAnimationCurveEaseOut],  
  9.                       [NSNumber numberWithInteger:UIViewAnimationCurveLinear],  
  10.                       [NSNumber numberWithInteger:UIViewAnimationOptionAllowAnimatedContent],  
  11.                       [NSNumber numberWithInteger:UIViewAnimationOptionOverrideInheritedCurve],  
  12.                       [NSNumber numberWithInteger:UIViewAnimationOptionTransitionFlipFromTop],  
  13.                       [NSNumber numberWithInteger:UIViewAnimationOptionTransitionFlipFromBottom]];  

然后切换图片的时候, 实现如下代码即可。  (具体参见PhotoStackView)

[objc] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. -(void)reloadData {  
  2.       
  3.     if (!self.dataSource) {  
  4.         //exit if data source has not been set up yet  
  5.         self.photoViews = nil;  
  6.         return;  
  7.     }  
  8.       
  9.     NSInteger numberOfPhotos = [self.dataSource numberOfPhotosInPhotoStackView:self];  
  10.     NSInteger topPhotoIndex  = [self indexOfTopPhoto]; // Keeping track of current photo’s top index so that it remains on top if new photos are added  
  11.       
  12.     if(numberOfPhotos > 0) {  
  13.   
  14.         NSMutableArray *photoViewsMutable   = [[NSMutableArray alloc] initWithCapacity:numberOfPhotos];  
  15.         UIImage *borderImage                = [self.borderImage resizableImageWithCapInsets:UIEdgeInsetsMake(self.borderWidthself.borderWidthself.borderWidthself.borderWidth)];  
  16.           
  17.         for (NSUInteger index = 0; index < numberOfPhotos; index++) {  
  18.   
  19.             UIImage *image = [self.dataSource photoStackView:self photoForIndex:index];  
  20.             CGSize imageSize = image.size;  
  21.             if([self.dataSource respondsToSelector:@selector(photoStackView:photoSizeForIndex:)]){  
  22.                 imageSize = [self.dataSource photoStackView:self photoSizeForIndex:index];  
  23.             }  
  24.             UIImageView *photoImageView     = [[UIImageView alloc] initWithFrame:(CGRect){CGPointZero, imageSize}];  
  25.             photoImageView.image            = image;  
  26.             UIView *view                    = [[UIView alloc] initWithFrame:photoImageView.frame];  
  27.             view.layer.rasterizationScale   = [[UIScreen mainScreen] scale];              
  28.             view.layer.shouldRasterize      = YES// rasterize the view for faster drawing and smooth edges  
  29.   
  30.             if (self.showBorder) {  
  31.                   
  32.                 // Add the background image  
  33.                 if (borderImage) {  
  34.                     // If there is a border image, we need to add a background image view, and add some padding around the photo for the border  
  35.   
  36.                     CGRect photoFrame                = photoImageView.frame;  
  37.                     photoFrame.origin                = CGPointMake(self.borderWidthself.borderWidth);  
  38.                     photoImageView.frame             = photoFrame;  
  39.   
  40.                     view.frame                       = CGRectMake(00, photoImageView.frame.size.width+(self.borderWidth*2), photoImageView.frame.size.height+(self.borderWidth*2));  
  41.                     UIImageView *backgroundImageView = [[UIImageView alloc] initWithFrame:view.frame];  
  42.                     backgroundImageView.image        = borderImage;  
  43.                       
  44.                     [view addSubview:backgroundImageView];  
  45.                 } else {  
  46.                     // if there is no boarder image draw one with the CALayer  
  47.                     view.layer.borderWidth        = self.borderWidth;  
  48.                     view.layer.borderColor        = [[UIColor whiteColor] CGColor];  
  49.                     view.layer.shadowOffset       = CGSizeMake(00);  
  50.                     view.layer.shadowOpacity      = 0.5;  
  51.                 }  
  52.             }  
  53.   
  54.             [view addSubview:photoImageView];  
  55.   
  56.             view.tag    = index;  
  57.             view.center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));  
  58.   
  59.             [photoViewsMutable addObject:view];  
  60.               
  61.         }  
  62.   
  63.         // Photo views are added to subview in the photoView setter  
  64.         self.photoViews = photoViewsMutable; photoViewsMutable = nil;  
  65.         [self goToPhotoAtIndex:topPhotoIndex];  
  66.           
  67.     }  
  68.       
  69. }  



七。自定义后台显示图片

这个功能就是演示效果里面, 当应用切换到后台后, 我们双击home键后显示后台程序时候, 该应用的显示效果。

比如..  有时候我们浏览的图片尺度比较大.. 然后切到后台的时候, 就希望把它隐藏起来..  

这就涉及到了Background Fetch的应用。
之前也写过一篇博客专门介绍。 这里就不重复了。




好了。 到这里终于是介绍的差不多了。
当然。 我这里的解析都比较概括, 列举的都是几个关键代码段。
更加详细的还是需要自己去看代码。 注释也写了, 估计没什么问题。 如果有问题, 欢迎联系我。

一口气写了3个小时的博客…  累的够呛的。也希望, 能对你有所帮助。

本文正在参加博客大赛。 如果觉得对你有所帮助, 还望帮忙投下票。 多谢。 

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/194018.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 操作系统银行家算法C语言代码实现「建议收藏」

    操作系统银行家算法C语言代码实现「建议收藏」计算机操作系统课设需要,写了两个下午的银行家算法(陷在bug里出不来耽误了很多时间),参考计算机操作系统(汤子瀛)实现过程中不涉及难度较大的算法,仅根据银行家算法的思想和步骤进行实现。以下为详细步骤

  • springboot排除exclude

    springboot排除exclude

  • Java中的POJO是什么?[通俗易懂]

    Java中的POJO是什么?[通俗易懂]1.介绍在这个简短的教程中,我们将研究“普通Java对象”(PlainOldJavaObject)的定义,简称POJO。我们将看看POJO与JavaBean的比较,以及如何将POJO转换为JavaBean。2.普通java对象2.1何为普通java对象?当我们谈论POJO时,我们所描述的是一个简单的类型,没有任何特定框架的引用。POJO对我们的属性和方法没有命名约定。让我们创建一个基本的员工POJO。它将有三个属性;名字、姓氏和入职日期:publicclassEmployeePojo

  • murmurhash算法_hash function

    murmurhash算法_hash functionunsignedlonglongMurmurHash64B(constvoid*key,intlen,unsignedintseed){ constunsignedintm=0x5bd1e995; constintr=24; unsignedinth1=seed^len; unsignedinth2=0; con

  • 什么是CMS_SiteServer CMS

    什么是CMS_SiteServer CMS纵观现如今国内CMS程序,大有百花争艳的感觉,随着企业建站需求的复杂度和功能的不断扩展,传统的三五个人写一段代码即告网站建已经行不通,于是以内容管理为应用核心的CMS产品大行其道。  这些CMS系统大体上基于两套框架编写:PHP+MySQL和.NET+MSSQL。在PHP中比较有名的就有DeDeCMS、PHP168、帝国CMS、Supesite等,在.NET方面就有zoomla!…

  • linux中用户态和内核态是什么_用户态内核

    linux中用户态和内核态是什么_用户态内核内核态:操作系统在内核态运行——运行操作系统程序用户态:应用程序只能在用户态运行——运行用户程序当一个进程在执行用户自己的代码时处于用户运行态(用户态),此时特权级最低,为3级,是普通的用户进程运行的特权级,大部分用户直接面对的程序都是运行在用户态。Ring3状态不能访问Ring0的地址空间,包括代码和数据;当一个进程因为系统调用陷入内核代码中执行时处于内核运行态(内核态),此时特权级最高,为0级。执行的内核代码会使用当前进程的内核栈,每个进程都有自己的内核栈。…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号