始终将屏幕截图保存在“照片”中相同的自定义名称应用相册中

Posted

技术标签:

【中文标题】始终将屏幕截图保存在“照片”中相同的自定义名称应用相册中【英文标题】:Always save screenshot in same custom name app album in "Photos" 【发布时间】:2015-10-13 19:24:33 【问题描述】:

我正在构建一个带有屏幕截图按钮的应用程序。现在,我想将在此应用中制作的所有屏幕截图保存在相同的自定义名称应用相册中。我已经知道如何在第一次使用下面的代码打开该应用程序时创建相册。 我正在使用照片框架创建我的相册,例如:

-(void)createAppAlbum


[[phphotoLibrary sharedPhotoLibrary] performChanges:^
    PHAssetCollectionChangeRequest *changeRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:@"App Album Name"];
    albumPlaceholder = changeRequest.placeholderForCreatedAssetCollection;



 completionHandler:^(BOOL success, NSError *error) 
                         if (success) 
                         fetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[albumPlaceholder.localIdentifier] options:nil];
                                          assetCollection = fetchResult.firstObject;

 
                        else 
                              NSLog(@"Error creating album: %@", error);
                                  ];


所以我的应用程序创建了名为“应用程序专辑名称”的专辑。 我可以使用以下按钮将我的截图保存在我的新专辑中:

 -(IBAction)screenshot:(id)sender


if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [UIScreen mainScreen].scale);
else
    UIGraphicsBeginImageContext(self.view.bounds.size);

[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();


[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^
    PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];

    PHAssetCollectionChangeRequest *assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
    [assetCollectionChangeRequest addAssets:@[[assetChangeRequest placeholderForCreatedAsset]]];
 completionHandler:^(BOOL success, NSError *error) 
    if (!success) 
        NSLog(@"Error creating asset: %@", error);
    
];

如果我离开这个viewController,稍后再回来,我想找到我已经创建的相册,并在同一个相册中保存另一个屏幕截图,因为我不想每次进入这个都创建一个新的视图控制器。

所以我的问题是,我如何获得我第一次按名称创建的专辑,然后保存新的屏幕截图。

【问题讨论】:

ios save photo in an app specific album的可能重复 @Fennelouski - iOS 5,也不使用照片框架.. 你能解释一下困难是什么吗?创建相册时,您将获得其标识符。从那时起,通过其标识符访问专辑。你有什么困难? 【参考方案1】:

由于此问题专门针对 iOS 8,因此此代码可以正常工作:

- (void)saveImage:(UIImage *)image 
    if (!self.library) 
        self.library = [[ALAssetsLibrary alloc] init];
    

    __weak ALAssetsLibrary *lib = self.library;

    [self.library addAssetsGroupAlbumWithName:@"My Photo Album" resultBlock:^(ALAssetsGroup *group) 

        ///checks if group previously created
        if(group == nil)

            //enumerate albums
            [lib enumerateGroupsWithTypes:ALAssetsGroupAlbum
                               usingBlock:^(ALAssetsGroup *g, BOOL *stop)
             
                 //if the album is equal to our album
                 if ([[g valueForProperty:ALAssetsGroupPropertyName] isEqualToString:@"My Photo Album"]) 

                     //save image
                     [lib writeImageDataToSavedPhotosAlbum:UIImagePNGRepresentation(image) metadata:nil
                                           completionBlock:^(NSURL *assetURL, NSError *error) 

                                               //then get the image asseturl
                                               [lib assetForURL:assetURL
                                                    resultBlock:^(ALAsset *asset) 
                                                        //put it into our album
                                                        [g addAsset:asset];
                                                     failureBlock:^(NSError *error) 

                                                    ];
                                           ];

                 
             failureBlock:^(NSError *error)

             ];

        else
            // save image directly to library
            [lib writeImageDataToSavedPhotosAlbum:UIImagePNGRepresentation(image) metadata:nil
                                  completionBlock:^(NSURL *assetURL, NSError *error) 

                                      [lib assetForURL:assetURL
                                           resultBlock:^(ALAsset *asset) 

                                               [group addAsset:asset];

                                            failureBlock:^(NSError *error) 

                                           ];
                                  ];
        

     failureBlock:^(NSError *error) 

    ];

为了测试它是否有效,我创建了一个单屏应用程序,向视图添加了一个按钮,并添加了一个截取屏幕截图然后将图像传递给saveImage: 函数的方法。这是我添加到它以使其工作的代码:

#import <AssetsLibrary/AssetsLibrary.h>

@interface ViewController ()
@property (nonatomic, strong) UIButton *screenshotButton;
@property (nonatomic, strong) ALAssetsLibrary *library;
@end

@implementation ViewController

- (void)viewDidLoad 
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    [self.view addSubview:self.screenshotButton];


- (UIButton *)screenshotButton 
    if (!_screenshotButton) 
        _screenshotButton = [[UIButton alloc] initWithFrame:CGRectInset(self.view.bounds, 100.0f, 120.0f)];
        _screenshotButton.layer.borderColor = [UIColor blueColor].CGColor;
        _screenshotButton.layer.borderWidth = 2.0f;
        _screenshotButton.layer.cornerRadius = 5.0f;
        [_screenshotButton setTitle:@"Take Screenshot" forState:UIControlStateNormal];
        [_screenshotButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
        [_screenshotButton addTarget:self action:@selector(takeScreenshot) forControlEvents:UIControlEventTouchUpInside];
    

    return _screenshotButton;


- (void)takeScreenshot 
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
        UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [UIScreen mainScreen].scale);
    else
        UIGraphicsBeginImageContext(self.view.bounds.size);

    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    NSData * imgData = UIImagePNGRepresentation(image);
    if(imgData)
        [imgData writeToFile:@"screenshot.png" atomically:YES];
    else
        NSLog(@"error while taking screenshot");


    UIColor *randomColor = [UIColor colorWithHue:((CGFloat)(arc4random()%255)/255.0f)
                                      saturation:((CGFloat)(arc4random()%255)/200.0f)
                                      brightness:((CGFloat)(arc4random()%100)/255.0f) + 0.5f
                                           alpha:1.0f];
    self.screenshotButton.layer.borderColor = randomColor.CGColor;
    [self.screenshotButton setTitleColor:randomColor forState:UIControlStateNormal];

    [self saveImage:image];

需要注意的几点:

AssetsLibrary 在 iOS 9 中已弃用,因此不建议使用 在 iOS 8 之后可以使用,但仍然可以使用。 这可以实现和 与传递给saveImage: 的任何UIImage 一起使用,因此它甚至可以工作 如果您正在使用另一个库。 确保包含#import &lt;AssetsLibrary/AssetsLibrary.h&gt;。 将“我的相册”更改为正确的相册名称,并可能静态设置

【讨论】:

使用Photo Kit很容易解决问题;使用资产库只是一个拐杖。 太棒了!我刚刚添加了 If 语句来创建文件夹,如果用户删除它。谢谢! 我不同意这并不理想,并且可能有更好的选择更适合 iOS 9,但这确实有效并且符合 iOS 8 的要求。

以上是关于始终将屏幕截图保存在“照片”中相同的自定义名称应用相册中的主要内容,如果未能解决你的问题,请参考以下文章

将屏幕截图保存到CoreData

如何将iphone屏幕截图保存为jpeg图像?

照片和视频未保存在我的自定义相册中

将 UIImage 保存为不同的名称

如何在用户帐户上显示创建的自定义注册字段中的数据(Drupal 8)

使用照片框架按图片大小过滤照片库