如何创建带有 DPI 集的 UIImage?

How do I create a UIImage with the DPI set?

我有一个 UIImage,我希望将它保存到具有 DPI 元数据集的照片中。我知道 UIImage 是不可变的,所以我必须创建一个新的 UIImage。我使用 this answer 作为参考在 UIImage 上创建一个 swift 扩展函数,该函数生成一个带有 DPI 集的新 UIImage。我已使用 UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil) 成功将其保存到照片中。我通过电子邮件将其发送给自己(设置为 'Actual Size')并在预览中打开它,但 DPI 始终保持在 72。

这是我转换的函数:

func imageWithDPI(dpi :Int) -> UIImage? {
    guard let sourceImageData = UIImageJPEGRepresentation(self, 0.8) else {
        print("Couldn't make PNG Respresentation of UIImage")
        return nil
    }

    guard let source = CGImageSourceCreateWithData(sourceImageData, nil) else {
        print("Couldn't create source with sourceImageData")
        return nil
    }

    var metadata = CGImageSourceCopyPropertiesAtIndex(source, 0, nil) as? [String:AnyObject] ?? [String:AnyObject]()
    metadata[kCGImagePropertyDPIWidth as String] = dpi
    metadata[kCGImagePropertyDPIHeight as String] = dpi

    var exifDictionary = metadata[kCGImagePropertyTIFFDictionary as String] as? [String:AnyObject] ?? [String:AnyObject]()
    exifDictionary[kCGImagePropertyTIFFXResolution as String] = dpi
    exifDictionary[kCGImagePropertyTIFFYResolution as String] = dpi
    metadata[kCGImagePropertyTIFFDictionary as String] = exifDictionary

    var jfifDictionary = metadata[kCGImagePropertyJFIFDictionary as String] as? [String:AnyObject] ?? [String:AnyObject]()
    jfifDictionary[kCGImagePropertyJFIFXDensity as String] = dpi
    jfifDictionary[kCGImagePropertyJFIFYDensity as String] = dpi
    jfifDictionary[kCGImagePropertyJFIFVersion as String] = 1
    metadata[kCGImagePropertyJFIFDictionary as String] = jfifDictionary

    guard let uti = CGImageSourceGetType(source) else {
        print("Couldn't get type from source")
        return nil
    }

    let destinationImageData = NSMutableData()
    guard let destination = CGImageDestinationCreateWithData(destinationImageData, uti, 1, nil) else {
        print("Couldn't create destination with destinationImageData")
        return nil
    }

    CGImageDestinationAddImageFromSource(destination, source,0, metadata)
    CGImageDestinationFinalize(destination)

    return UIImage(data: destinationImageData)
}

我对 Core Graphics 有点不了解,所以任何建议都将不胜感激。

非常感谢。

当您从 destinationImageData 创建图像时,UIImage 可能会从图像中剥离所有元数据,包括 DPI。我最近 运行 在通过 iOS 的 UIActivityItemProvider API 分享图片时遇到了这个问题。如果我从 - (id)item 方法 returned 一个 UIImage * 那么所有的元数据都会丢失。解决方法是 return NSData *NSURL *

尝试 return 直接发送 destinationImageData,或将其保存到文件中并通过电子邮件发送给自己。

我很好奇你为什么要给图片设置DPI?如今,DPI 对于几乎所有数字图像来说几乎毫无意义(除非图像旨在准确表示物理对象的尺寸)。实际像素分辨率远比 DPI 重要。