Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

slooksterPSV

macrumors 68040
Original poster
Apr 17, 2004
3,543
305
Nowheresville
I have an NSView subclass called StretchView. Here's what I want to do:
Since the StretchView has scrollbars and is extended via those scrollbars I want to be able to grab the entire StretchView (including the area not visible on screen) and save that to a file.

Now here's what I've been able to do:
I've been able to grab the frame of the StretchView and save it as a JPEG. But i want the entire view (even the parts that are not visible). E.g.:

I have a box like this: and the visible data is represented by V and the invisible data is represented by D:

DDDDDDDDDDDDDDDD
DD_______________DD
DD|VVVVVVVVVVVV|DD
DD|VVVVVVVVVVVV|DD
DD|VVVVVVVVVVVV|DD
DD|VVVVVVVVVVVV|DD
DD|VVVVVVVVVVVV|DD
DD|VVVVVVVVVVVV|DD
DD--------------------DD
DDDDDDDDDDDDDDDD

I want to grab the visible data (V) along with the hidden data (D) and save it as a JPEG.
 

Attachments

  • Picture 1.jpg
    Picture 1.jpg
    106.5 KB · Views: 271

HiRez

macrumors 603
Jan 6, 2004
6,250
2,576
Western US
How are you currently getting the data? You didn't say. Are you using NSView's dataWithPDFInsideRect: method (using the view's full bounds as the rect), and passing that to NSImage?
 

slooksterPSV

macrumors 68040
Original poster
Apr 17, 2004
3,543
305
Nowheresville
HiRez said:
How are you currently getting the data? You didn't say. Are you using NSView's dataWithPDFInsideRect: method (using the view's full bounds as the rect), and passing that to NSImage?
Uhh... here's my classes, you decide from there... uh yeah..

Code:
//AppController.h
/* AppController */

#import <Cocoa/Cocoa.h>
@class StretchView;

@interface AppController : NSObject
{
    IBOutlet NSSlider *slider;
    IBOutlet StretchView *stretchView;
}
- (IBAction)fade:(id)sender;
- (IBAction)open:(id)sender;
- (IBAction)save:(id)sender;
@end

Code:
//AppController.m
#import "AppController.h"
#import "StretchView.h"

@implementation AppController

- (void)awakeFromNib
{
	//Make sure the slider and the stretch view
	//agree on the initial opacity
	[slider setFloatValue:0.5];
	[stretchView setOpacity:0.5];
}

- (IBAction)fade:(id)sender
{
	//The sender is the slider
	[stretchView setOpacity:[sender floatValue]];
}

- (void)openPanelDidEnd:(NSOpenPanel *)openPanel returnCode:(int)returnCode contextInfo:(void *)x
{
	NSString *path;
	NSImage *image;
	
	//Did they choose open?
	if(returnCode == NSOKButton) {
		path = [openPanel filename];
		image = [[NSImage alloc] initWithContentsOfFile:path];
		//image = [NSKeyedUnarchiver unarchiveObjectWithFile: path];
		[stretchView setImage:image];
		[image release];
	}
}

- (void)savePanelDidEnd:(NSOpenPanel *)savePanel returnCode:(int)returnCode contextInfo:(void *)x
{
	NSString *path, *fullpath;
	//NSData *tiff_data = [[NSdata alloc] initWithData: [ 
	
	if(returnCode == NSOKButton) {
		fullpath = [savePanel filename];
		path = fullpath;
		NSLog(@"Path Extension: %@", [fullpath pathExtension]);
		if([[path pathExtension] length] ==  0)
		{
			NSLog(@"This is fake");
			path = [fullpath stringByAppendingPathExtension: @"jpeg"];
		}
		[stretchView display];
		
		[stretchView lockFocus];

		NSBitmapImageRep *bits;
		bits = [[NSBitmapImageRep alloc]
           initWithFocusedViewRect:[stretchView frame]];
		   
		[stretchView unlockFocus];
		
		//NSData *imageData = [image  TIFFRepresentation];
		NSData *imageData;// = [stretchView TIFFRepresentation];
		//NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];
		//NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:0.9] forKey:NSImageCompressionFactor];
		NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:0.9] forKey:NSImageCompressionFactor];
		//imageData = [imageRep representationUsingType:NSJPEGFileType properties:imageProps];
		imageData = [bits representationUsingType:NSJPEGFileType properties:imageProps];
		[imageData writeToFile:path atomically:NO];

	}
}

- (IBAction)open:(id)sender
{
	NSOpenPanel *panel = [NSOpenPanel openPanel];
	
	//Run the open panel
	[panel beginSheetForDirectory:nil 
		file:nil 
		types:[NSImage imageFileTypes] 
		modalForWindow:[stretchView window] 
		modalDelegate:self 
		didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)
		contextInfo:NULL];
}

-(IBAction)save:(id)sender
{
	NSSavePanel *panel = [NSSavePanel savePanel];
	[panel beginSheetForDirectory:nil
		file:@"untitled.jpeg" 
		modalForWindow:[stretchView window]
		modalDelegate:self 
		didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) 
		contextInfo:NULL];

}

@end

Code:
//StretchView.h
/* StretchView */

#import <Cocoa/Cocoa.h>

