PINRemoteImage
快速、非死锁并行图像下载器和缓存库,适用于 iOS
PINRemoteImageManager 是一个图像下载、处理和缓存管理器。它使用下载和处理任务的概念来确保即使对下载或处理图像的多次调用,也只发生一次(除非项不再在缓存中)。PINRemoteImageManager 由 GCD 支持,并可在多个线程中安全地 访问。它确保图像在主线程之外解码,从而不影响动画性能。其公开的方法都不允许进行同步访问。但是,如果项目在其内存缓存中,它被优化为在调用线程上调用自己的回调。
PINRemoteImage 支持下载许多类型的文件。它当然 支持 无论是 PNGs 还是 JPGs。它还支持在 Google 库可用的情况下解码 WebP 图像。它甚至通过 PINAnimatedImageView 支持 GIFs 和 动态 WebP。
PINRemoteImage 还有两个方法来提高在慢速网络连接上下载图像的体验。第一个是对 渐进式 JPGs 的支持。这不是对渐进式 JPGs 的旧支持:PINRemoteImage 在返回之前将对渐进式扫描添加一个吸引力的模糊效果。
PINRemoteImageCategoryManager 定义了一个协议,UIView子类可以实现并提供对 PINRemoteImageManager 方法的轻松访问。在 UIImageView、PINAnimatedImageView 和 UIButton 上有 内置的分类,实现一个新分类很容易。请参考现有的分类 [UIImageView+PINRemoteImage]。
下载图片并将其设置在视图上
Objective-C
UIImageView *imageView = [[UIImageView alloc] init];
[imageView pin_setImageFromURL:[NSURL URLWithString:@"http://pinterest.com/kitten.jpg"]];
Swift
let imageView = UIImageView()
imageView.pin_setImage(from: URL(string: "https://pinterest.com/kitten.jpg")!)
下载渐进式 JPEG 并获得漂亮的模糊更新
Objective-C
UIImageView *imageView = [[UIImageView alloc] init];
[imageView setPin_updateWithProgress:YES];
[imageView pin_setImageFromURL:[NSURL URLWithString:@"http://pinterest.com/progressiveKitten.jpg"]];
Swift
let imageView = UIImageView()
imageView.pin_updateWithProgress = true
imageView.pin_setImage(from: URL(string: "https://pinterest.com/progressiveKitten.jpg")!)
下载 WebP 文件
Objective-C
UIImageView *imageView = [[UIImageView alloc] init];
[imageView pin_setImageFromURL:[NSURL URLWithString:@"http://pinterest.com/googleKitten.webp"]];
Swift
let imageView = UIImageView()
imageView.pin_setImage(from: URL(string: "https://pinterest.com/googleKitten.webp")!)
下载 GIF 并使用 PINAnimatedImageView 显示
Objective-C
PINAnimatedImageView *animatedImageView = [[PINAnimatedImageView alloc] init];
[animatedImageView pin_setImageFromURL:[NSURL URLWithString:@"http://pinterest.com/flyingKitten.gif"]];
Swift
let animatedImageView = PINAnimatedImageView()
animatedImageView.pin_setImage(from: URL(string: "http://pinterest.com/flyingKitten.gif")!)
下载并处理图片
Objective-C
UIImageView *imageView = [[UIImageView alloc] init];
[self.imageView pin_setImageFromURL:[NSURL URLWithString:@"https://i.pinimg.com/736x/5b/c6/c5/5bc6c5387ff6f104fd642f2b375efba3.jpg"] processorKey:@"rounded" processor:^UIImage *(PINRemoteImageManagerResult *result, NSUInteger *cost)
{
CGSize targetSize = CGSizeMake(200, 300);
CGRect imageRect = CGRectMake(0, 0, targetSize.width, targetSize.height);
UIGraphicsBeginImageContext(imageRect.size);
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:imageRect cornerRadius:7.0];
[bezierPath addClip];
CGFloat sizeMultiplier = MAX(targetSize.width / result.image.size.width, targetSize.height / result.image.size.height);
CGRect drawRect = CGRectMake(0, 0, result.image.size.width * sizeMultiplier, result.image.size.height * sizeMultiplier);
if (CGRectGetMaxX(drawRect) > CGRectGetMaxX(imageRect)) {
drawRect.origin.x -= (CGRectGetMaxX(drawRect) - CGRectGetMaxX(imageRect)) / 2.0;
}
if (CGRectGetMaxY(drawRect) > CGRectGetMaxY(imageRect)) {
drawRect.origin.y -= (CGRectGetMaxY(drawRect) - CGRectGetMaxY(imageRect)) / 2.0;
}
[result.image drawInRect:drawRect];
UIImage *processedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return processedImage;
}];
Swift
let imageView = FLAnimatedImageView()
imageView.pin_setImage(from: URL(string: "https://i.pinimg.com/736x/5b/c6/c5/5bc6c5387ff6f104fd642f2b375efba3.jpg")!, processorKey: "rounded") { (result, unsafePointer) -> UIImage? in
guard let image = result.image else { return nil }
let radius : CGFloat = 7.0
let targetSize = CGSize(width: 200, height: 300)
let imageRect = CGRect(x: 0, y: 0, width: targetSize.width, height: targetSize.height)
UIGraphicsBeginImageContext(imageRect.size)
let bezierPath = UIBezierPath(roundedRect: imageRect, cornerRadius: radius)
bezierPath.addClip()
let widthMultiplier : CGFloat = targetSize.width / image.size.width
let heightMultiplier : CGFloat = targetSize.height / image.size.height
let sizeMultiplier = max(widthMultiplier, heightMultiplier)
var drawRect = CGRect(x: 0, y: 0, width: image.size.width * sizeMultiplier, height: image.size.height * sizeMultiplier)
if (drawRect.maxX > imageRect.maxX) {
drawRect.origin.x -= (drawRect.maxX - imageRect.maxX) / 2
}
if (drawRect.maxY > imageRect.maxY) {
drawRect.origin.y -= (drawRect.maxY - imageRect.maxY) / 2
}
image.draw(in: drawRect)
UIColor.red.setStroke()
bezierPath.lineWidth = 5.0
bezierPath.stroke()
let ctx = UIGraphicsGetCurrentContext()
ctx?.setBlendMode(CGBlendMode.overlay)
ctx?.setAlpha(0.5)
let logo = UIImage(named: "white-pinterest-logo")
ctx?.scaleBy(x: 1.0, y: -1.0)
ctx?.translateBy(x: 0.0, y: -drawRect.size.height)
if let coreGraphicsImage = logo?.cgImage {
ctx?.draw(coreGraphicsImage, in: CGRect(x: 90, y: 10, width: logo!.size.width, height: logo!.size.height))
}
let processedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return processedImage
}
处理认证
Objective-C
[[PINRemoteImageManager sharedImageManager] setAuthenticationChallenge:^(NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, PINRemoteImageManagerAuthenticationChallengeCompletionHandler aCompletion) {
aCompletion(NSURLSessionAuthChallengePerformDefaultHandling, nil)];
Swift
PINRemoteImageManager.shared().setAuthenticationChallenge { (task, challenge, completion) in
completion?(.performDefaultHandling, nil)
}
支持高分辨率图片
目前PINRemoteImage支持两种处理高分辨率图片的方式
- 如果URL包含
_2x.
或_3x.
后缀,将自动由PINRemoteImage处理,并以正确的比例返回结果图片。 - 如果无法提供包含
_2x.
或_3x.
后缀的URL,您也可以使用完成处理器来处理它
NSURL *url = ...;
__weak UIImageView *weakImageView = self.imageView;
[self.imageView pin_setImageFromURL:url completion:^(PINRemoteImageManagerResult * _Nonnull result) {
CGFloat scale = UIScreen.mainScreen.scale;
if (scale > 1.0) {
UIImage *image = result.image;
weakImageView.image = [UIImage imageWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation];
}
}];
设置一些限制
// cache is an instance of PINCache as long as you haven't overridden defaultImageCache
PINCache *cache = (PINCache *)[[PINRemoteImageManager sharedImageManager] cache];
// Max memory cost is based on number of pixels, we estimate the size of one hundred 600x600 images as our max memory image cache.
[[cache memoryCache] setCostLimit:600 * [[UIScreen mainScreen] scale] * 600 * [[UIScreen mainScreen] scale] * 100];
// ~50 MB
[[cache diskCache] setByteLimit:50 * 1024 * 1024];
// 30 days
[[cache diskCache] setAgeLimit:60 * 60 * 24 * 30];
安装
CocoaPods
将PINRemoteImage添加到您的Podfile
中,并运行pod install
。
如果您想使用WebP图片,请将PINRemoteImage/WebP添加到您的Podfile
中,并运行pod install
。
Carthage
将github "pinterest/PINRemoteImage"
添加到您的Cartfile中。有关如何将Carthage构建的框架集成到项目的更多信息,请参阅Carthage的readme。
手动
下载最新标签,并将Pod/Classes
文件夹拖放到您的Xcode项目中。您还必须手动链接到PINCache。
通过在docs/
目录下双击.docset
文件来安装文档,或在cocoadocs.org上在线查看。
Git子模块
您可以将PINRemoteImage作为子模块设置到您的仓库中,而不是克隆并将所有文件复制到您的仓库中。使用以下命令添加子模块,然后按照上述手动说明操作。
git submodule add https://github.com/pinterest/PINRemoteImage.git
git submodule update --init
要求
PINRemoteImage 需要 iOS 7.0 或更高版本。
联系
Garrett Moon @garrettmoon Pinterest
许可证
版权所有 2015 Pinterest, Inc.
根据Apache License, Version 2.0 ("许可证")许可;除非符合许可证规定或书面同意,否则不得使用此文件。您可以在 http://www.apache.org/licenses/LICENSE-2.0 获取许可证的副本。
除非适用法律要求或书面同意,在许可证下分发的软件按“现状”提供,不提供任何明示或暗示的保证或条件。有关许可证的特定语言和限制,请参见许可证。