This is ImageReader.m in view mode; [Download] [Up]
/* ImageReader.m * Purpose: The application delegate. This class reads in and saves out EPS * and TIFF images. * * You may freely copy, distribute, and reuse the code in this example. * NeXT disclaims any warranty of any kind, expressed or implied, as to its fitness * for any particular use. * */ #import <math.h> #import <strings.h> #import <dpsclient/wraps.h> #import <appkit/graphics.h> #import <appkit/OpenPanel.h> #import <appkit/SavePanel.h> #import <appkit/NXImage.h> #import <appkit/Application.h> #import <appkit/Menu.h> #import <appkit/MenuCell.h> #import <appkit/Matrix.h> #import <appkit/TextField.h> #import <appkit/NXBitmapImageRep.h> #import <appkit/Control.h> #import <appkit/publicWraps.h> #import <appkit/tiff.h> #import "ImageReader.h" #import "ImageView.h" @implementation ImageReader : Object /* -windowWillClose: * Window delegate method. Called before a window is about to be * closed. If the last window is being closed, dim the "Save Image..." * menu item. */ - windowWillClose:sender { int cnt; id menu = [NXApp mainMenu]; id matrix = [menu itemList]; id menuCell = [matrix cellAt: 1:0]; /* Location of the "Save..." menu item */ /* The minimum window count for this app is 2 when there */ /* are no open TIFF/EPS windows -- if 3 or more windows are */ /* open, then the "Save Image..." menu item should be enabled. */ NXCountWindows(&cnt); if (cnt <= 3) [menuCell setEnabled: NO]; return self; } /* -windowDidBecomeMain: * Window delegate method. Called after the window has become main. * The theory being if any main windows exist, then enable the "Save Image..." * menu item. */ - windowDidBecomeMain:sender { id menu = [NXApp mainMenu]; id matrix = [menu itemList]; id menuCell = [matrix cellAt: 1:0]; [menuCell setEnabled:YES]; return self; } /* -appDidInit: * Application delegate method. Called after application has been initialized * and before any events are received. */ - appDidInit:sender { /* Ensure that a required file type has been set for the */ /* save panel. Also initializes the save panel instance */ /* variable */ saveReq = [SavePanel new]; [saveReq setRequiredFileType: tiffType]; /* The default TIFF compression is LZW. Disable JPEG */ /* factor text field. */ [JPEGvalue setEnabled:NO]; return self; } /* - openRequest: * Called when the user selects "Open Image..." from the menu. Both EPS * and TIFF images are supported. */ - openRequest:sender { id openReq; const char *fileName; const char *const fileTypes[] = {tiffType, epsType, NULL}; openReq = [OpenPanel new]; if ([openReq runModalForTypes:fileTypes] && (fileName =[openReq filename])) { [self openFile:fileName]; } return self; } /* -openFile: * Does the work of creating a window exactly the size of the image [tiff or eps]. * Then creates an instance of ImageView and replaces the contentView of the * window with the ImageView instance. */ -(BOOL) openFile:(const char *)fileName { id anImage, window, view; NXRect rect; char title[100], *name; /* Read in the EPS or TIFF image */ anImage = [[NXImage alloc] initFromFile:fileName]; if ([anImage lastRepresentation] == nil) return NO; /* We will be scaling this image */ [anImage setScalable: YES]; /* Create an instance of ImageView */ if ((view = [[ImageView alloc] initFromImage: anImage]) == nil) return NO; /* Create a new window the size of the image */ [view getFrame:&rect]; window = [[Window alloc] initContent:&rect style:NX_TITLEDSTYLE backing:NX_RETAINED buttonMask:NX_CLOSEBUTTONMASK defer:NO]; /* Set the window delegate */ [window setDelegate:self]; /* Replace the current contentView of the window with my new view */ /* and free up the old contentView */ [[window setContentView:view] free]; [window center]; /* Put the window in the center of the screen */ /* Set the title of the window to be the title of the file */ name = rindex(fileName, '/'); sprintf (title, "%s", name ? name+1 : fileName); [window setTitle:title]; [window makeKeyAndOrderFront:self]; [window display]; return YES; } /* selectFormat: * This method is called when the user selects a button in the formatMatrix. * It dims or brightens other panel items, as appropriate. For example, if saving * an image as EPS, the DPI matrix needs to be dimmed as it is not applicable. */ - selectFormat:sender { switch ([formatMatrix selectedCol]) { case TIFF_FORMAT: [DPIpopup setEnabled:YES]; [DPIvalue setEnabled:YES]; [compressionType setEnabled:YES]; [saveReq setRequiredFileType: tiffType]; [self selectCompression: nil]; break; case EPS_FORMAT: [DPIpopup setEnabled:NO]; [DPIvalue setEnabled:NO]; [compressionType setEnabled:NO]; [saveReq setRequiredFileType: epsType]; [JPEGlabel setTextGray: NX_DKGRAY]; [JPEGvalue setEnabled:NO]; break; } return self; } /* selectCompression: * This method is called when the user selects a button in the * compressionType matrix. It dims or brightens the JPEG value * field, as appropriate. */ - selectCompression:sender { switch ([compressionType selectedCol]) { case LZW_COMPRESSION: [JPEGlabel setTextGray: NX_DKGRAY]; [JPEGvalue setEnabled:NO]; break; case JPEG_COMPRESSION: [JPEGlabel setTextGray: NX_BLACK]; [JPEGvalue setEnabled:YES]; break; } return self; } /* -saveRequest: * This method is called when the user selects "Save Image..." from the menu. * An accessory view is installed in the save panel which allows the user to specify * saving the image as either EPS or TIFF. In the case of TIFF, the user must * provide a DPI value. */ - saveRequest:sender { id window; const char *fileName, *title; char name[100], *extension; int cnt; window = [NXApp keyWindow]; /* can't save anything if no windows are available */ if (window == nil) return self; title = [window title]; /* Yank off the extension */ extension = index(title, '.'); cnt = (int)extension-(int)title; strncpy(name, title, cnt); name[cnt] = '\0'; /* * Insert my accessory view into the save panel. * This view allows [forces] the user to select either EPS or TIFF when * saving the image. If the image is to be saved as TIFF, the user must * supply a DPI value -- the default resolution is 72DPI. */ if ([saveReq accessoryView] == nil) [saveReq setAccessoryView: [accessoryWindow contentView]]; if ([saveReq runModalForDirectory: "." file: name] && (fileName =[saveReq filename])) { switch ([formatMatrix selectedCol]) { case TIFF_FORMAT: [self saveTIFF:fileName inWindow: window]; break; case EPS_FORMAT: [self saveEPS:fileName inWindow: window]; break; } } return self; } /* -saveTIFF: inWindow: * This method saves a specified view to disk with the specified * fileName using the TIFF format. An instance of NXBitmapImageRep * is created with the desired resolution, then written to a stream and * then to disk using LZW compression. The instance of NXBitmapImageRep * is then freed. */ - (BOOL)saveTIFF: (const char *)fileName inWindow: window { id tiffImage, theImage; NXSize origSize, newSize; NXRect rect; int DPI; BOOL error = NO; NXStream *s; float factor; char *dpiInput; /* Get the original size and squirrel that away. */ /* We'll be changing the size to reflect the desired DPI of the TIFF file */ /* and then image it at that resolution. */ theImage = [[window contentView] image]; [theImage getSize:&origSize]; dpiInput = (char *)[DPIpopup title]; sscanf(dpiInput,"%d",&DPI); newSize.width = origSize.width * (float)DPI/ POINTSPERINCH; newSize.height = origSize.height * (float)DPI/ POINTSPERINCH; [theImage setSize: &newSize]; /* Create a tiff image at the desired size */ [theImage lockFocus]; rect.origin.x = rect.origin.y = 0.0; rect.size = newSize; tiffImage = [[NXBitmapImageRep alloc] initData: NULL fromRect: &rect]; [theImage unlockFocus]; [theImage setSize: &origSize]; [tiffImage setSize: &origSize]; if (!tiffImage) return NO; s = NXOpenMemory (NULL, 0, NX_READWRITE); if (s) { switch ([compressionType selectedCol]) { case LZW_COMPRESSION: [tiffImage writeTIFF:s usingCompression:NX_TIFF_COMPRESSION_LZW]; break; case JPEG_COMPRESSION: if ([tiffImage bitsPerSample] < 4) { NXRunAlertPanel("TIFFandEPS Save Error", "JPEG compression requires 4 or 8 bits per sample for grayscale or RGB", NULL, NULL, NULL); error = YES; break; } factor = [JPEGvalue floatValue]; if (factor < 1.0) factor = 1.0; if (factor > 255.0) factor = 255.0; [tiffImage writeTIFF:s usingCompression:NX_TIFF_COMPRESSION_JPEG andFactor: factor]; break; } NXFlush (s); if (!error) { if (NXSaveToFile (s, fileName)) { error = YES; perror (fileName); } } NXCloseMemory (s, NX_FREEBUFFER); } else error = YES; [tiffImage free]; return (error ? NO : YES); } /* -saveEPS: inWindow: * This method saves a specified view to disk with the specified * fileName using the EPS format. To do this the copyPSCode * method of view is used on the view with the result going to a stream * and then to disk. */ - (BOOL)saveEPS: (const char *)fileName inWindow: window { NXRect rect; BOOL error = NO; NXStream *s; s = NXOpenMemory(NULL, 0, NX_WRITEONLY); if (s) { [[window contentView] getFrame:&rect]; [[window contentView] copyPSCodeInside:&rect to:s]; NXFlush(s); if (NXSaveToFile (s, fileName)) { error = YES; perror (fileName); } NXCloseMemory(s, NX_FREEBUFFER); } else error = YES; return (error? NO : YES); } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.