I am working on a little side project (program for iPhone platform)and I don't exactly have a problem, but I don't really know where to start. The project I am working on has to do with getting the info and manipulating a pixel's RGB values inside an image. I know this is a very basic program , but I am a beginning iPhone programmer. I am planning on using CGImage library. I am displaying an image with a UIImage and imagePickerController and then converting that UImage into a CGImage. Is this the correct way of going about it?
I've already developed my algorithm, now I just need to be pushed/"knudged" in the right direction. Could anyone please help me? Any tutorials on this kind of thing or related topics?
I am working on a little side project (program for iPhone platform)and I don't exactly have a problem, but I don't really know where to start. The project I am working on has to do with getting the info and manipulating a pixel's RGB values inside an image. I know this is a very basic program , but I am a beginning iPhone programmer. I am planning on using CGImage library. I am displaying an image with a UIImage and imagePickerController and then converting that UImage into a CGImage. Is this the correct way of going about it?
I've already developed my algorithm, now I just need to be pushed/"knudged" in the right direction. Could anyone please help me? Any tutorials on this kind of thing or related topics?
Thanks in advance!
You're on the right track. Once you have a CGImage, use the functions CGImageGetBitmapInfo and CGImageGetAlphaInfo to get the bitmap data.
I've done quite a bit of direct manipulation of bitmap data in Mac OSX using NSImage objects, but haven't had occasion to do it with iOS yet, so I don't have any concrete info to give you.
Once you get the CGImageGetBitmapInfo you have to look at the CGBitmapInfo flags to figure out how the bitmap data is formatted. I don't know if the different OS versions or devices in the iOS family use different bitmap formats. I would suggest posting to Apple's developer site asking Apple's dev support staff what bitmap formats are used by different OS/hardware combinations.
If you don't intend to distribute your app, and only want it to work on your device, you can write it for just the format you get back from your device and OS, but remember that it may not work on other device/OS combinations. For that matter, the device and the simulator may well use different bitmap formats. The simulator is only a rough approximation of the iOS runtime environment, and some of the underlying code libraries are Mac OSX rather than iOS
Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.
Thanks! I found another thread that talks about this.
Heres a quoted post:
Quote:
Originally Posted by fiftysixty
The name of the method should be drawRect, not DrawRectangle. Another things is that if your class inherits from UIView, and if you haven't added MainImage as a subview of your view, then you should draw the image to your UIView in drawRect. That can be done like this:
Code:
- (void) drawRect:(CGRect)rect {
// get the graphics context used for drawing on this view
CGContextRef viewContext = UIGraphicsGetCurrentContext();
CGContextDrawImage(viewContext, self.bounds, image);
}
About the pixel array, the pointer you get using the methods in the 2nd post points to the beginning of the pixel array, to the first byte. You're likely dealing with an RGBA8888 format image, which means that there is one byte for red, green, blue and alpha values. So, using the pointer you can access the color components of a pixel in the image with the following formula:
pixel in coordinates x, y
imageWidth is the width of the image, in pixels
bytesPerPixel is the number of bytes used to store the pixel color components, in RGBA8888 format it is 4
red, green, blue, and alpha will contain values 0-255 for the current x,y position in your image. This code assumes that the data is in RGBA order with 8 bits per pixel. You should add code that verifies this and reports an error if the image has a different format.
Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.
Just wondering, whats all that "unsigned char red;" stuff?
wouldn't it be easier, and more efficient, to just make an array, for each r,g,b, and alpha? then store those values inside it?
Just wondering, whats all that "unsigned char red;" stuff?
wouldn't it be easier, and more efficient, to just make an array, for each r,g,b, and alpha? then store those values inside it?
The data you get from the bitmap will BE an array. I spelled out the code that lets you break the contents into a red, green, blue, and alpha component for each pixel.
You could also define a struct for the RGBA data, and assign it all at once, but I thought I would keep it simple since you seem to be struggling with C pointer syntax. The difference in efficiency is fairly small.
I'd have to do a little research to make sure that the struct above would use 4 consecutive bytes rather than adding padding between to make each byte begin on an even word boundary. There are compiler directives that let you control how structs are packed, but I don't have those directives or the default packing rules memorized.
As I say, the code I wrote at first is simpler for a neophyte.
Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.
Thanks again, you don't know how much you've helped me. I came from java and the eclipse sdk, which basically took care of everything for you...so you can see how I am with objective c lol
Thanks again, you don't know how much you've helped me. I came from java and the eclipse sdk, which basically took care of everything for you...so you can see how I am with objective c lol
Oh dear. Java leaves you woefully unprepared to deal with pointer manipulation.
I would STRONGLY suggest that you go buy a book on C. The K&R C book (The C programming language) is REALLY well written. It only covers C, not Objective C, but it will help a lot in understanding things like pointers which are completely alien to a Java programmer.
Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.
Hehe my dad has that book in his library. But, this project is just for a little summer school project so after this app, I am basically done with objective C and apple. and macs. So...is there any site that has all this pointer concept stuff in a condensed, easy to understand format? Thanks.
How to access raw bytes in CGImage without copying
Quote:
Originally Posted by Duncan C
You're on the right track. Once you have a CGImage, use the functions CGImageGetBitmapInfo and CGImageGetAlphaInfo to get the bitmap data.
I've done quite a bit of direct manipulation of bitmap data in Mac OSX using NSImage objects, but haven't had occasion to do it with iOS yet, so I don't have any concrete info to give you.
Once you get the CGImageGetBitmapInfo you have to look at the CGBitmapInfo flags to figure out how the bitmap data is formatted. I don't know if the different OS versions or devices in the iOS family use different bitmap formats. I would suggest posting to Apple's developer site asking Apple's dev support staff what bitmap formats are used by different OS/hardware combinations.
If you don't intend to distribute your app, and only want it to work on your device, you can write it for just the format you get back from your device and OS, but remember that it may not work on other device/OS combinations. For that matter, the device and the simulator may well use different bitmap formats. The simulator is only a rough approximation of the iOS runtime environment, and some of the underlying code libraries are Mac OSX rather than iOS
First time ever posting to a forum! Hope I'm typing in this in the correct place.
How exactly does one get the data out of a CGImage without copying? The options I've discovered so far are:
1. Allocate a byte array, put a graphics context on it, and draw the CGImage to it. (requires a copy)
2. Use CGDataProviderCopyData(CGImageGetDataProvider(CGIm age)); (requires a copy, apparently)
My actual goal is to decode a jpeg compressed image shortest time possible using only one buffer large enough to contain the result. I've used jpeg libraries on the desktop, and these usually allow access to the uncompressed bytes by rows. Is this possible on the iPhone? If not, is there at least a way to decompress the jpeg that requires only one buffer to store the result?
In short: I want to write this function
char* getImage(char* jpeg_bytes);
// should take only 1 big image buffer to store result, and possible a little more.
First time ever posting to a forum! Hope I'm typing in this in the correct place.
How exactly does one get the data out of a CGImage without copying? The options I've discovered so far are:
1. Allocate a byte array, put a graphics context on it, and draw the CGImage to it. (requires a copy)
2. Use CGDataProviderCopyData(CGImageGetDataProvider(CGIm age)); (requires a copy, apparently)
My actual goal is to decode a jpeg compressed image shortest time possible using only one buffer large enough to contain the result. I've used jpeg libraries on the desktop, and these usually allow access to the uncompressed bytes by rows. Is this possible on the iPhone? If not, is there at least a way to decompress the jpeg that requires only one buffer to store the result?
In short: I want to write this function
char* getImage(char* jpeg_bytes);
// should take only 1 big image buffer to store result, and possible a little more.
Thanks!
Convex,
I know how to do this in OX X, but haven't done it in iOS.
Here is some info extracted from a Stack overflow post that was linked earlier in this thread:
Quote:
You can't access the bitmap data of a UIImage directly.
You need to get the CGImage representation of the UIImage. Then get the CGImage's data provider, from that a CFData representation of the bitmap. Make sure to release the CFData when done.
You will probably want to look at the bitmap info of the CGImage to get pixel order, image dimensions, etc.
The above should give you a pointer to the bitmap data without making a copy, although as the poster says, you need to look at the description of the CGImage to figure out the pixel dimensions, byte ordering, end-of-row padding, etc.
EDIT: I just noticed that even the above code makes a copy of the data. It uses a call CGDataProviderCopyData, which makes a COPY of the underlying bitmap data.
Note that CGImages are complex beasties, with a wide variety of different formats. You'll need to carefully research the way that iOS formats it's images and figure out what variations you may get, and handle them all. This approach is potentially fragile. Apple may only use RGBA interleaved byte data now, in OS 4, but later, in a different version of the OS, use planar floating point R, G, B, and A values.
You might want to write some defensive code. For speed, write code that queries the CGImage to see if it is in the format you expect. If it is, use the above code. If not, create a custom context in the format you expect and ask the OS for the data in that format.
If you create your own graphics context, on the other hand, you can specify the format of the data, and the system will handle data conversion for you. That would involve creating a copy however, which you said you wanted to avoid.
Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.