Sunday, December 22, 2013

Using WSO2 Enterprise Service Bus

In order to use the WSO2 ESB, you need to download the following.

Latest version of WSO2 ESB Binary
I use the currently available latest version which is 4.8.0 that is available in the WSO2 website. 
Click here to navigate to the downloads page and click on Binary button to start the download as shown below.























Latest version of Java Development Kit
 I use the currently available latest jdk which is jdk7.
Click here to navigate to the downloads page of Oracle to start the download. The below image could help you.























once you are done with the jdk download, you can install it and then do not forget to set the path for the bin folder and set the JAVA_HOME variable in your machine.

Setting the java path to the bin folder


Once you install jdk in your machine, do navigate to the jdk bin folder of the correct version as shown below and copy the path to it.
































then type env under startup search box ( in windows) and select Edit the system environment variables option from the search results box. Next click Environment Variables under Advanced tab and then focus on path under System variables. Select it and then click Edit. Then place the cursor under variable value text box and go towards its end then add a semicolon and paste the path that you copied to clipboard (e.g :- C:\Program Files\Java\jdk1.7.0_45\bin). Then close all three opened windows by clicking OK buttons in each of them.

Note, if you don't have administrative privileges then you can temporarily set the path as below usinga command prompt (remeber you should use the correct path of your jdk bin folder)

set path=%path%;C:\Program Files\Java\jdk1.7.0_45\bin

Setting the JAVA_HOME variable


type env under startup search box ( in windows) and select Edit the system environment variables option from the search results box. under User variables for <username> panel, click New. Then add the following

Variable Name: JAVA_HOME
Variable Value: C:\Program Files\Java\jdk1.7.0_45

Then close all three opened windows by clicking OK buttons in each of them.

Note, if you don't have administrative privileges then you can temporarily set the path as below usinga command prompt (remeber you should use the correct path of your jdk bin folder)

set JAVA_HOME=C:\Program Files\Java\jdk1.7.0_45

Checking whether jdk path to bin and the JAVA_HOME variables are correctly set in your machine


open a command prompt and type,
java -version to check the java version installed is correctly identified

type,

set JAVA_HOME and observe whether the path to java home is correctly identified






















Now you are ready to run the WSO2 ESB.

Running the WSO2 ESB Server


First of all, extract the wso2esb-4.8.0.zip file that you have just downloaded. then navigate to the bin folder as shown below. Meanwhile open a command prompt getting ready to run the esb sever in your machine.






























use the command prompt to navigate to the bin folder which is shown above and then type,

cd C:\Users\Sherihan\Downloads\wso2esb-4.8.0\wso2esb-4.8.0\bin\wso2server.bat

and hit Enter. Or simply drag and drop the wso2server.bat in to the command prompt so that it will paste the complete file to the bat file and then hit Enter.

carefully observe the command line where it stops at a certain point providing you a URL to start the WSO2 esb server in a browser as shown below. 



Copy the url and paste it in a web browser to start the ESB server from an interface. Once it gives you the login page, enter admin as the username and admin as the password and you are ready to run the Wso2 ESB server to do what ever the required task that you wished to do with the ESB server.






Hope It was useful to you. Please leave a comment for any clarification :)

Thursday, November 7, 2013

Parsing XML files in iOS using XPath

Hi all. After a long break I have decided to add another post to my blogger about another interesting post and a technique that found really challenging to me while working on a certain project recently. OK, this time I'm going to explain how I solved a bit of a tough task of parsing an XML file from an iOS Application easily. Keep one thing in your mind that I will not be using 100% of my own code in this post but I will be instructing you to download few header and implementation files to your project in order to perform this task. Also note that you also require a well formatted valid XML file to test your app and ensure that the parsing of XML task is done as you expected.

By the way, let's quickly go through some very simple questions before starting with the code. Try to understand the following and make sure you know the background of what I'm going to perform here.

XML... what's it about?

XML stands for Extensible Markup Language and it is a markup language (everything is marked as a tag) that defines a set of rules for encoding documents in a format that both human-readable and machine-readable. 

