在 Swift 中将 UIImage 转换为 NSData 并转换回 UIImage? ?

我试图保存一个 UIImageNSData,然后读取 NSData回到一个新的 UIImage在雨燕。为了将 UIImage转换成 NSData,我使用了以下代码:

let imageData: NSData = UIImagePNGRepresentation(myImage)

如何将 imageData(即 NSData)转换回新的 UIImage

198436 次浏览

假设图像的比例为1。

在 Swift 4.2中,使用以下代码获取 Data ()。

image.pngData()

使用 imageWithData:方法,它被转换为 Swift 的 UIImage(data:)

let image : UIImage = UIImage(data: imageData)

谢谢,帮了我大忙,改成了 Swift 3

保存: let data = UIImagePNGRepresentation(image)

加载: < code > let image = UIImage (data: data)

以数据形式保存:

从 StoryBoard 中,如果您想在 MainStoryBoard 的 image 视图中保存“ image”数据,以下代码可以工作。

let image = UIImagePNGRepresentation(imageView.image!) as NSData?

将“ image”加载到 imageView: 仔细看看叹号“ !”,“ ?”是否和这个完全一样。

imageView.image = UIImage(data: image as! Data)

“ NSData”类型在此过程中自动转换为“ Data”类型。

为了安全地执行代码,使用 if-let块与 Data,以防止应用程序崩溃 & ,因为函数 UIImagePNGRepresentation返回一个可选的值。

if let img = UIImage(named: "TestImage.png") {
if let data:Data = UIImagePNGRepresentation(img) {
// Handle operations with data here...
}
}

注意: 百科是 Swift 3 + 类。使用 Data 代替 NSData Swift 3 +

通用图像操作(如 png 和 jpg) :

if let img = UIImage(named: "TestImage.png") {  //UIImage(named: "TestImage.jpg")
if let data:Data = UIImagePNGRepresentation(img) {
handleOperationWithData(data: data)
} else if let data:Data = UIImageJPEGRepresentation(img, 1.0) {
handleOperationWithData(data: data)
}
}


*******
func handleOperationWithData(data: Data) {
// Handle operations with data here...
if let image = UIImage(data: data) {
// Use image...
}
}

使用扩展名:

extension UIImage {


var pngRepresentationData: Data? {
return UIImagePNGRepresentation(self)
}


var jpegRepresentationData: Data? {
return UIImageJPEGRepresentation(self, 1.0)
}
}


*******
if let img = UIImage(named: "TestImage.png") {  //UIImage(named: "TestImage.jpg")
if let data = img.pngRepresentationData {
handleOperationWithData(data: data)
} else if let data = img.jpegRepresentationData {
handleOperationWithData(data: data)
}
}


*******
func handleOperationWithData(data: Data) {
// Handle operations with data here...
if let image = UIImage(data: data) {
// Use image...
}
}

现在在 Swift 4.2中,您可以使用 UIImagepngData()新实例方法从图像中获取数据

let profileImage = UIImage(named:"profile")!
let imageData = profileImage.pngData()

图片到数据:-

    if let img = UIImage(named: "xxx.png") {
let pngdata = img.pngData()
}


if let img = UIImage(named: "xxx.jpeg") {
let jpegdata = img.jpegData(compressionQuality: 1)
}

数据对图片:-

guard let image = UIImage(data: pngData) else { return }

细节

  • Xcode 10.2.1(10E1001) ,Swift 5

解决方案1

guard let image = UIImage(named: "img") else { return }
let jpegData = image.jpegData(compressionQuality: 1.0)
let pngData = image.pngData()

解决方案2.1

extension UIImage {
func toData (options: NSDictionary, type: CFString) -> Data? {
guard let cgImage = cgImage else { return nil }
return autoreleasepool { () -> Data? in
let data = NSMutableData()
guard let imageDestination = CGImageDestinationCreateWithData(data as CFMutableData, type, 1, nil) else { return nil }
CGImageDestinationAddImage(imageDestination, cgImage, options)
CGImageDestinationFinalize(imageDestination)
return data as Data
}
}
}

解决方案2.1的用法

// about properties: https://developer.apple.com/documentation/imageio/1464962-cgimagedestinationaddimage
let options: NSDictionary =     [
kCGImagePropertyOrientation: 6,
kCGImagePropertyHasAlpha: true,
kCGImageDestinationLossyCompressionQuality: 0.5
]


// https://developer.apple.com/documentation/mobilecoreservices/uttype/uti_image_content_types
guard let data = image.toData(options: options, type: kUTTypeJPEG) else { return }
let size = CGFloat(data.count)/1000.0/1024.0
print("\(size) mb")

