AVFoundationで写真を撮るアプリを作成していますが、カスタムアルバムに保存して、クエリを実行してアプリで表示できます。 (ユーザーがそれを望まない限り、一般的な写真ロールにそれらを入れたくない)私はSwiftでこれを行う方法を示すものを本当に見つけることができません...またはまったくありません。これを行うことになっている別の方法はありますか?
SOでこの例を見つけましたが、私には意味がなく、動作させることができません。
func savePhoto() {
var albumFound : Bool = false
var assetCollection: PHAssetCollection!
var photosAsset: PHFetchResult!
var assetThumbnailSize:CGSize!
// Create the album if does not exist (in viewDidLoad)
if let first_Obj:AnyObject = collection.firstObject{
//found the album
self.albumFound = true
self.assetCollection = collection.firstObject as PHAssetCollection
}else{
//Album placeholder for the asset collection, used to reference collection in completion handler
var albumPlaceholder:PHObjectPlaceholder!
//create the folder
NSLog("\nFolder \"%@\" does not exist\nCreating now...", albumName)
PHPhotoLibrary.sharedPhotoLibrary().performChanges({
let request = PHAssetCollectionChangeRequest.creationRequestForAssetCollectionWithTitle(albumName)
albumPlaceholder = request.placeholderForCreatedAssetCollection
},
completionHandler: {(success:Bool, error:NSError!)in
NSLog("Creation of folder -> %@", (success ? "Success":"Error!"))
self.albumFound = (success ? true:false)
if(success){
let collection = PHAssetCollection.fetchAssetCollectionsWithLocalIdentifiers([albumPlaceholder.localIdentifier], options: nil)
self.assetCollection = collection?.firstObject as PHAssetCollection
}
})
}
let bundle = NSBundle.mainBundle()
let myFilePath = bundle.pathForResource("highlight1", ofType: "mov")
let videoURL:NSURL = NSURL.fileURLWithPath(myFilePath!)!
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0), {
PHPhotoLibrary.sharedPhotoLibrary().performChanges({
//let createAssetRequest = PHAssetChangeRequest.creationRequestForAssetFromImage
let createAssetRequest = PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(videoURL)
let assetPlaceholder = createAssetRequest.placeholderForCreatedAsset
let albumChangeRequest = PHAssetCollectionChangeRequest(forAssetCollection: self.assetCollection, assets: self.photosAsset)
albumChangeRequest.addAssets([assetPlaceholder])
}, completionHandler: {(success, error)in
dispatch_async(dispatch_get_main_queue(), {
NSLog("Adding Image to Library -> %@", (success ? "Sucess":"Error!"))
//picker.dismissViewControllerAnimated(true, completion: nil)
})
})
})
}
どんな助け/説明も素晴らしいでしょう!
これは私がする方法です:
頂点で:
import Photos
var image: UIImage!
var assetCollection: PHAssetCollection!
var albumFound : Bool = false
var photosAsset: PHFetchResult!
var assetThumbnailSize:CGSize!
var collection: PHAssetCollection!
var assetCollectionPlaceholder: PHObjectPlaceholder!
アルバムの作成:
func createAlbum() {
//Get PHFetch Options
let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: "title = %@", "camcam")
let collection : PHFetchResult = PHAssetCollection.fetchAssetCollectionsWithType(.Album, subtype: .Any, options: fetchOptions)
//Check return value - If found, then get the first album out
if let _: AnyObject = collection.firstObject {
self.albumFound = true
assetCollection = collection.firstObject as! PHAssetCollection
} else {
//If not found - Then create a new album
PHPhotoLibrary.sharedPhotoLibrary().performChanges({
let createAlbumRequest : PHAssetCollectionChangeRequest = PHAssetCollectionChangeRequest.creationRequestForAssetCollectionWithTitle("camcam")
self.assetCollectionPlaceholder = createAlbumRequest.placeholderForCreatedAssetCollection
}, completionHandler: { success, error in
self.albumFound = success
if (success) {
let collectionFetchResult = PHAssetCollection.fetchAssetCollectionsWithLocalIdentifiers([self.assetCollectionPlaceholder.localIdentifier], options: nil)
print(collectionFetchResult)
self.assetCollection = collectionFetchResult.firstObject as! PHAssetCollection
}
})
}
}
写真を保存するとき:
func saveImage(){
PHPhotoLibrary.sharedPhotoLibrary().performChanges({
let assetRequest = PHAssetChangeRequest.creationRequestForAssetFromImage(self.image)
let assetPlaceholder = assetRequest.placeholderForCreatedAsset
let albumChangeRequest = PHAssetCollectionChangeRequest(forAssetCollection: self.assetCollection, assets: self.photosAsset)
albumChangeRequest!.addAssets([assetPlaceholder!])
}, completionHandler: { success, error in
print("added image to album")
print(error)
self.showImages()
})
}
そのアルバムの画像を表示する:
func showImages() {
//This will fetch all the assets in the collection
let assets : PHFetchResult = PHAsset.fetchAssetsInAssetCollection(assetCollection, options: nil)
print(assets)
let imageManager = PHCachingImageManager()
//Enumerating objects to get a chached image - This is to save loading time
assets.enumerateObjectsUsingBlock{(object: AnyObject!,
count: Int,
stop: UnsafeMutablePointer<ObjCBool>) in
if object is PHAsset {
let asset = object as! PHAsset
print(asset)
let imageSize = CGSize(width: asset.pixelWidth, height: asset.pixelHeight)
let options = PHImageRequestOptions()
options.deliveryMode = .FastFormat
imageManager.requestImageForAsset(asset, targetSize: imageSize, contentMode: .AspectFill, options: options, resultHandler: {(image: UIImage?,
info: [NSObject : AnyObject]?) in
print(info)
print(image)
})
}
}
Objective-Cで回答し、少し整理しました。
__block PHFetchResult *photosAsset;
__block PHAssetCollection *collection;
__block PHObjectPlaceholder *placeholder;
// Find the album
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.predicate = [NSPredicate predicateWithFormat:@"title = %@", @"YOUR_ALBUM_TITLE"];
collection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum
subtype:PHAssetCollectionSubtypeAny
options:fetchOptions].firstObject;
// Create the album
if (!collection)
{
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCollectionChangeRequest *createAlbum = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:@"YOUR_ALBUM_TITLE"];
placeholder = [createAlbum placeholderForCreatedAssetCollection];
} completionHandler:^(BOOL success, NSError *error) {
if (success)
{
PHFetchResult *collectionFetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[placeholder.localIdentifier]
options:nil];
collection = collectionFetchResult.firstObject;
}
}];
}
// Save to the album
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *assetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:[UIImage imageWithData:imageData]];
placeholder = [assetRequest placeholderForCreatedAsset];
photosAsset = [PHAsset fetchAssetsInAssetCollection:collection options:nil];
PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection
assets:photosAsset];
[albumChangeRequest addAssets:@[placeholder]];
} completionHandler:^(BOOL success, NSError *error) {
if (success)
{
NSString *UUID = [placeholder.localIdentifier substringToIndex:36];
self.photo.assetURL = [NSString stringWithFormat:@"assets-library://asset/asset.PNG?id=%@&ext=JPG", UUID];
[self savePhoto];
}
else
{
NSLog(@"%@", error);
}
}];
UUIDの最後のビットは、ALAssetからAssetURLプロパティの代替を作成するために 別のStackOverflowスレッド で見つけたものです。
注:より完全な回答については、以下のchrisのコメントを参照してください。
私が書いたコードを再利用したいので、次のように使用できるPHPhotoLibraryの拡張機能を作成することにしました。
PHPhotoLibrary.saveImage(photo, albumName: "Trip") { asset in
guard let asset = asset else {
assert(false, "Asset is nil")
return
}
PHPhotoLibrary.loadThumbnailFromAsset(asset) { thumbnail in
print(thumbnail)
}
}
コードは次のとおりです。 https://Gist.github.com/ricardopereira/636ccd0a3c8a327c43d42e7cbca4d041
Swiftのために更新されたよう2.1+とビデオ用の場合には、あなたはそれをやろうとしていると、ここで終わっています。 (そのようなイメージのために使用してではなく、ビデオなど)のわずかな違いのために他の回答と比較
var photosAsset: PHFetchResult!
var collection: PHAssetCollection!
var assetCollectionPlaceholder: PHObjectPlaceholder!
//Make sure we have custom album for this app if haven't already
let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: "title = %@", "MY_APP_ALBUM_NAME")
self.collection = PHAssetCollection.fetchAssetCollectionsWithType(.Album, subtype: .Any, options: fetchOptions).firstObject as! PHAssetCollection
//if we don't have a special album for this app yet then make one
if self.collection == nil {
PHPhotoLibrary.sharedPhotoLibrary().performChanges({
let createAlbumRequest : PHAssetCollectionChangeRequest = PHAssetCollectionChangeRequest.creationRequestForAssetCollectionWithTitle("MY_APP_ALBUM_NAME")
self.assetCollectionPlaceholder = createAlbumRequest.placeholderForCreatedAssetCollection
}, completionHandler: { success, error in
if success {
let collectionFetchResult = PHAssetCollection.fetchAssetCollectionsWithLocalIdentifiers([self.assetCollectionPlaceholder.localIdentifier], options: nil)
print(collectionFetchResult)
self.collection = collectionFetchResult.firstObject as! PHAssetCollection
}
})
}
//save the video to Photos
PHPhotoLibrary.sharedPhotoLibrary().performChanges({
let assetRequest = PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(self.VIDEO_URL_FOR_VIDEO_YOU_MADE!)
let assetPlaceholder = assetRequest!.placeholderForCreatedAsset
self.photosAsset = PHAsset.fetchAssetsInAssetCollection(self.collection, options: nil)
let albumChangeRequest = PHAssetCollectionChangeRequest(forAssetCollection: self.collection, assets: self.photosAsset)
albumChangeRequest!.addAssets([assetPlaceholder!])
}, completionHandler: { success, error in
if success {
print("added video to album")
}else if error != nil{
print("handle error since couldn't save video")
}
}
})
@ricardopereiraと@ColossalChrisのコードを改善しました。内線にビデオを追加し、コンパイルエラーを取り除くためにPHAssetの上に別の拡張子を追加しました。 。Swift 2.1サンプルの使用で動作します:
#import "Yourtargetname-Swift.h"//important!
NSURL *videoURL = [[NSURL alloc] initFileURLWithPath:PATH_TO_VIDEO];
[PHPhotoLibrary saveVideo:videoURL albumName:@"my album" completion:^(PHAsset * asset) {
NSLog(@"success");
NSLog(@"asset%lu",(unsigned long)asset.pixelWidth);
}];
インポートSwiftファイルの両方: https://github.com/kv2/PHPhotoLibrary-PhotoAsset.Swift
ターゲットのSwiftヘッダーをインポートする限り、objective-cで使用できます( ViewController.m ファイルを参照)。