Why XML is so popular?

I don't think that anyone in the field of Information Technology will ever tell that they have never heard the word XML since it is so popular because the design goals of XML highlight simplicity, generality and usability over the Internet. XML files are simply text files and no mater of the platform or technology we are using XML can be understood by all of them.

Well Formed Vs Valid XML Documents

A "Well Formed" XML Document has correct XML syntax. For an example, 
  • XML documents must have a root element
  • XML elements have a closing tag
  • XML tags are case sensitive
  • XML elements must be properly nested
  • XML attribute values must be quoted

A "Valid" XML document is a "Well Formed" XML document which is also confirms to the rules of Document Type Definition (DTD)

How to Validate your XML file?

Let's say that you have an XML file with you and you want to validate it to check for it's syntax. you have a number of tools to do this but let's make it simple. Follow the below links to find out how this task can be easily done through online tools within few seconds. All what you have to do is to simply copy paste the content of your XML file or browse your XML file in the given URL and use the validator to check your file.


OK, now let's move to the most interesting part of our post today. As I told you earlier, we need to have a valid and well formed XML file and it is going to be the below shown file.


File content is as below,

<services>
<service name="Service1" url="/utilities/service1.xml">
<type>GET</type>
<parameter-mapping enumvalue="ID">ID</parameter-mapping>
<parameter-mapping enumvalue="NAMEOFDEVICE">DeviceName</parameter-mapping>
<parameter-mapping enumvalue="SERIALOFDEVICE">Serial</parameter-mapping>
<parameter-mapping enumvalue="IPADDRESS">IP_Address</parameter-mapping>
<parameter-mapping enumvalue="STATUS">status</parameter-mapping>
</service>
<service name="Service2" url="/utilities/service2.xml">
<type>POST</type>
<parameter-mapping enumvalue="DEVICEUNIQUEID">UniqueId</parameter-mapping>
<parameter-mapping enumvalue="PASSWORD">password</parameter-mapping>
<parameter-mapping enumvalue="PAIREDDEVICEID">PairedTabletID</parameter-mapping>
<parameter-mapping enumvalue="STATUS">status</parameter-mapping>
</service>
</services>

I have added this xml file to my project resources in the sample XCode project that I've created by just dragging and dropping it to the project file hierarchy as below.


























OK, Now we have simply added the required XML file to our XCode project. Now it's time to get the content of the XML file and start parsing it using our app.

By the way, Do you know how to read an embedded file from an XCode project in Objective-C?


It's simple. Just a matter of adding few lines of code to get the file content to an NSString. Refer the code below.


NSData *configXmlData;
/*
*Function reads the embedded SampleXMLFile.xml file and saves to an instance variable call configXmlData of type NSData
*@return : no data returned
*/

-(void)setConfigurationFile
{
    //reading the resources from the mainBundle of where it search for a file named SampleXMLFile with file extension of xml
  NSString *configXmlFilePath=[[NSBundle mainBundle] pathForResource:@"SampleXMLFile" ofType:@"xml"];

  @try
  {
   //if the file exist, then get the contents of the file to the configXmlData variable 
   if([[NSFileManager defaultManager]fileExistsAtPath:configXmlFilePath])
   {
    configXmlData=[NSData dataWithContentsOfFile:configXmlFilePath];
   }

  }

  //if incase of an error occurs (file doesn't exist or user has no privilege to access it etc ), then print this error message in NSLog
  @catch (NSException *exception)
  {
   NSLog(@"Exception Occurred in reading setConfigurationFile: %@ ",exception);
  }
}


Now Let's turn on the XPath related work now. Keep in mind that I am going to use some files for this purpose that are available in GitHub in the Hppl Project. Use the below shown link to access the Hppl project.

Access Hppl Project From Here

download the project above and add these files to your project.
  • TFHppl.h
  • TFHppl.m
  • TFHpplElement.h
  • TFHpplElement.m
  • XPathQuery.h
  • XPathQuery.m
