Saturday, August 17, 2013

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