方案2.2

extension UIImage {


func toJpegData (compressionQuality: CGFloat, hasAlpha: Bool = true, orientation: Int = 6) -> Data? {
guard cgImage != nil else { return nil }
let options: NSDictionary =     [
kCGImagePropertyOrientation: orientation,
kCGImagePropertyHasAlpha: hasAlpha,
kCGImageDestinationLossyCompressionQuality: compressionQuality
]
return toData(options: options, type: .jpeg)
}


func toData (options: NSDictionary, type: ImageType) -> Data? {
guard cgImage != nil else { return nil }
return toData(options: options, type: type.value)
}
// about properties: https://developer.apple.com/documentation/imageio/1464962-cgimagedestinationaddimage
func toData (options: NSDictionary, type: CFString) -> Data? {
guard let cgImage = cgImage else { return nil }
return autoreleasepool { () -> Data? in
let data = NSMutableData()
guard let imageDestination = CGImageDestinationCreateWithData(data as CFMutableData, type, 1, nil) else { return nil }
CGImageDestinationAddImage(imageDestination, cgImage, options)
CGImageDestinationFinalize(imageDestination)
return data as Data
}
}


// https://developer.apple.com/documentation/mobilecoreservices/uttype/uti_image_content_types
enum ImageType {
case image // abstract image data
case jpeg                       // JPEG image
case jpeg2000                   // JPEG-2000 image
case tiff                       // TIFF image
case pict                       // Quickdraw PICT format
case gif                        // GIF image
case png                        // PNG image
case quickTimeImage             // QuickTime image format (OSType 'qtif')
case appleICNS                  // Apple icon data
case bmp                        // Windows bitmap
case ico                        // Windows icon data
case rawImage                   // base type for raw image data (.raw)
case scalableVectorGraphics     // SVG image
case livePhoto                  // Live Photo


var value: CFString {
switch self {
case .image: return kUTTypeImage
case .jpeg: return kUTTypeJPEG
case .jpeg2000: return kUTTypeJPEG2000
case .tiff: return kUTTypeTIFF
case .pict: return kUTTypePICT
case .gif: return kUTTypeGIF
case .png: return kUTTypePNG
case .quickTimeImage: return kUTTypeQuickTimeImage
case .appleICNS: return kUTTypeAppleICNS
case .bmp: return kUTTypeBMP
case .ico: return kUTTypeICO
case .rawImage: return kUTTypeRawImage
case .scalableVectorGraphics: return kUTTypeScalableVectorGraphics
case .livePhoto: return kUTTypeLivePhoto
}
}
}
}

解决方案2.2的用法

let compressionQuality: CGFloat = 0.4
guard let data = image.toJpegData(compressionQuality: compressionQuality) else { return }
printSize(of: data)


let options: NSDictionary =     [
kCGImagePropertyHasAlpha: true,
kCGImageDestinationLossyCompressionQuality: compressionQuality
]
guard let data2 = image.toData(options: options, type: .png) else { return }
printSize(of: data2)

问题

图像表示需要大量的 CPU 和内存资源。因此,在这种情况下,最好遵循以下几条规则:

- 不要在主队列上运行 jpegData (pressionQuality:)

- 同时只运行一个 jpegData (pressionQuality:)

错:

for i in 0...50 {
DispatchQueue.global(qos: .utility).async {
let quality = 0.02 * CGFloat(i)
//let data = image.toJpegData(compressionQuality: quality)
let data = image.jpegData(compressionQuality: quality)
let size = CGFloat(data!.count)/1000.0/1024.0
print("\(i), quality: \(quality), \(size.rounded()) mb")
}
}

右图:

let serialQueue = DispatchQueue(label: "queue", qos: .utility, attributes: [], autoreleaseFrequency: .workItem, target: nil)


for i in 0...50 {
serialQueue.async {
let quality = 0.02 * CGFloat(i)
//let data = image.toJpegData(compressionQuality: quality)
let data = image.jpegData(compressionQuality: quality)
let size = CGFloat(data!.count)/1000.0/1024.0
print("\(i), quality: \(quality), \(size.rounded()) mb")
}
}

连结

Swift 5

让您作为 UIImage 创建的图像成为图像

image.pngData() as NSData?

这是一个简单的解决方案

static var UserProfilePhoto = UIImage()
guard let image = UIImage(named: "Photo") else { return }
guard let pngdata = image.pngData() else { return }
UserProfilePhoto = UIImage(data: pngdata)!