remember that you need to add reference to these header files from your Xcode project.

What Am I going to do now...

Ok, let's come to the main target of this post. Here's what I am going to do. I hope you have noticed the structure of the above shown XML file. All what I m going to do is to extract the data of that file as I wanted. Let's say I don't need the entire file content always but a part of it is sufficient for me to perform a task as shown below.

When I pass a string called 'Service1' then the app should display the output as below.

url=/utilities/service1.xml
type=GET
ID=ID
NAMEOFDEVICE=DeviceName
SERIALOFDEVICE=Serial
IPADDRESS=IP_Address
STATUS=status

when I pass s string 'Service2' then the app should display the output as below.

url=/utilities/service2.xml
type=POST
DEVICEUNIQUEID=UniqueId
PASSWORD=password
PAIREDDEVICEID=PairedTabletID
STATUS=status

My plan is to write a simple XML parser function to read tags, attributes, elements and values of the XML file accordingly with the help of the methods included in Hppl Project that we have just added to the project. It's really easy and all what you have to pay a little more attention is for the XPath query that you are suppose to write to extract the matching XML elements.
For simplicity, I'll explain you the methods one by one and then you can download the sample app and monitor how things are handled as a whole.

Note that MetaConfigurationHandler is the name of the class that I have and you need to add two more reference for it as below.

#import "TFHpple.h"
#import "Discovery.h"
 
 
/*
*Function creates an NSDictionary containing all the data required for a specific http connection as key value pairs
*@return : an NSDictionary containing the required key value pairs
*/

-(NSDictionary *)generateConfigurationDictionary:(NSString *)request
{
//calls the above mentioned function to read the embedded xml

//file contents to the instance variable configXmlData
  [self setConfigurationFile];

//holds each value for each key of the dictionary
  NSString *valueForKey=nil;

//holds each key of the dictionary
  NSString *key=nil;

//holds the name of the tag
  NSString *tagName=nil;

//holds the xPath query (what matching string we are searching for)
  NSString *xPathQuery=nil;

//holds all the elements of the Services tag
  NSArray *configurationServiceElements=[NSMutableArray array];

//this will be returned as an output containing the aforementioned
//NSMutableDictionary with keys and values respectively
  NSMutableDictionary *configurationDictionary =[NSMutableDictionary dictionary];

@try
{
//xpath query string to search for the children of service tag

//where the service's name= request (here, request is a string
//as Service1 or Service2 that is passed to this function as
//a parameter
  xPathQuery=[NSString stringWithFormat:@"/services/service[@name='%@']",request];

//passing the xPath query, retrieving all the tags that are

//matching with the above xPath query
//configurationServiceElements array will hold elements like url,
//type,ID,NAMEOFDEVICE,SERIALOFDEVICE,IPADDRESS and STATUS

//when request=Service1

  configurationServiceElements=[self getConfigurationElementArray:xPathQuery];

 //valueForKey is going to hold /utilities/service1.xml

//(when request=Service1)
  valueForKey=[[configurationServiceElements objectAtIndex:0] objectForKey:@"url"];

//add value=/utilities/service1.xml where key=url

//(when request=Service1) which
//means configurationDictionary will hold one entry with a key-value pair
  [configurationDictionary setObject:valueForKey forKey:@"url"];

//clear the xPathQuery
  xPathQuery=nil;

//xpath query string to search for the value under the tag named as type and
//which is a sub element od Services/service where service name is equal to
//request
  xPathQuery=[NSString stringWithFormat:@"/services/service[@name='%@']/type",request];

//pass the query to get the value
  configurationServiceElements=[self getConfigurationElementArray:xPathQuery];

//how to get the value of the tag which is type
  valueForKey=[[[configurationServiceElements objectAtIndex:0] firstChild] content];

//add this key value pair to the dictionary,  configurationDictionary
  [configurationDictionary setObject:valueForKey forKey:@"type"];


/*Now, I'm trying to get all the tags under /services/service that are named as
parameter-mapping, then get(element) each of its attribute values and element values to form the key-value pairs for the dictionary as
ID: ID
NAMEOFDEVICE=DeviceName
SERIALOFDEVICE:Serial etc
*/


//first the xPath query search for parameter-mapping elements
//under services/service
  xPathQuery=[NSString stringWithFormat:@"/services/service[@name='%@']/parameter-mapping", request];

//get all those elements that matches the xpath query above to an array
configurationServiceElements=[self getConfigurationElementArray: xPathQuery];
 

//now for each element in the configurationServiceElements array...
  for (TFHppleElement *element in configurationServiceElements)
  {

         //get the name of the tag and assign to tagName variable
     tagName=element.tagName;
       

     //check if that tagName is equal to parameter-mapping
     if[tagName isEqualToString:@"parameter-mapping"])

     //if true, assign it to key          
      key=element.tagName;

     //get the attribute of parameter-mapping which is enumvalue and
     //make it a key
     key=[element objectForKey:@"enumvalue"];


          //get the value of the attribute named key (which means enumvalue)and
     //assign it to valueForKey
     valueForKey=[[element firstChild]content];
     

     //now add those key-value pair to the configurationDictionary as
     //another entry 
     [configurationDictionary setObject:valueForKey forKey:key];          
  }
}

  //if incase an exception occurs then handle it by printing the exception
  //in NSLog
  @catch (NSException *exception)
  {
    NSLog(@"Exception Occurred in generateConfigurationDictionary:%@ ",exception);  
  }

 //finally, return the configurationDictionary NDmutableDictionary
  @finally
  {
    return configurationDictionary;
  }

}
 

