How to convert (OS_dispatch_data *) 5018112 bytes into NSData to put into UIImage
Asked Answered
B

1

10

I've been looking for an answer to this and some seem like they might be what I need but I'm not sure. I found this Question #9152851 and this Question #2617625 and poked around on a bunch of links but I need some direction here.

Essentially, I'm dispatching an async call to process an image using OpenCV. You can see by the code here that I'm turning it into NSData * before sending it back to my delegate.

NSData *proccessedData = [NSData dataWithBytes:processedImage.data length:(processedImage.rows * processedImage.cols)];        
[self.delegate onProcessedBitmapReady:proccessedData withFocusQuality:focusQuality];

But when I get back to my delegate, my processedBitmap is of type (OS_dispatch_data *) and contains a value of bytes. So, when I try to set the UIImage, it gets set to null.

- (void)onProcessedBitmapReady:(NSData *)processedBitmap withFocusQuality:(double)focusQuality
{
    //Use comverted image from self.captureCommand onComplete
    UIImage *image = [[UIImage alloc] initWithData:processedBitmap];
    [self saveImage:image];
}

Here is a screen capture of the values:

Imgur

So, how do I convert those bytes (or whatever they are) into something that I can stuff into a UIImage?

Thank you in advance for your help.

------------------------------------------------------- Adding a new image -----------------------------------------

My Bytes

Does this new image help?

Thank you.

Bureaucrat answered 17/10, 2013 at 18:17 Comment(8)
Does onProcessedBitmapReady retain the NSData object? Is the NSData object retained elsewhere? Are you using ARC?Skirmish
Looks like reclaimed memory to me, your NSData was not retained properly.Array
My processedBitmap is my NSData. I see 5018112 bytes in it. The only thing weird is that it is of type OS_dispatch_data *. Does that mean that the memory has been reclaimed?Bureaucrat
OK. I created a property with (nonatomic, strong) and now I retrieve that value from my object and it still says that it is of type OS_dispatch_data *. Could that just be because I am calling it in an asynch call using GCD?Bureaucrat
NSData, like many other Foundation classes, is actually a class cluster, meaning that NSData is just providing the interface. OS_dispatch_data sounds like a specialized subclass that is used internally by Apple to transfer NSData stuff around blocks, but I might be wrong though. If it behaves like an NSData instance, it probably is, and the image is just in a format that isn't recognized by UIImageToms
@Toms - You are correct! I had to create a CGContextRef using CGBitmapContextCreate and then create a CGImageRef using the CGBitmapContextCreateImage and then create a UIImage using imageWithCGImage. Answer the question and I'll give you the points.Bureaucrat
@Lucy: Could have made a post with your own answer ? about how did you got around the issue ?Nubile
@Nubile - I used the CVImageConverter code by Artem Myagkov posted here: code.google.com/p/opencv-on-ios/source/browse/trunk/utilities/…Bureaucrat
T
11

NSData is actually a class cluster which just provides the interface, and there are multiple special implementations for it around. It appears that OS_dispatch_data is such a special implementations made to pass data objects around blocks, especially since your UIImage creation doesn't crash (as it would if you would pass it a non NSData object, or just garbage memory). Instead, it looks like UIImage simply doesn't recognize the format the image is in!

By the way, Apple has a great guide about the concept of class clusters, which can be found here.

Toms answered 17/10, 2013 at 21:59 Comment(1)
Specifically, OS_dispatch_data is a dispatch_data_t, from libdispatch. In iOS 7 and Mavericks, dispatch datas can be freely cast to NSData and are in fact NSData subclasses (if and only if Foundation is linked in the process of course).Melyndamem

© 2022 - 2024 — McMap. All rights reserved.