选择照片会导致重新保存到相机胶卷 [英] Choosing a picture causes resave to camera roll

查看:39
本文介绍了选择照片会导致重新保存到相机胶卷的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序,用户可以在其中选择一张照片放在屏幕上,代码会自动将其放入自定义相册.但是每当他们选择一张照片时,它都会将其重新保存到相机胶卷中,从而创建重复项.我如何让它停止这样做?

I have a program in which the user chooses a photo to put on the screen and the code puts it into a custom album automatically. But whenever they choose a picture, it resaves it to the camera roll, creating duplicates. How do I make it stop doing this?

func fetchAssetCollectionForAlbum() -> PHAssetCollection? {
    let fetchOptions = PHFetchOptions()
    fetchOptions.predicate = NSPredicate(format: "title = %@", albumName)
    // fetch the asset for the album
    let collection = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: fetchOptions)

    var picturePlaceHolder: PHObjectPlaceholder? = nil

    if let _: AnyObject = collection.firstObject {
        return collection.firstObject
    }
    return nil
}

func save(image: UIImage) {
    if assetCollection == nil {
        return
    }

    PHPhotoLibrary.shared().performChanges({
        let assetChangeRequest = PHAssetChangeRequest.creationRequestForAsset(from: image)
        let assetPlaceHolder = assetChangeRequest.placeholderForCreatedAsset
        let albumChangeRequest = PHAssetCollectionChangeRequest(for: self.assetCollection)
        let enumeration: NSArray = [assetPlaceHolder!]
        albumChangeRequest!.addAssets(enumeration)

    }, completionHandler: nil)
}

推荐答案

我发布了一个类似的问题:Swift 3 或 4 保存到自定义相册会创建重复图片

I posted a similar question: Swift 3 or 4 Saving to custom album creates duplicate images

但我除了蟋蟀之外什么也没有.幸运的是,我想我找到了答案.我也会回答我自己的问题.

But I got nothing but crickets as well. Luckily, I think I found the answer. I'll answer my own question as well.

您拥有的代码(与我拥有的代码相同)是创建新资产.它仅用于在用户使用相机拍照后将图像保存到您的自定义相册中.它适用于全新的资产.

The code you have (which was the same code I had) is to CREATE A NEW ASSET. It is useful only for the saving the image to your custom album after the user has taken a picture with the camera. It is for brand new assets.

但是,对于现有资产,您不希望创建新资产.相反,您希望将现有资产添加到自定义相册.为此,您需要一种不同的方法.这是我创建的代码,它似乎正在运行.请记住,您必须首先获得资产 ID,以便您可以将其发送到您的方法并访问现有资产.

However, for existing assets, you do not want to create a new asset. Instead, you want to add the existing asset to the custom album. To do this, you need a different method. Here is the code I created and it seems to be working. Keep in mind that you will have to get the asset ID FIRST, so that you can send it to your method and access the existing asset.

因此,在您的 imagePickerController 中,您必须确定用户是否选择了现有图像,或者是否正在从新的相机操作调用该方法.

So, in your imagePickerController, you have to determine whether the user chose an existing image or whether the method is being called from a new camera action.

let pickerSource = picker.sourceType;
switch(pickerSource){
 case .savedPhotosAlbum, .photoLibrary:
  if(let url = info[UIIMagePickerControllerReferenceURL] as? NSURL{
   let refURLString = refURL?.absoluteString;
   /* value for refURLString looks something like assets-library://asset/asset.JPG?id=82A6E75C-EA55-4C3A-A988-4BF8C7F3F8F5&ext=JPG */
   let refID = {function here to extract the id query param from the url string}
   /*above gets you the asset ID, you can get the asset directly, but it is only 
     available in ios 11+.
   */
   MYPHOTOHELPERCLASS.transferImage(toAlbum: "myalbumname", withID: refID!, ...)

 }
 break;
 case .camera:
 ...
 break;
}

现在,在您的 photohelper 类(或任何地方的任何函数中),编辑资产而不是创建新资产,这就是我所拥有的.我假设可以省略 changeRequest 变量.我只是在玩,直到我做对了.通过完全荒谬的苹果文档,我至少能够注意到还有其他方法可以使用.我发现 NSFastEnumeration 参数可以是 PHAssets 的 NSArray,而不仅仅是占位符 PHObjectPlaceholder 对象.

Now, in your photohelper class (or in any function anywhere, whatever), to EDIT the asset instead of create a new one, this is what I have. I am assuming the changeRequest variable can be ommitted. I was just playing around until I got this right. Going through the completely ridiculous apple docs I was able to at least notice that there were other methods to play with. I found that the NSFastEnumeration parameter can be an NSArray of PHAssets, and not just placeholder PHObjectPlaceholder objects.

public static func transferImage(toAlbum albumName:String, withID imageID:String, onSuccess success:@escaping(String)->Void, onFailure failure:@escaping(Error?)->Void){

  guard let album = self.getAlbum(withName: albumName) else{
    ... failure here, albumNotFoundError
    return;
  }

  if(self.hasImageInAlbum(withIdentifier: imageID, fromAlbum: albunName)){
    ... failure here, image already exists in the album, do not make another
    return;
  }

  let theAsset = self.getExistingAsset(withLocalIdentifier: imageID);
  if(theAsset == nil){
    ... failure, no asset for asset id
    return;
  }

    PHPhotoLibrary.shared().performChanges({
      let albumChangeRequest = PHAssetCollectionChangeRequest(for: album);
      let changeRequest = PHAssetChangeRequest.init(for: theAsset!);
      let enumeration:NSArray = [theAsset!];
      let cnt = album.estimatedAssetCount;
      if(cnt == 0){
          albumChangeRequest?.addAssets(enumeration);
      }else{
          albumChangeRequest?.inserAssets(enumeration, at: [0]);
      }
    }){didSucceed, error) in
       OperationQueue.main.addOperation({
         didSucceed ? success(imageID) : failure(error);
       })
    }

}

所以,它几乎是一样的,除了不是创建资产创建请求并为创建的资产生成占位符,而是使用现有资产 ID 来获取现有资产并将现有资产添加到 addasset/insertasset NSArray 参数而不是新创建的资产占位符.

So, it is pretty much the same, except instead of creating an Asset Creation Request and generating a placeholder for the created asset, you instead just use the existing asset ID to fetch an existing asset and add the existing asset to the addasset/insertasset NSArray parameter instead of a newly created asset placeholder.

这篇关于选择照片会导致重新保存到相机胶卷的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