/*
*Function executes an xpath query and returns the matching nodes as an NSArray to the callee
*@xPathQuery : xpath query as a string should be passed
*@return : an NSArray containing the matching elements will be returned
*/

-(NSArray *)getConfigurationElementArray:(NSString *)xPathQuery
{
  NSArray *servicesNodes;
  TFHpple *servicesParser = [TFHpple hppleWithXMLData:configXmlData];
  NSString *servicesXpathQueryString = xPathQuery;               
  servicesNodes = [servicesParser searchWithXPathQuery:servicesXpathQueryString];
  return servicesNodes;
}


Now, the most required or I would rather say most difficult part of our XML parsing is done. All what you have to do is to make relevant function calls passing proper parameters to get the output as you want.


for an example, I can call the parser functions as shown below. Assume that I am going to call these functions from another class

MetaConfigurationHandler *meta=[[MetaConfigurationHandler alloc]init];

NSDictionary  *configDic=[NSDictionary  dictionary];

*configDic=[meta generateConfigurationDictionary:@"Service1"];


Now you can simply print the configDic contents in NSLog or as you preferred. 

Hope this post was interesting to you guys  :)

Further reading :

http://www.w3schools.com/xml/default.asp
http://www.raywenderlich.com/14172/how-to-parse-html-on-ios

Saturday, August 17, 2013

An Image processing application in IOS


Hello all , I thought to write an interesting post in IOS this time. It’s going to be a colorful application J No suspense…All what I’m going to explain here is about an image processing application in IOS. We all know what image processing means. Image processing is any form of signal processing for which the input is an image, such as a photograph or a set of characteristics or parameters related to the image.

I have been working on finding techniques to perform few takes with an image that is been selected from a UIImagePickerController . So, what I’m going to explain here describes the below tasks which I have already figured out how to achieve.
  • How to pop up the UIImagePickerController in an iphone to select an image
  • How to convert a UIImage to Grayscale
  • How to convert a UIImage to Black and White
  • How to resize a UIImage
  • How to check whether a UIImage is black and white or not

  • How to convert an image to Hexadecimal string

The application that I designed consists of a single view with two UIImageViews, each to display the image before processing and after processing. And I have a collection of buttons where each one will perform the image process and display the resulting image in the second UIImageView.

