ios 将 UIImage 转换为 NSData 并在 Swift 中转换回 UIImage?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32297704/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert UIImage to NSData and convert back to UIImage in Swift?
提问by pete
I'm trying to save a UIImage
to NSData
and then read the NSData
back to a new UIImage
in Swift. To convert the UIImage
to NSData
I'm using the following code:
我正在尝试保存一个UIImage
toNSData
然后在 Swift 中读NSData
回一个新UIImage
的。要转换UIImage
为NSData
我使用以下代码:
let imageData: NSData = UIImagePNGRepresentation(myImage)
How do I convert imageData
(i.e., NSData
) back to a new UIImage
?
如何将imageData
(即NSData
)转换回新的UIImage
?
回答by algal
UIImage(data:imageData,scale:1.0)
presuming the image's scale is 1.
UIImage(data:imageData,scale:1.0)
假设图像的比例为 1。
In swift 4.2, use below code for get Data().
在 swift 4.2 中,使用下面的代码获取数据()。
image.pngData()
回答by Ivan Sinigaglia
Thanks. Helped me a lot. Converted to Swift 3 and worked
谢谢。帮了我很多。转换为 Swift 3 并开始工作
To save: let data = UIImagePNGRepresentation(image)
保存: let data = UIImagePNGRepresentation(image)
To load: let image = UIImage(data: data)
装载: let image = UIImage(data: data)
回答by dasblinkenlight
Use imageWithData:
method, which gets translated to Swift as UIImage(data:)
使用imageWithData:
方法,它被翻译成 Swift 作为UIImage(data:)
let image : UIImage = UIImage(data: imageData)
回答by Sh_Khan
Now in Swift 4.2you can use pngData()
new instance method of UIImage
to get the data from the image
现在在Swift 4.2 中,您可以使用pngData()
新的实例方法UIImage
从图像中获取数据
let profileImage = UIImage(named:"profile")!
let imageData = profileImage.pngData()
回答by Vasily Bodnarchuk
Details
细节
- Xcode 10.2.1 (10E1001), Swift 5
- Xcode 10.2.1 (10E1001),Swift 5
Solution 1
解决方案1
guard let image = UIImage(named: "img") else { return }
let jpegData = image.jpegData(compressionQuality: 1.0)
let pngData = image.pngData()
Solution 2.1
解决方案 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
}
}
}
Usage of solution 2.1
解决方案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")
Solution 2.2
解决方案 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
}
}
}
}
Usage of solution 2.2
解决方案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)
Problems
问题
Image representing will take a lot of cpu and memory resources. So, in this case it is better to follow several rules:
图像表示会占用大量的 CPU 和内存资源。因此,在这种情况下,最好遵循以下几条规则:
- do not run jpegData(compressionQuality:) on main queue
- 不要在主队列上运行 jpegData(compressionQuality:)
- run only one jpegData(compressionQuality:) simultaneously
- 同时只运行一个 jpegData(compressionQuality:)
Wrong:
错误的:
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")
}
}
Right:
对:
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")
}
}
Links
链接
回答by zemunkh
To save as data:
保存为数据:
From StoryBoard, if you want to save "image" data on the imageView of MainStoryBoard, following codes will work.
从 StoryBoard 中,如果您想在 MainStoryBoard 的 imageView 上保存“图像”数据,以下代码将起作用。
let image = UIImagePNGRepresentation(imageView.image!) as NSData?
To load "image" to imageView: Look at exclamation point "!", "?" closely whether that is quite same as this one.
将“图像”加载到 imageView:查看感叹号“!”、“?” 是否与此完全相同。
imageView.image = UIImage(data: image as! Data)
"NSData" type is converted into "Data" type automatically during this process.
在此过程中,“NSData”类型会自动转换为“Data”类型。
回答by Krunal
For safe execution of code, use if-let
block with Data
to prevent app crash & , as function UIImagePNGRepresentation
returns an optional value.
为了安全执行代码,请使用if-let
block withData
来防止应用程序崩溃 & ,因为函数UIImagePNGRepresentation
返回一个可选值。
if let img = UIImage(named: "TestImage.png") {
if let data:Data = UIImagePNGRepresentation(img) {
// Handle operations with data here...
}
}
Note: Datais Swift 3+ class. Use Data instead of NSData with Swift 3+
注意:数据是 Swift 3+ 类。在 Swift 3+ 中使用 Data 而不是 NSData
Generic image operations (like png & jpg both):
通用图像操作(如 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...
}
}
By using extension:
通过使用扩展:
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...
}
}
回答by Yogendra Singh
Image to Data:-
图像到数据:-
if let img = UIImage(named: "xxx.png") {
let pngdata = img.pngData()
}
if let img = UIImage(named: "xxx.jpeg") {
let jpegdata = img.jpegData(compressionQuality: 1)
}
Data to Image:-
数据到图像:-
let image = UIImage(data: pngData)
回答by dakrawat
Swift 5
斯威夫特 5
let the image you create as UIImage be image
让您创建为 UIImage 的图像成为图像
image.pngData() as NSData?