// // NSImageToRimage.m // AUCoderDemo // // Created by Andrew Salamon on 5/31/06. // Copyright (c) 2006 Machine Perception Laboratory // University of California San Diego.// #import "NSImageToRimage.h" #ifdef USE_IMAGEMAGICK #import #endif /// divide image values by this to normalize (usually 255.0 or 1.0) static const float norm = 255.0; @implementation NSImage(CERTMethods) + (NSImage *)imageFromRImage:(RImage *)rimage { NSImage *newImage = NULL; unsigned char *planes[1]; planes[0] = (unsigned char *)rimage->array; NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:rimage->width pixelsHigh:rimage->height bitsPerSample:8 samplesPerPixel:3 hasAlpha:NO isPlanar:NO colorSpaceName:NSCalibratedRGBColorSpace bitmapFormat:(NSBitmapFormat)0 bytesPerRow:0 bitsPerPixel:0]; if( rep ) { if( YES ) { for( unsigned int row=0; row < [rep pixelsHigh]; ++row ) { // unsigned int i = row * [imageRep bytesPerRow]; for( unsigned int col=0; col < [rep pixelsWide]; ++col ) { unsigned int pvalues[3]; unsigned char rgb = (unsigned char)(rimage->getPixel( col, row ) * norm); pvalues[0] = rgb; pvalues[1] = rgb; pvalues[2] = rgb; [rep setPixel:pvalues atX:col y:row]; } } } else { unsigned char *data = [rep bitmapData]; int pixelCnt = rimage->width * rimage->height; for( int i=0, repi=0; i < pixelCnt; ++i ) { unsigned char rgb = (unsigned char)(rimage->array[i] * norm); data[repi++] = rgb; data[repi++] = rgb; data[repi++] = rgb; } } newImage = [[NSImage alloc] initWithSize:NSMakeSize(rimage->width,rimage->height)]; [newImage addRepresentation:rep]; [rep release]; } return [newImage autorelease]; } - (NSBitmapImageRep *)bitmapImageRep { NSArray *reps = [self representations]; NSEnumerator *repEnum = [reps objectEnumerator]; NSBitmapImageRep *imageRep = NULL; while( (imageRep = [repEnum nextObject]) && ![imageRep isKindOfClass:[NSBitmapImageRep class]] ) { } return imageRep; } - (RImage *)rimageRep { NSBitmapImageRep *imageRep = [self bitmapImageRep]; if( !imageRep ) { return NULL; } NSSize size = [imageRep size]; unsigned char *data = [imageRep bitmapData]; if( [imageRep numberOfPlanes] != 1 ) { NSLog( @"Planar image type, can't handle it, yet" ); return NULL; } RImage *rimage = new RImage( (int)size.width, (int)size.height ); NSAssert( size.width == rimage->width, @"Bad width in RImage" ); NSAssert( size.height == rimage->height, @"Bad height in RImage" ); unsigned int byteCount = [imageRep pixelsWide] * [imageRep pixelsHigh] * [imageRep samplesPerPixel]; // unsigned int pixel = 0; BOOL alphaFirst = [imageRep hasAlpha] && ([imageRep bitmapFormat] & NSAlphaFirstBitmapFormat); unsigned int inc = [imageRep samplesPerPixel]; // [imageRep hasAlpha]?4:3; //NSLog( @"Row byte padding: %d", [imageRep bytesPerRow] - ([imageRep pixelsWide] * [imageRep samplesPerPixel]) ); if( YES || ([imageRep bytesPerRow] != ([imageRep pixelsWide] * [imageRep samplesPerPixel])) ) { for( unsigned int row=0; row < [imageRep pixelsHigh]; ++row ) { // unsigned int i = row * [imageRep bytesPerRow]; for( unsigned int col=0; col < [imageRep pixelsWide]; ++col ) { // unsigned int tmpi = i + (col * inc); // if( alphaFirst ) // ++tmpi; // int r = data[tmpi]; // int g = data[tmpi+1]; // int b = data[tmpi+2]; // int theGrayValue = 0; unsigned int pixValues[inc]; [imageRep getPixel:pixValues atX:col y:row]; if( inc == 1 ) { theGrayValue = pixValues[0]; } else { unsigned int tmpi = 0; if( alphaFirst ) ++tmpi; int r = pixValues[tmpi]; int g = pixValues[tmpi+1]; int b = pixValues[tmpi+2]; theGrayValue = ((306 * (r & 0xff)) + (601 * (g & 0xff)) + (117 * (b & 0xff))) >> 10; } // float pixVal2 = theGrayValue / 255.0; float pixVal2 = theGrayValue / norm; // float pixVal = (data[i] + data[i+1] + data[i+2]) / 3.0; // pixVal /= 255.0; //rimage->setPixel( pixel++, pixVal2 ); NSAssert( (pixVal2 <= 1.0), @"Pixel value is greater than 1.0 but shouldn't be." ); rimage->setPixel( col, row, pixVal2 ); } } } else { for( unsigned int i=0; i < byteCount; i+=inc ) { unsigned int tmpi = i; if( alphaFirst ) ++tmpi; int r = data[tmpi]; int g = data[tmpi+1]; int b = data[tmpi+2]; int theGrayValue = ((306 * (r & 0xff)) + (601 * (g & 0xff)) + (117 * (b & 0xff))) >> 10; float pixVal2 = theGrayValue / norm; // float pixVal = (data[i] + data[i+1] + data[i+2]) / 3.0; // pixVal /= 255.0; rimage->setPixel( pixel++, pixVal2 ); } } return rimage; } #ifdef USE_IMAGEMAGICK - (RImage *)rimageFromImageMagick { using namespace Magick; NSBitmapImageRep *imageRep = [self bitmapImageRep]; if( !imageRep ) { return NULL; } NSDictionary *properties = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithFloat:1.0], NSImageCompressionFactor, NULL]; NSData *bitmapData = [imageRep representationUsingType:NSJPEGFileType properties:properties]; Blob blob( [bitmapData bytes], [bitmapData length] ); Image image( blob ); if (image.columns() == 0 && image.rows() == 0) { // NSLog( @"Image contains 0 rows and 0 columns!" ); return NULL; } RImage *pixels = new RImage( image.columns(), image.rows() ); // image.quantizeColors(256); // convert to 256 colors image.quantize(); // convert to grayscale image.write(0,0, image.columns(), image.rows(), "I", FloatPixel, pixels->array); return pixels; } #endif @end