Following is the simple screen that I have created to perform all the above mentioned tasks. And please make sure that you have enough photos in you device or simulator’s photo library to test the functions correctly working. I recommend having images with different file extensions (.bmp, jpeg, png etc), sizes and colors.


#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
<UIApplicationDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate,UIPopoverControllerDelegate>
{
    IBOutlet UITextField *getHeight;
    IBOutlet UITextField *getWidth;
    IBOutlet UIImageView *imageDisplay;
    IBOutlet UIImageView *resultImageView;
    IBOutlet UIButton *resizeImageBtn;
    IBOutlet UIButton *convertGrayScaleBtn;
    IBOutlet UIButton *convertBlackNWhiteBtn;
    IBOutlet UIButton *convertMonoChromeBtn;
    IBOutlet UIButton *selectImageBtn;
    IBOutlet UIButton *convertToHex;
    IBOutlet UIButton *convertToBase64;
    UIImagePickerController *ipc;
    UIPopoverController *popoverController;
    UIImage *sourceImage;
    UIAlertView *alert;
}

@property (nonatomic,retain)UITextField *getHeight;
@property (nonatomic,retain)UITextField *getWidth;
@property (nonatomic,retain)UIImageView *imageDisplay;
@property (nonatomic,retain)UIImageView *resultImageView;
@property (nonatomic,retain)UIButton *resizeImageBtn;
@property (nonatomic,retain)UIButton *convertGrayScaleBtn;
@property (nonatomic,retain)UIButton *convertBlackNWhiteBtn;
@property (nonatomic,retain)UIButton *convertMonoChromeBtn;
@property (nonatomic,retain)UIButton *selectImageBtn;
@property (nonatomic,retain)UIButton *convertToHex;
@property (nonatomic,retain)UIButton *convertToBase64;
@property (nonatomic, retain) UIPopoverController *popoverController;
@property (nonatomic, retain) UIImagePickerController *ipc;
@property (nonatomic, retain) UIImage *sourceImage;
@property (nonatomic, retain) UIAlertView *alert;

-(IBAction) resize:(id)sender;
-(IBAction) convertGrayScale:(id)sender;
-(IBAction) convertBlackNWhite:(id)sender;
-(IBAction) checkBlackAndWhite:(id)sender;
-(IBAction) selectImage:(id)sender;
-(IBAction) convertImageToHex:(id)sender;
-(IBAction) convertToBaseSixtyFour:(id)sender;

@end

and do not forget to put the below section in your implementation file. 

@synthesize getHeight,getWidth,imageDisplay,resizeImageBtn,convertBlackNWhiteBtn,convertGrayScaleBtn,convertMonoChromeBtn,resultImageView,popoverController,ipc,sourceImage,selectImageBtn,alert,convertToHex,convertToBase64;

By the way, do you know how to add images to the photo library in a simulator?

It’s very simple. Keep few images in a folder and run the ios simulator in a side of the screen. You can be in any screen in the simulator. Drag and drop the images that you have (one at a time) on to the simulator’s screen. The image will be displayed on the screen. Click and hold the , mouse on the image for about a second where a popup will ask you whether you need to save the image. Select “Save Image” option where the selected image will be made available in your Photo Library from that point onwards.

I don’t think that I should explain you on how to create a view based an xcode project and create an interface as simple as above. If not sure, you can refer my previous blogs under the ios category. OK, following is my header file content. By the name means of the variables, it’s easy for you to understand what they are used for.

So, do not forget to bind the controls (the UIButtons and UIImageViews) with their declared variables and methods. I hope you can simply do that. Ok, let’s start the work now. For making the post simple for you to refer, I have made it a collection of posts, so, all what you have to do is simply click on the above links to know about the implementation of the task that you want to achieve.

How to convert an image to Hexadecimal string?

Please do follow this post along with the post here

Recently I had to face a problem in sending a user selected image in an ios application, to a printer where the printer only identifies hex strings. After days of struggle, finally I came up with a solution by following an existing algorithm in some other language to do the same task in my ios application.

If someone faced the same situation as me, don't worry even to copy my code and proceed with your work without being stuck for few days :)

