Swift - 使用PhotoKit获取照片1(获取所有照片缩略图、原图及其信息)
来源:互联网 发布:深圳谷歌优化 编辑:程序博客网 时间:2024/04/29 04:17
我之前写过一篇文章:Swift - 使用ALAssetsLibrary获取相簿里所有图片,视频(附样例)。介绍了如何使用 AssetsLibrary 框架来读取并显示系统中的所有照片。
几年以来,相机应用和照片应用发生了显著的变化,增加了许多新特性,包括按时刻来组织照片的方式。但与此同时,AssetsLibrary 框架却没有跟上步伐。所以到了iOS 9后,AssetsLibrary 框架要被彻底废除。作为替代,苹果自 iOS 8 起提供了一个更现代化的框架 PhotoKit。本文将使用 PhotoKit 来实现同之前文章一样的功能:读取并显示设备中的所有照片。
1,Photos框架的特点
淡化了照片库中 URL 的概念,改之使用一个标志符来唯一代表一个资源。同时这个标志符还是动态变化的,也就是说即使同一个资源,每次启动应用后获取的标志符和上一次都是不一样的。
2,获取原图
通过 PHImageManager.defaultManager().requestImageDataForAsset() 这个方法可以获取图片的缩略图或者原图。如果要获取原图,即不对照片大小进行修改或裁剪,那么方法里参数要进行如下设置:
targetSize 设成 PHImageManagerMaximumSize
contentMode 设成 .Default (其实 targetSize 如果是 PHImageManagerMaximumSize 的话,contentMode 不管设置成什么都会视作 .Default )
(1)与 AssetsLibrary 相比,PhotoKit 没有直接的提供缩略图方法。我们需要指定需要获取的缩略图尺寸,系统会按照你的要求来返回接近该尺寸的图像(会提供刚好大于或等于该尺寸的缩略图,没有的话则返回原图)。
(2)前面提到,PHImageManager.defaultManager().requestImageDataForAsset() 既可以用来获取原图,也可以用来获取缩略图。这里我们使用 PHCachingImageManager,它是 PHImageManager 的子类,所以获取图片的方法是一样的。但这个可以用于缓存 PHAsset,这样可以快速获取照片或视频。在 UICollectionViewController 中使用比较适合。
4,样例说明
(1)启动程序后会获取相机胶卷中所有图片的缩略图,并在 UICollectionViewController 中显示出来。
(2)图片按照创建时间倒序排列(最近拍的照片在最上面)。
(3)点击缩略图,可以查看照片的原图以及图片的相关信息。
(2)图片按照创建时间倒序排列(最近拍的照片在最上面)。
(3)点击缩略图,可以查看照片的原图以及图片的相关信息。
5,效果图如下
--- 首页 CollectionViewController.swift ---
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import
UIKit
import
Photos
class
CollectionViewController
:
UICollectionViewController
{
///取得的资源结果,用了存放的PHAsset
var
assetsFetchResults:
PHFetchResult
!
///缩略图大小
var
assetGridThumbnailSize:
CGSize
!
/// 带缓存的图片管理对象
var
imageManager:
PHCachingImageManager
!
override
func
viewWillAppear(animated:
Bool
) {
super
.viewWillAppear(animated)
//根据单元格的尺寸计算我们需要的缩略图大小
let
scale =
UIScreen
.mainScreen().scale
let
cellSize = (
self
.collectionViewLayout
as
!
UICollectionViewFlowLayout
).itemSize
assetGridThumbnailSize =
CGSizeMake
( cellSize.width*scale , cellSize.height*scale)
}
override
func
viewDidLoad() {
super
.viewDidLoad()
//则获取所有资源
let
allPhotosOptions =
PHFetchOptions
()
//按照创建时间倒序排列
allPhotosOptions.sortDescriptors = [
NSSortDescriptor
(key:
"creationDate"
,
ascending:
false
)]
//只获取图片
allPhotosOptions.predicate =
NSPredicate
(format:
"mediaType = %d"
,
PHAssetMediaType
.
Image
.rawValue)
assetsFetchResults =
PHAsset
.fetchAssetsWithMediaType(
PHAssetMediaType
.
Image
,
options: allPhotosOptions)
// 初始化和重置缓存
self
.imageManager =
PHCachingImageManager
()
self
.resetCachedAssets()
}
//重置缓存
func
resetCachedAssets(){
self
.imageManager.stopCachingImagesForAllAssets()
}
// CollectionView行数
override
func
collectionView(collectionView:
UICollectionView
,
numberOfItemsInSection section:
Int
) ->
Int
{
return
self
.assetsFetchResults.count
}
// 获取单元格
override
func
collectionView(collectionView:
UICollectionView
,
cellForItemAtIndexPath indexPath:
NSIndexPath
)
->
UICollectionViewCell
{
// storyboard里设计的单元格
let
identify:
String
=
"DesignViewCell"
// 获取设计的单元格,不需要再动态添加界面元素
let
cell = (
self
.collectionView?.dequeueReusableCellWithReuseIdentifier(
identify, forIndexPath: indexPath))!
as
UICollectionViewCell
let
asset =
self
.assetsFetchResults[indexPath.row]
as
!
PHAsset
//获取缩略图
self
.imageManager.requestImageForAsset(asset, targetSize: assetGridThumbnailSize,
contentMode:
PHImageContentMode
.
AspectFill
,
options:
nil
) { (image, nfo)
in
(cell.contentView.viewWithTag(1)
as
!
UIImageView
).image = image
print
(image)
}
return
cell
}
// 单元格点击响应
override
func
collectionView(collectionView:
UICollectionView
,
didSelectItemAtIndexPath indexPath:
NSIndexPath
) {
let
myAsset =
self
.assetsFetchResults[indexPath.row]
as
!
PHAsset
//这里不使用segue跳转(建议用segue跳转)
let
detailViewController =
UIStoryboard
(name:
"Main"
, bundle:
nil
)
.instantiateViewControllerWithIdentifier(
"detail"
)
as
!
ImageDetailViewController
detailViewController.myAsset = myAsset
// navigationController跳转到detailViewController
self
.navigationController!.pushViewController(detailViewController,
animated:
true
)
}
override
func
didReceiveMemoryWarning() {
super
.didReceiveMemoryWarning()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import
UIKit
import
Photos
class
ImageDetailViewController
:
UIViewController
{
//选中的图片资源
var
myAsset:
PHAsset
!
//用于显示图片信息
@IBOutlet
weak
var
textView:
UITextView
!
//用于显示原图
@IBOutlet
weak
var
imageView:
UIImageView
!
override
func
viewDidLoad() {
super
.viewDidLoad()
//获取文件名
PHImageManager
.defaultManager().requestImageDataForAsset(myAsset, options:
nil
,
resultHandler: {
_, _, _, info
in
self
.title = (info![
"PHImageFileURLKey"
]
as
!
NSURL
).lastPathComponent
})
//获取图片信息
textView.text =
"日期:\(myAsset.creationDate!)\n"
+
"类型:\(myAsset.mediaType.rawValue)\n"
+
"位置:\(myAsset.location)\n"
+
"时长:\(myAsset.duration)\n"
//获取原图
PHImageManager
.defaultManager().requestImageForAsset(myAsset,
targetSize:
PHImageManagerMaximumSize
, contentMode: .
Default
,
options:
nil
, resultHandler: {
(image, _: [
NSObject
:
AnyObject
]?)
in
self
.imageView.image = image
})
}
override
func
didReceiveMemoryWarning() {
super
.didReceiveMemoryWarning()
}
}
7,图像的裁剪与传输策略
上面样例运行后会发现虽然相册中的图片只有7张,但 collectionView 页面却加载了14次:
这是由于图像管理器的优化策略,即它在将图像的高质量版本递送给你之前,先传递一个较低质量的版本过来。这样就会让页面UI更加顺畅。
当然这些策略也是可以通过 requestImageForAsset() 方法中的 options 参数进行设置的(类型是 PHImageRequestOptions。本文样例都是传的都是 nil,即使用默认设置。)
8,PHImageRequestOptions对象常用属性说明
(1)resizeMode 属性
可以设置为 .Exact (返回图像必须和目标大小相匹配),.Fast (比 .Exact 效率更高,但返回图像可能和目标大小不一样,接近且稍大与目标大小) 或者 .None(默认值)。
可以设置为 .Exact (返回图像必须和目标大小相匹配),.Fast (比 .Exact 效率更高,但返回图像可能和目标大小不一样,接近且稍大与目标大小) 或者 .None(默认值)。
比如:我们如果将其设置成 .Exact,那么输出结果如下:
(2)deliveryMode 属性
前面提到的在得到高质量的图片之前,会先传输个低质量的策略就是由这个属性设置。一共有三种方式:
.Opportunistic(默认值)
.FastFormat(如果你想要更快的加载速度,且可以牺牲一点图像质量,可以设成这个。)
.HighQualityFormat(如果你只想要高质量的图像,并且可以接受更长的加载时间,那么就设成这个。)
比如我们将 deliveryMode 设置 .HighQualityFormat,那么可以看到图片只加载了7次,之前不会再先获得低质量的图片了。
前面提到的在得到高质量的图片之前,会先传输个低质量的策略就是由这个属性设置。一共有三种方式:
.Opportunistic(默认值)
.FastFormat(如果你想要更快的加载速度,且可以牺牲一点图像质量,可以设成这个。)
.HighQualityFormat(如果你只想要高质量的图像,并且可以接受更长的加载时间,那么就设成这个。)
比如我们将 deliveryMode 设置 .HighQualityFormat,那么可以看到图片只加载了7次,之前不会再先获得低质量的图片了。
默认是 false,表示 requestImageForAsset() 方法是异步操作。如果设置成 true,这个就变成同步的了。
注意:当 synchronous 设为 true 时,deliveryMode 属性就会被忽略,并被当作 .HighQualityFormat 来处理。
9,源码下载:hangge_1233.zip
原文出自:www.hangge.com 转载请保留原文链接:http://www.hangge.com/blog/cache/detail_1233.html
0 0
- Swift - 使用PhotoKit获取照片1(获取所有照片缩略图、原图及其信息)
- Swift - 使用PhotoKit获取照片2(列出所有相簿、并选择)
- Android使用摄像头,分别获取照片的缩略图与原图
- 获取某一个相册中所有照片和照片的缩略图
- iOS获取所有照片
- ios PhotoKit遍历所有照片
- 获取照片Exif信息
- 获取照片库中所有照片
- Java获取照片EXIF信息
- 获取照片的Exif信息
- 获取照片的属性信息
- 获取照片的属性信息
- 照片头信息的获取
- Java获取照片EXIF信息
- Java获取照片EXIF信息
- iOS获取照片EXif信息
- Java获取照片EXIF信息
- Java获取照片EXIF信息
- 【Linux】初识Linux操作系统
- 使用通知 Notification
- spring中jdbcTemplate的应用 二
- 如何将Win7做为NTP服务器
- 全手写struts用户登录系统
- Swift - 使用PhotoKit获取照片1(获取所有照片缩略图、原图及其信息)
- 从用户体验的角度说明产品的五个层次
- CSS选择器速查
- es
- Retrofit2 本地模拟API数据
- Swift - 使用PhotoKit获取照片2(列出所有相簿、并选择)
- 【JZOJ4788】序列
- docker+python无头浏览器爬虫
- 22 接电话状态广播