简体   繁体   English

NSData到UIImage

[英]NSData to UIImage

I'm trying to save a UIIMage and then retrieve it and display it. 我正在尝试保存UIIMage,然后检索并显示它。 I've been successful by saving an image in the bundle, retrieving it from there and displaying. 通过在图像包中保存图像,从那里检索并显示图像,我获得了成功。 My problem comes from when I try to save an image to disk (converting it to NSData), then retrieving it. 我的问题来自于我尝试将图像保存到磁盘(将其转换为NSData),然后检索它。 I convert the image to NSData like so... 我像这样将图像转换为NSData ...

NSData* topImageData = UIImageJPEGRepresentation(topImage, 1.0);

then I write it to disk like so... 然后我把它写成磁盘就像这样......

[topImageData writeToFile:topPathToFile atomically:NO];

then I tried to retrieve it like so... 然后我试着像这样检索它......

topSubView.image = [[UIImage alloc] initWithContentsOfFile:topPathToFile];

which returns no image (the size is zero). 它不返回任何图像(大小为零)。 so then I tried... 所以我试过......

NSData *data = [[NSData alloc] initWithContentsOfFile:topPathToFile];
topSubView.image = [[UIImage alloc] initWithData:data];

to no avail. 无济于事。 When I step through the debugger I do see that data contains the correct number of bytes but I'm confused as to why my image is not being created. 当我单步执行调试器时,我确实看到数据包含正确的字节数,但我很困惑为什么我的图像没有被创建。 Am I missing a step? 我错过了一步吗? Do I need to do something with NSData before converting to an image? 在转换为图像之前,我是否需要对NSData执行某些操作?

Try this code. 试试这个代码。 This worked for me. 这对我有用。

Saving the data. 保存数据。

create path to save the image. 创建保存图像的路径。

let libraryDirectory = NSSearchPathForDirectoriesInDomains(.libraryDirectory,
                                                               .userDomainMask,
                                                               true)[0]
let libraryURL = URL(fileURLWithPath: libraryDirectory, isDirectory: true)
let fileURL = libraryURL.appendingPathComponent("image.data")

convert the image to a Data object and save it to the file. 将图像转换为Data对象并将其保存到文件中。

let data = UIImageJPEGRepresentation(myImage, 1.0)
try? data?.write(to: fileURL)

retrieving the saved image 检索保存的图像

let newImage = UIImage(contentsOfFile: fileURL.relativePath)

Create an imageview and load it with the retrieved image. 创建一个imageview并使用检索到的图像加载它。

let imageView = UIImageView(image: newImage)
self.view.addSubview(imageView)

You should be able to use class methods of UIImage 您应该能够使用UIImage的类方法

[UIImage imageWithContentsOfFile:topPathToFile]; 

OR 要么

[UIImage imageWithData:data];

Did that not work? 这不起作用吗?

Hope this helps! 希望这可以帮助!

Just in case this helps someone, from iOS6 we have the imageWithData:scale method. 为了防止有人,从iOS6我们有了imageWithData:scale方法。 To get an UIImage with the right scale from an NSData object, use that method, declaring the scale you use to store the original image. 要从NSData对象获取具有正确比例的UIImage,请使用该方法,声明用于存储原始图像的比例。 For example: 例如:

CGFloat screenScale = [[UIScreen mainScreen] scale];
UIImage *image = [UIImage imageWithData:myimage scale:screenScale];

Here, myimage is the NSData object where you stored the original image. 这里,myimage是存储原始图像的NSData对象。 In the example, I used the scale of the screen. 在示例中,我使用了屏幕的比例。 If you use another scale for the original image, use that value instead. 如果您对原始图像使用其他比例,请改用该值。

Use if-let block with Data to prevent app crash & safe execution of code, as function UIImagePNGRepresentation returns an optional value. 使用if-let阻止数据以防止应用程序崩溃和安全执行代码,因为函数UIImagePNGRepresentation返回一个可选值。

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

Note: Data is Swift 3+ class. 注意: 数据是Swift 3+类。 Use Data instead of NSData with Swift 3+ 使用数据代替NSData和Swift 3+

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(img)
    }

    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...
     }
}

Check this out: http://www.nixwire.com/getting-uiimage-to-work-with-nscoding-encodewithcoder/ . 看看这个: http//www.nixwire.com/getting-uiimage-to-work-with-nscoding-encodewithcoder/

It has exactly what I think the solution to your problem is. 它正是我认为你的问题的解决方案。 You can't just make an image out of NSData, even though that's what common sense suggests. 你不能只用NSData制作图像,即使这是常识所暗示的。 You have to use UIImagePNGRepresentation. 你必须使用UIImagePNGRepresentation。 Let me know if this helps. 如果这有帮助,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM