Open churabou opened 6 years ago
import SnapKit
import Photos
class PhotoPickerView: UIViewController {
private lazy var layout: UICollectionViewFlowLayout = {
let l = UICollectionViewFlowLayout()
l.itemSize = CGSize(width: view.bounds.width / 3 - 4,
height: view.bounds.width / 3 - 4)
l.sectionInset = UIEdgeInsets(top: 8, left: 1, bottom: 0, right: 1)
l.minimumInteritemSpacing = 1
l.minimumLineSpacing = 1
return l
}()
private lazy var collectionView: UICollectionView = {
let v = UICollectionView(frame: view.frame, collectionViewLayout: layout)
v.setAutoLayout()
v.dataSource = self
v.delegate = self
v.register(CameraRollCollectionViewCell.self, forCellWithReuseIdentifier: "cell")
return v
}()
fileprivate var photoAssets: [PHAsset] = []
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(collectionView)
collectionView.snp.makeConstraints { (make) in
make.edges.equalToSuperview()
}
libraryRequestAuthorization()
}
// カメラロールへのアクセス許可
fileprivate func libraryRequestAuthorization() {
PHPhotoLibrary.requestAuthorization({ [weak self] status in
guard let wself = self else {
return
}
switch status {
case .authorized:
wself.getAllPhotosInfo()
case .denied:
wself.showDeniedAlert()
case .notDetermined:
print("NotDetermined")
case .restricted:
print("Restricted")
}
})
}
// カメラロールから全て取得する
fileprivate func getAllPhotosInfo() {
let assets: PHFetchResult = PHAsset.fetchAssets(with: .image, options: nil)
assets.enumerateObjects({ [weak self] (asset, index, stop) -> Void in
guard let wself = self else {
return
}
DispatchQueue.global(qos: .default).async {
wself.photoAssets.append(asset as PHAsset)
print("global \(Date())")
}
})
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
// カメラロールへのアクセスが拒否されている場合のアラート
fileprivate func showDeniedAlert() {
let alert = UIAlertController(title: "エラー",
message: "「写真」へのアクセスが拒否されています。設定より変更してください。",
preferredStyle: .alert)
let cancel = UIAlertAction(title: "キャンセル",
style: .cancel,
handler: nil)
let ok = UIAlertAction(title: "設定画面へ",
style: .default,
handler: { [weak self] (action) -> Void in
guard let wself = self else {
return
}
wself.transitionToSettingsApplition()
})
alert.addAction(cancel)
alert.addAction(ok)
present(alert, animated: true, completion: nil)
}
fileprivate func transitionToSettingsApplition() {
if let url = URL(string: UIApplicationOpenSettingsURLString) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
}
extension PhotoPickerView : UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return photoAssets.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CameraRollCollectionViewCell
cell.configure(asset: photoAssets[indexPath.row])
return cell
}
}
extension PhotoPickerView: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let asset = photoAssets[indexPath.row]
asset.getOriginalImage(handler: { [weak self] (image, info) in
let img = self?.resizeMaxSize1920(image!)
let n = PhotoEditorViewController(image: img!)
print(image!.size)
print(img?.size)
DispatchQueue.main.async {
self?.present(n, animated: true, completion: nil)
}
})
}
func resizeMaxSize1920(_ image: UIImage) -> UIImage {
var ratio: CGFloat = 0
let maxS: CGFloat = 1920
if image.size.width > image.size.height {
if image.size.width >= maxS {
ratio = maxS / image.size.width
} else {
return image
}
} else {
if image.size.height >= maxS {
ratio = maxS / image.size.height
} else {
return image
}
}
let resize = image.size.multiple(by: ratio)
UIGraphicsBeginImageContextWithOptions(resize, false, image.scale)
image.draw(in: CGRect(origin: .zero, size: resize))
let resized = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return resized!
}
}
class CameraRollCollectionViewCell: BaseCollectionViewCell {
let imageView = UIImageView()
override func initializeView() {
imageView.setAutoLayout()
imageView.backgroundColor = .red
contentView.addSubview(imageView)
}
override func initializeConstraints() {
imageView.snp.makeConstraints { (make) in
make.edges.equalToSuperview()
}
}
// 画像を表示する
func configure(asset: PHAsset) {
asset.getThumbNail(handler: { [weak self] (image, info) in
self?.imageView.image = image
})
}
}
extension PHAsset {
func getThumbNail(handler: @escaping (UIImage?, [AnyHashable : Any]?) -> Swift.Void) {
let options = PHImageRequestOptions()
options.deliveryMode = .highQualityFormat
options.resizeMode = .exact
options.isNetworkAccessAllowed = true
options.isSynchronous = false
let scale = UIScreen.main.scale
let width: CGFloat = 100
let size = CGSize(width: width*scale, height: width*scale)
PHImageManager
.default()
.requestImage(for: self,
targetSize: size,
contentMode: .aspectFill,
options: options,
resultHandler: handler)
}
func getOriginalImage(handler: @escaping (UIImage?, [AnyHashable : Any]?) -> Swift.Void) {
let options = PHImageRequestOptions()
options.deliveryMode = .highQualityFormat
options.resizeMode = .exact
options.isNetworkAccessAllowed = true
options.isSynchronous = false
let scale: CGFloat = 1 //UIScreen.main.scale
let size = CGSize(width: CGFloat(pixelWidth)*scale,
height: CGFloat(pixelHeight)*scale)
PHImageManager
.default()
.requestImage(for: self,
targetSize: size,
contentMode: .aspectFill,
options: options,
resultHandler: handler)
}
}
カメラロールを取得して表示したやつ。 reloadDataがmainスレッド以外で呼ばれていたらしい。 GCDについて学ぶ
image.draw in resizeする image.draw at
CIGaussianGradient CIMaskedVariableBlur