来自PHImageManager的图像数据与保存为资产

时间:2016-02-16 15:43:30

标签: ios swift ios9 phasset

您好,并提前感谢您抽出时间来查看我的问题。

我正在创建一个位图,然后从该位图构建一个PNG。然后我将PNG保存到相册中。通过其本地标识符获取该资产后,然后使用PHImageManager检索与该资产关联的UIImage,我注意到图像的字节已更改。我不确定在保存为PHAsset时是否添加了标题或什么,但我没有看到插入和检索图像之间的任何常见字节。当我将检索到的图像本身放入视图中时,它看起来不错,所以我很难过。

以下是一些展示问题的示例代码。

// image is a UIImage

// This is to show what the bytes are prior to saving
let imageRef = image.CGImage!
let cgData = CGDataProviderCopyData(CGImageGetDataProvider(imageRef))
let data = NSData(data: cgData)
let bytes = UnsafeMutablePointer<UInt8>(data.bytes)

print(data.length)
for i in 0..<16 {
    print(bytes[i])
}

var assetIdentifier: String!

// collectionIdentifier is a valid local identifier for an existing collection
let collectionFetchRequest = PHAssetCollection.fetAssetCollectionsWithLocalIdentifiers([collectionIdentifier], options: nil)
let collection = collectionFetchRequest.firstObject as! PHAssetCollection

PHPhotoLibrary.sharedPhotoLibrary().performChanges({

    let assetCreationRequest = PHAssetChangeRequest.creationRequestForAssetFromImage(image)
    let collectionChangeRequest = PHAssetCollectionChangeRequest(forAssetCollection: collection)!
    let assetPlaceholder = assetCreationRequest.placeholderForCreatedAsset!
    collectionChangeRequest.addAssets([assetPlaceholder])
    assetIdentifier = assetPlaceholder.localIdentifier

}) { (_, _) in

    let assetFetchRequest = PHAsset.fetchAssetsWithLocalIdentifiers([assetIdentifier], options: nil)
    let asset = assetFetchRequest.firstObject as! PHAsset

    let options = PHImageRequestOptions()
    options.synchronous = true
    options.version = .Current
    options.resizeMode = .None

    // The image is actually 64 x 64, but the targetSize doesn't seem to affect the bytes I'm getting out, I assume because the options aren't saying not to resize or crop anything
    // This was the not working code.
    // PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: CGSizeMake(256, 256), contentMode: .Default, options: options) { (retrievedImage, _) in

    // This is the working code.
    PHImageManager.defaultManager().requestImageDataForAsset(asset, options: options) { (data, _, _, _) in

        let retrievedImage = UIImage(data: data!)!

        // This is to show what the bytes are after retrieving
        let retrievedCGImage = retrievedImage!.CGImage!
        let retrievedCFData = CGDataProviderCopyData(CGImageGetDataProvider(retrievedCGImage))!
        let retrievedData = NSData(data: retrievedCFData)
        let retrievedBytes = UnsafeMutablePointer<UInt8>(retrievedData.bytes)

        // Length is the same but the bytes are not even close to right
        print(retrievedData.length)
        for i in 0..<16 {
            print(retrievedBytes[i])
        }

    }
}

请随意纠正此代码中任何不正确或低效执行操作的部分。这段代码应该运行,所以如果你看到任何语法错误或错误的变量,那些只在StackOverflow而不是在XCode中,所以它们不是这个字节问题的原因。此外,就图像中的字节而言,我并不关心第4个字节,即alpha分量,因为从我的测试到目前为止它始终是255。如果有人知道如何使用这个第4个字节,而不是在保存图像时只设置为255或者只是没有alpha组件,那么这也会有所帮助。

再次感谢您的时间和考虑!

编辑:

以下是对回答者的完整回复:

感谢您的提升。事实证明你对requestImageDataForAsset的工作正确。我将编辑原始代码块以反映工作代码。您是否知道它在描述requestImageForAsset返回的图像的文档中的哪个位置?

此外,您是否知道任何描述requestImageDataForAsset返回的数据的文档?我对图片存储机制不是很熟悉,但是从requestImageData返回的数据也不会与图片完全匹配,直到它变成UIImage。

再次感谢!

StackOverflow的可爱界面使输入按键提交评论,然后最多可以编辑5分钟。这太好了。

1 个答案:

答案 0 :(得分:2)

requestImageForAsset方法不保证您获得字节完美输出。我建议你尝试requestImageDataForAsset方法,它应该给出你期望的结果。