[iOS]浅谈图片加载<结合SDWebImageManag

2016-09-28  本文已影响859人  noikin

前言--这次我要探讨的问题是一个不那么引人注意的地方,我认为细节决定成败,因此今天拿出来探讨一下。针对于iOS的图片加载---就拿最近比较火的电影《浮山行》做栗子了。

Image.png

上图为使用SDWebImageManager加载网络图片的状态,可以轻易地看到图片是有拉伸的。我们对UIImageView的填充模式进行设置,图片也会多多少少看起来不那么顺眼。

通常会出现以下情况

原因:对UIImageView有固定的大小,加载的图片活动范围也就只有设置的那么大

如果我们把UIImageView的填充模式改变了,图片不会拉伸但是两边会有空白,显然,这对排版来说,看起来会很杂乱。
我们希望看到的不是一个有拉伸的图片,并且加载的网络图片要将UIImageView填充完全。

个人会采用等比剪切的方式进行加载

Image.png

像以上图片这样,虽然图片看起来没有显示完全,但是它属于图片正中间,我们能够看到图片的主要内容,并且看起来不会特别乱。

首先会用到以下代码,用于对图片的裁剪

+(UIImage *)cutImage:(UIImage *)image imageView:(UIImageView *)imageView
{    //裁剪压缩图片   
   CGSize newSize; 
   CGImageRef imageRef = nil;  
     if ((image.size.width / image.size.height) < (imageView.frame.size.width / imageView.frame.size.height)) {   
     newSize.width = image.size.width;   
     newSize.height = image.size.width * imageView.frame.size.height / imageView.frame.size.width;                
    imageRef = CGImageCreateWithImageInRect([image CGImage], CGRectMake(0, fabs(image.size.height - newSize.height) / 2, newSize.width, newSize.height));      
     } else {   
     newSize.height = image.size.height;   
     newSize.width = image.size.height * imageView.frame.size.width / imageView.frame.size.height;               
     imageRef = CGImageCreateWithImageInRect([image CGImage], CGRectMake(fabs(image.size.width - newSize.width) / 2, 0, newSize.width, newSize.height));   
        }     
  return [UIImage imageWithCGImage:imageRef];
}

接下来,当我们使用网络加载图片的时候就会用到SDWebImageManager。这是一个强大的三方,里面包含了大多数对图片的处理。如果,您对SDWebImageManager只有简单的了解,仅仅用于加载图片,但是对图片填充有细节的要求,我想这篇文章可能对你会有些许的帮助。
我将结合SDWebImageManager三方来谈谈图片填充。上面,讲到要对图片进行裁剪,因此在我们需要加载图片的时候我们会用到上面的裁剪方式。

我将裁剪方法写在一个类里面,然后结合SDWebImageManager也将加载图片的方法写在类里面。

+(void)addImageWith:(NSString *)imageName andImageView:(UIImageView *)imageView{  
         BOOL isExit = [[SDWebImageManager sharedManager] cachedImageExistsForURL:[NSURL URLWithString:imageName]];   
 if (isExit) {     
 //  NSLog(@"有");      
  UIImage *cachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:imageName];      
  imageView.image = cachedImage; 
   }else{  
     dispatch_queue_t ab = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);   
     dispatch_queue_t main = dispatch_get_main_queue();        
dispatch_async(ab, ^{                 
      [NSThread sleepForTimeInterval:2];            
   dispatch_async(main, ^{        
          NSURL *urlBack = [NSURL URLWithString:imageName];      
          UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:urlBack]];           
          image = [Cut cutImage:image imageView:imageView];                
          imageView.image = image;      
          //缓存图片     
           [[SDImageCache sharedImageCache] storeImage:image forKey:imageName];           
                    [[SDWebImageManager sharedManager] downloadImageWithURL:urlBack options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {           
         NSLog(@"下载完成");           
     } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {                   
                }];         
   });        
           });      
     }   }

上面的代码结合了许多,其中有关线程的暂且不谈,之后会单独谈谈我对线程的理解。

//判断是否有缓存过
BOOL isExit = [[SDWebImageManager sharedManager] cachedImageExistsForURL:[NSURL URLWithString:imageName]];

这里的方法,调用的就是SDWebImageManager里面封装的一个方法,他可以检测是否图片缓存过

//如果缓存里有,我们直接调用Cache里的图片,以便节省下次网络请求加载图片
UIImage *cachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:imageName]; imageView.image = cachedImage;

这样的方法也是SDWebImageManager里面的。

如果缓存里面没有,那么就在线程里面重新加载网络图片,下载完毕后就将图片缓存起来。也就是else里面的语句。

总结

1.加载图片很简单,先裁剪
2.再检查是否缓存
3.有缓存,直接调用;没有缓存,先下载,再缓存

最后,SDWebImageManager里面有很多网络加载的方法,里面囊括了许多iOS的知识,可以抽时间仔细研究一下,说不定自己以后也能写加载图片的方法。以上是我通过学习SDWebImageManager,结合自己的理解和需求写的加载图片的方法,虽有小问题,但是对于初学者来说,或许会有些感悟。我的方法结合了SDWebImageManager,所以或许会有些小问题,如果你不嫌弃可一起来探讨,或者指出错误。

上一篇下一篇

猜你喜欢

热点阅读