-(IBAction) convertImageToHex:(id)sender
{
    UIImage *srcImg=[imageDisplay image];//imageDisplay is the UIImageView that I currently display the user selected image from the Photo Library
    NSString *hexOutput=[self convertUIImageToHex:srcImg];
    NSLog(@"%@",hexOutput);
}

//this function will accept a UIImage and convert it to the Hexa Decimal String
-(NSString *)convertUIImageToHex:(UIImage *)uiImage
{
    NSMutableString *writeString=[[NSMutableString alloc]init];
    NSMutableString *trimmedString=[[NSMutableString alloc]init];
    // First get the image into your data buffer
    CGImageRef imageRef = [uiImage CGImage];
    NSUInteger width = CGImageGetWidth(imageRef);
    NSUInteger height = CGImageGetHeight(imageRef);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                                 bitsPerComponent, bytesPerRow, colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    CGContextRelease(context);

    NSUInteger xOfImage;
    NSUInteger yOfImage;

    int wp=0;

    @try
    {
        for(xOfImage=0;xOfImage <= width-1 ; xOfImage++)
        {
            for(yOfImage=0;yOfImage<=height-1;yOfImage++)
            {
                int byteIndex = (bytesPerRow * yOfImage) + xOfImage * bytesPerPixel;
                
                char green = rawData[byteIndex + 1];

                byteIndex += 4;
                
                if ((yOfImage % 8) == 0)
                {
                    wp = 0;
                    wp = (green!=0) ? 0 : 1;
                }
                else if ((yOfImage % 8) == 7)
                {
                    wp = (wp << 1) | ((green!=0) ? 0 : 1);
                    [writeString appendString:[NSMutableString stringWithFormat:@"%%%02X",wp]];  
                }
                else
                {
                    wp = (wp << 1) | ((green!=0) ? 0 : 1);
                }    
            }      
        }
    }
    
    @catch (NSException *exception)
    {
        NSLog(@"%@",exception);      
    }
    @finally
    {
        NSString *formattedString=[[[NSString alloc]initWithFormat:@"%@",writeString] lowercaseString]    
        return formattedString;
    }

}


Ok, now let's say we Input a UIImage and successfully converted it to Hex string... As I have done above, It will simply display the output in the NSLog. But, how do you know that your output is correct?

Yes, It was a bit problem to me too. But as I said above, I used an existing hexconverison algorithm in some other language and I had the converted hex string of a specific image saved in a text file via that program. So, what I did was, downloaded a simple bitmap image from the web and let that program convert te image to hex. then i got a copy of the resulting hex string value stored text file-->1

then I came back to my IOS application, added the same bitmap image to my photo library and let my app convert it to hex as well. Since the output is in the Log, I copied it to another text file and had it with me -->2

finally what I did was, comparing both of the files that they are identical. Of Course they were identical?

Ok, now you would ask, how I compared them? going through line by line? :) of course NO

you can get this tool called DiffMerge from the following link. It helps you with that process...


How to check whether a UIImage is black and white or not?


Please do follow this post along with the post here

In one of my previous posts, I described on how I convert an image to black and white and grayscale as well. Here, I'm going to explain on how to check an image is black and white or not.

