objective c - How do I access and manipulate JPEG image pixels? -


i have jpg file. need convert pixel data , change color of pixel. this:

    nsstring *string = [[nsbundle mainbundle] pathforresource:@"pic" oftype:@"jpg"];     nsdata *data = [nsdata datawithcontentsoffile:string];     unsigned char *bytesarray = datai.bytes;     nsuinteger byteslenght = data.length;    //--------pixel array     nsmutablearray *array = [[nsmutablearray alloc] initwithcapacity:byteslenght];     (int = 0; i<byteslenght; i++) {         [array addobject:[nsnumber numberwithunsignedchar:bytesarray[i]]];     } 

here try change color of pixels since 95 till 154.

nsnumber *number = [nsnumber numberwithint:200];     (int i=95; i<155; i++) {         [array replaceobjectatindex:i withobject:number];     } 

but when convert array image got blurred picture. don't understand why don't have influence on pixels , why have influence on picture in total?

the process of accessing pixel-level data little more complicated question might suggest, because, martin pointed out, jpeg can compressed image format. apple discusses approved technique getting pixel data in technical q&a qa1509.

bottom line, uncompressed pixel data uiimage, would:

  1. get cgimage uiimage.

  2. get data provider cgimageref via cgimagegetdataprovider.

  3. get binary data associated data provider via cgdataprovidercopydata.

  4. extract of information image, know how interpret buffer.

thus:

uiimage *image = ...  cgimageref imageref = image.cgimage;                                     // cgimageref nsassert(imageref, @"unable cgimageref");  cgdataproviderref provider = cgimagegetdataprovider(imageref);           // data provider nsassert(provider, @"unable provider");  nsdata *data = cfbridgingrelease(cgdataprovidercopydata(provider));      // copy of data nsassert(data, @"unable copy image data");  nsinteger       bitspercomponent = cgimagegetbitspercomponent(imageref); // other interesting details image nsinteger       bitspercomponent = cgimagegetbitspercomponent(imageref); nsinteger       bitsperpixel     = cgimagegetbitsperpixel(imageref); cgbitmapinfo    bitmapinfo       = cgimagegetbitmapinfo(imageref); nsinteger       bytesperrow      = cgimagegetbytesperrow(imageref); nsinteger       width            = cgimagegetwidth(imageref); nsinteger       height           = cgimagegetheight(imageref); cgcolorspaceref colorspace       = cgimagegetcolorspace(imageref); 

given want manipulate this, presumably want mutable pixel buffer. easiest approach make mutablecopy of nsdata object , manipulate there, in these cases, tend fall c, creating void *outputbuffer, copy original pixels , manipulate using traditional c array techniques.

to create buffer:

void *outputbuffer = malloc(width * height * bitsperpixel / 8); nsassert(outputbuffer, @"unable allocate buffer"); 

for precise details on how manipulate it, have @ bitmapinfo (which tell whether it's rgba or argb; whether it's floating point or integer) , bitspercomponent (which tell whether it's 8 or 16 bits per component, etc.). example, common jpeg format 8 bits per component, 4 components, rgba (i.e. red, green, blue, , alpha, in order). need check various properties extracted cgimageref make sure. see discussion in quartz 2d programming guide - bitmap images , image masks more information. find "figure 11-2" illuminating.

the next logical question when you're done manipulating pixel data, how create uiimage that. in short, you'd reverse above process, e.g. create data provider, create cgimageref, , create uiimage:

cgdataproviderref outputprovider = cgdataprovidercreatewithdata(null, outputbuffer, sizeof(outputbuffer), releasedata);  cgimageref outputimageref = cgimagecreate(width,                                           height,                                           bitspercomponent,                                           bitsperpixel,                                           bytesperrow,                                           colorspace,                                           bitmapinfo,                                           outputprovider,                                           null,                                           no,                                           kcgrenderingintentdefault);  uiimage *outputimage = [uiimage imagewithcgimage:outputimageref];  cgimagerelease(outputimageref); cgdataproviderrelease(outputprovider); 

where releasedata c function calls free pixel buffer associated data provider:

void releasedata(void *info, const void *data, size_t size) {     free((void *)data); } 

Comments

Popular posts from this blog

PHPMotion implementation - URL based videos (Hosted on separate location) -

javascript - Using Windows Media Player as video fallback for video tag -

c# - Unity IoC Lifetime per HttpRequest for UserStore -