@interface StretchView : NSView
{
	NSPoint downPoint;
	NSPoint currentPoint;
	NSBezierPath *path;
	NSData *viewData;
	NSImage *image;
	float opacity;
}

- (void)setImage:(NSImage *)newImage;
- (NSImage*)image;
- (void)setOpacity:(float)x;
- (NSPoint)randomPoint;
- (NSRect)currentRect;
- (void)setViewData;
- (NSData *)data;
@end

Code:
//StretchView.m
#import "StretchView.h"

@implementation StretchView

- (id)initWithFrame:(NSRect)frameRect
{
	int i;
	NSPoint p;
	
	if (self = [super initWithFrame:frameRect]) {
		//Seed the random number generator
		srandom(time(NULL));
		
		//Create a path object
		path = [[NSBezierPath alloc] init];
		[path setLineWidth:3.0];
		p = [self randomPoint];
		[path moveToPoint: p];
		for (i = 0; i < 15; i++) {
			p = [self randomPoint];
			[path lineToPoint: p];
		}
		[path closePath];
	}
	return self;
}

- (void)setImage:(NSImage *)newImage
{
	[newImage retain];
	[image release];
	image = newImage;
	
	NSSize imageSize;
	imageSize = [newImage size];
	downPoint = NSZeroPoint;
	currentPoint.x = downPoint.x + imageSize.width;
	currentPoint.y = downPoint.y + imageSize.height;
	
	[self setNeedsDisplay:YES];
}

- (NSImage *)image
{
	return image;
}

- (void)setOpacity:(float)x
{
	opacity = x;
	[self setNeedsDisplay:YES];
}

//randomPoint returns a random point inside the view
- (NSPoint)randomPoint
{
	NSPoint result;
	NSRect r;
	int width, height;
	r = [self bounds];
	width = round(r.size.width);
	height = round(r.size.height);
	result.x = (random() % width) + r.origin.x;
	result.y = (random() % height) + r.origin.x;
	return result;
}

- (void)mouseDown:(NSEvent *)event
{
	NSPoint p = [event locationInWindow];
	downPoint = [self convertPoint:p fromView:nil];
	currentPoint = downPoint;
	[self setNeedsDisplay:YES];
}

- (void)mouseDragged:(NSEvent *)event
{
	NSPoint p = [event locationInWindow];
	currentPoint = [self convertPoint:p fromView:nil];
	[[self superview] autoscroll:event];
	[self setNeedsDisplay:YES];
	NSLog(@"mouseDragged:");
}

- (void)mouseUp:(NSEvent *)event
{
	NSPoint p = [event locationInWindow];
	currentPoint = [self convertPoint:p fromView:nil];
	[self setNeedsDisplay:YES];
	NSLog(@"mouseUp:");
}

- (void)drawRect:(NSRect)rect
{
	NSRect bounds = [self bounds];
	
	//Fill the view with green
	[[NSColor greenColor] set];
	[NSBezierPath fillRect:bounds];
	
	//Draw the path in white
	[[NSColor whiteColor] set];
	[path stroke];
	
	if(image) {
		NSRect imageRect;
		NSRect drawingRect;
		imageRect.origin = NSZeroPoint;
		imageRect.size = [image size];
		drawingRect = [self currentRect];
		[image drawInRect:drawingRect
			fromRect:imageRect
			operation:NSCompositeSourceOver
			fraction:opacity];
	}
	[self setViewData];
}

- (NSRect)currentRect
{
	float minX = MIN(downPoint.x, currentPoint.x);
	float maxX = MAX(downPoint.x, currentPoint.x);
	float minY = MIN(downPoint.y, currentPoint.y);
	float maxY = MAX(downPoint.y, currentPoint.y);
	
	return NSMakeRect(minX, minY, maxX-minX, maxY-minY);
}

- (void)setViewData
{
	 // Get the data into a bitmap.
	[self lockFocus];
	NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[self bounds]];
	[self unlockFocus];

	// Make an NSImage from our bitmap.
   NSImage *imageX = [[[NSImage alloc] initWithSize:[rep size]] autorelease];
   [imageX addRepresentation:rep];

	// Convert to TIFF, we'd like to support other file types as well.
	viewData = [imageX TIFFRepresentation];
}

- (NSData *)data
{
	return viewData;
}

- (void)dealloc
{
	[image release];
	[path release];
	[super dealloc];
}

@end
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
Can you:

Ask the view how bit it is.
Create an NSImage that size.
Lock focus on the image.
Call [view drawInRect:];
Unlock focus?
 

slooksterPSV

macrumors 68040
Original poster
Apr 17, 2004
3,543
305
Nowheresville
Here's what I had to do, and I feel like an idiot, in the next chapter, it tells you how to save a view via a PDF file. That was all I needed to do, was save it as a PDF here's the new code:

- (void)savePanelDidEnd:(NSSavePanel *)savePanel returnCode:(int)returnCode contextInfo:(void *)x
{
NSRect r;
NSData *data;

if (returnCode == NSOKButton) {
r = [stretchView rect];
data = [stretchView dataWithPDFInsideRect:r];
[data writeToFile:[savePanel filename] atomically:YES];
}
}
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.