//checking whether the image is a black and white one or not
-(IBAction) checkBlackAndWhite:(id)sender
{
//sourceImage  is the user selected image from the Image Picker. I simply display it on a UIImageView and for the processing  i get the image that is currently viewed in the UIImageView
    BOOL blackNWhite=[self imageIsBlackAndWhite:sourceImage];
    
    if(sourceImage==nil)
    {
        NSLog(@"Image Not selected");
        
        alert=[[UIAlertView alloc] initWithTitle:@"Image Process" message:@"Image Not selected" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
        [alert show];
    }
    
    else
    {    
        if(blackNWhite==YES)
        {
            NSLog(@"Image is Black and White");
            
            alert=[[UIAlertView alloc] initWithTitle:@"Image Process" message:@"Image is Black and White" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
            [alert show];
        }
        
        else
        {
            NSLog(@"Image is not Black and White");
            
            alert=[[UIAlertView alloc] initWithTitle:@"Image Process" message:@"Image is not Black and White" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
            [alert show];
        }
    }
}

//method will check whther a selected image is a black and white image or not
-(BOOL)imageIsBlackAndWhite:(UIImage *)image
{
    BOOL isBlackNWhite=NO;

    // load image
    CGImageRef imageRef = image.CGImage;
    CFDataRef cfData = CGDataProviderCopyData(CGImageGetDataProvider(imageRef));
    NSData * data = (__bridge NSData *) cfData;
    char *pixels = (char *)[data bytes];
    
    const int threshold = 10; //define a gray threshold
    
    for(int i = 0; i < [data length]; i += 4)
    {
        Byte red = pixels[i];
        Byte green = pixels[i+1];
        Byte blue = pixels[i+2];
        
        //check if a single channel is too far from the average value.
        //greys have RGB values very close to each other
        int average = (red+green+blue)/3;
        
        if( abs(average - red) >= threshold ||abs(average - green) >= threshold ||abs(average - blue) >= threshold )
        { 
            isBlackNWhite=NO;
        }
        
        else
        {
            isBlackNWhite=YES;
        }
    }
    CFRelease(cfData);
    return isBlackNWhite;
}





How to convert a UIImage to Black and White?


Please do follow this post along with the post here

//this button click even twill call the convertToBlackNWhite() method to sart the color conversion to black and white
 -(IBAction) convertBlackNWhite:(id)sender

{    
    if(sourceImage==nil) //sourceImage  is the user selected image from the Image Picker. I simply display it on a UIImageView and for the processing  i get the image that is currently viewed in the UIImageView
    {
        NSLog(@"Image Not selected");
    }
    
    else
    {    
        UIImage *blackAndWhiteImage=[self convertToBlackNWhite:sourceImage];
        resultImageView.image=blackAndWhiteImage;
    }
}

//method is used to convert an image to its black and white image and view in the UIImageView on te screen
-(UIImage *)convertToBlackNWhite:(UIImage *)initialImage

{
    /*
     approach:- threshold
     get the UIImage and convert it to take the bitmap image of it.
     check each pixal whether it is higher than a certain value. if yes->make it white else black
     */
    unsigned char *bitmap = [self convertUIImageToBitmapRGBA8:initialImage];
    
    for (int i=0;i<initialImage.size.width * initialImage.size.height * 4; i+=4)
    {
        if ((bitmap[i] + bitmap[i + 1] + bitmap[i + 2]) < (255 * 3 / 2))
        {
            bitmap[i ] = 0;
            bitmap[i + 1] = 0;
            bitmap[i + 2] = 0;
        }
        else
        {
            bitmap[i ] = 255;
            bitmap[i + 1] = 255;
            bitmap[i + 2] = 255;
        }
    }
    
    initialImage = [self convertBitmapRGBA8ToUIImage:bitmap withWidth:initialImage.size.width withHeight:initialImage.size.height];
    
    return initialImage;
    
}

//PLEASE FIND THE BELOW CONVERSION METHODS FROM HERE
//https://gist.github.com/PaulSolt/739132

-(UIImage *) convertBitmapRGBA8ToUIImage:(unsigned char *) buffer withWidth:(int) width withHeight:(int) height
{
size_t bufferLength = width * height * 4;
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, bufferLength, NULL);
size_t bitsPerComponent = 8;
size_t bitsPerPixel = 32;
size_t bytesPerRow = 4 * width;
    
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    
if(colorSpaceRef == NULL)
    {
NSLog(@"Error allocating color space");
CGDataProviderRelease(provider);
return nil;
}
    
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
    
CGImageRef iref = CGImageCreate(width,
height,
bitsPerComponent,
bitsPerPixel,
bytesPerRow,
colorSpaceRef,
bitmapInfo,
provider, // data provider
NULL, // decode
YES, // should interpolate
renderingIntent);
    
uint32_t* pixels = (uint32_t*)malloc(bufferLength);
    
if(pixels == NULL)
    {
NSLog(@"Error: Memory not allocated for bitmap");
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpaceRef);
CGImageRelease(iref);
return nil;
}
    
CGContextRef context = CGBitmapContextCreate(pixels, width, height, bitsPerComponent, bytesPerRow, colorSpaceRef, bitmapInfo);
if(context == NULL)
    {
NSLog(@"Error context not created");
free(pixels);
}
    
UIImage *image = nil;
    
if(context)
    {        
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), iref);        
CGImageRef imageRef = CGBitmapContextCreateImage(context);
        
// Support both iPad 3.2 and iPhone 4 Retina displays with the correct scale
if([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) {
float scale = [[UIScreen mainScreen] scale];
image = [UIImage imageWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp];

               else 
                {
image = [UIImage imageWithCGImage:imageRef];
}
        
CGImageRelease(imageRef);
CGContextRelease(context);
}
    
CGColorSpaceRelease(colorSpaceRef);
CGImageRelease(iref);
CGDataProviderRelease(provider);
    
if(pixels) {
free(pixels);
}
    
return image;
}

-(unsigned char *) convertUIImageToBitmapRGBA8:(UIImage *) image
{
CGImageRef imageRef = image.CGImage;
    
//Create a bitmap context to draw the uiimage into
CGContextRef context = [self newBitmapRGBA8ContextFromImage:imageRef];
    
if(!context)
    {
return NULL;
}
    
size_t width = CGImageGetWidth(imageRef);
size_t height = CGImageGetHeight(imageRef);
    
CGRect rect = CGRectMake(0, 0, width, height);
    
// Draw image into the context to get the raw image data
CGContextDrawImage(context, rect, imageRef);
    
// Get a pointer to the data
unsigned char *bitmapData = (unsigned char *)CGBitmapContextGetData(context);
    
// Copy the data and release the memory (return memory allocated with new)
size_t bytesPerRow = CGBitmapContextGetBytesPerRow(context);
size_t bufferLength = bytesPerRow * height;
    
unsigned char *newBitmap = NULL;
    
if(bitmapData)
    {
newBitmap = (unsigned char *)malloc(sizeof(unsigned char) * bytesPerRow * height);
        
if(newBitmap)
        { // Copy the data
for(int i = 0; i < bufferLength; ++i)
            {
newBitmap[i] = bitmapData[i];
}
}
        
free(bitmapData);
}
    
    else
    {
NSLog(@"Error getting bitmap pixel data\n");
    }
    
CGContextRelease(context);    
return newBitmap;
}

-(CGContextRef) newBitmapRGBA8ContextFromImage:(CGImageRef) image
{
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
uint32_t *bitmapData;
    
size_t bitsPerPixel = 32;
size_t bitsPerComponent = 8;
size_t bytesPerPixel = bitsPerPixel / bitsPerComponent;
    
size_t width = CGImageGetWidth(image);
size_t height = CGImageGetHeight(image);
    
size_t bytesPerRow = width * bytesPerPixel;
size_t bufferLength = bytesPerRow * height;
    
colorSpace = CGColorSpaceCreateDeviceRGB();
    
if(!colorSpace)
    {
NSLog(@"Error allocating color space RGB\n");
return NULL;
}
    
// Allocate memory for image data
bitmapData = (uint32_t *)malloc(bufferLength);
    
if(!bitmapData)
    {
NSLog(@"Error allocating memory for bitmap\n");
CGColorSpaceRelease(colorSpace);
return NULL;
}
    
//Create bitmap context
context = CGBitmapContextCreate(bitmapData, width,height,bitsPerComponent,bytesPerRow,colorSpace,
                                    kCGImageAlphaPremultipliedLast); // RGBA
    
if(!context)
    {
free(bitmapData);
NSLog(@"Bitmap context not created");
    }   
CGColorSpaceRelease(colorSpace);    
return context;
}