Setting color when drawing into a NSImage - cocoa

I'm trying to tag a picture file with a date in Cocoa and are trying to do this in a small command line tool. It works fine...but, I can't seem to be able to set the color. Am I doing something wrong?
#import <Cocoa/Cocoa.h>
int main (int argc, const char * argv[]) {
[NSApplication sharedApplication];
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSImage *image = [[NSImage alloc] initWithContentsOfFile:
[NSString stringWithFormat:#"%s", "/some/file.png"]];
if (image) {
[image lockFocus];
NSColor *color = [NSColor whiteColor];
// THESE DOESN'T SEEM TO WORK...
[color set];
[color setStroke];
[color setFill];
NSString *string = [NSString stringWithFormat:#"%#", [NSDate date]];
[string drawAtPoint:NSMakePoint(10, 10) withAttributes:nil];
[image unlockFocus];
NSBitmapImageRep *bits = [NSBitmapImageRep imageRepWithData:
[image TIFFRepresentation]];
NSData *data = [bits representationUsingType:NSPNGFileType
properties:nil];
[data writeToFile:#"/some/file.png"
atomically:NO];
}
[pool drain];
return 0;
}

I believe you need to set the color of text using the NSForegroundColorAttributeName attribute in the drawAtPoint:withAttributes: call, rather than setStroke/setFill.

Related

Looking for simple example to write text into a NSImage using Cocoa

NSImage *myNewIconImage=[[NSImage imageNamed:#"FanImage"] copy];
[myNewIconImage lockFocus];
[#"15" drawAtPoint:NSZeroPoint withAttributes:nil];
[myNewIconImage unlockFocus];
[myNewIconImage setTemplate:YES];
[[NSApplication sharedApplication]] setApplicationIconImage:myNewIconImage];
I am looking for a way to simply write a String onto this image.... and coming up very short. This does not worker me.
The following code will place a mutable attributed string on an NSImage:
NSImageView *imageView = [[NSImageView alloc] initWithFrame:NSMakeRect( 0, 0, _wndW, _wndH )];
[[window contentView] addSubview:imageView];
NSImage *image = [NSImage imageNamed:#"myImage.jpg"];
[image lockFocus];
NSMutableDictionary *attr = [NSMutableDictionary dictionary];
[attr setObject:[NSFont fontWithName:#"Lucida Grande" size:36] forKey:NSFontAttributeName];
[attr setObject: [NSNumber numberWithFloat: 10.0] forKey: NSStrokeWidthAttributeName];
[attr setObject:[NSColor whiteColor] forKey:NSForegroundColorAttributeName];
NSString *myStr = #"Welcome to Cocoa";
NSMutableAttributedString *s = [[NSMutableAttributedString alloc] initWithString: myStr attributes:attr];
[s drawAtPoint:NSMakePoint(130,130)];
[image unlockFocus];
[imageView setImage:image];

iTunes -like status bar

EDITED:
I am trying to show an iTunes-style like information bar. This was subject was covered in detail earlier, for example at iTunes or Xcode style information box at top of window
I only slightly modified the code from the above referenced link, so make it compile under a recent XCode.
My code is below:
- (void)drawRect:(NSRect)dirtyRect
{
// Drawing code here.
static NSShadow *kDropShadow = nil;
static NSShadow *kInnerShadow = nil;
static NSGradient *kBackgroundGradient = nil;
static NSColor *kBorderColor = nil;
if (kDropShadow == nil) {
kDropShadow = [[NSShadow alloc] init];
[kDropShadow setShadowColor:[NSColor colorWithCalibratedWhite:.863 alpha:.75]];
[kDropShadow setShadowOffset:NSMakeSize(0.0, -1.0)];
[kDropShadow setShadowBlurRadius:1.0];
kInnerShadow = [[NSShadow alloc] init];
[kInnerShadow setShadowColor:[NSColor colorWithCalibratedWhite:0.0 alpha:0.52]];
[kInnerShadow setShadowOffset:NSMakeSize(0.0, -1.0)];
[kInnerShadow setShadowBlurRadius:4.0];
kBorderColor = [[NSColor colorWithCalibratedWhite:0.569 alpha:1.0] retain];
// iTunes style
// kBackgroundGradient = [[NSGradient alloc] initWithColorsAndLocations:[NSColor colorWithCalibratedRed:0.929 green:0.945 blue:0.882 alpha:1.0],0.0,[NSColor colorWithCalibratedRed:0.902 green:0.922 blue:0.835 alpha:1.0],0.5,[NSColor colorWithCalibratedRed:0.871 green:0.894 blue:0.78 alpha:1.0],0.5,[NSColor colorWithCalibratedRed:0.949 green:0.961 blue:0.878 alpha:1.0],1.0, nil];
// Xcode style
kBackgroundGradient = [[NSGradient alloc] initWithColorsAndLocations:[NSColor colorWithCalibratedRed:0.957 green:0.976 blue:1.0 alpha:1.0],0.0,[NSColor colorWithCalibratedRed:0.871 green:0.894 blue:0.918 alpha:1.0],0.5,[NSColor colorWithCalibratedRed:0.831 green:0.851 blue:0.867 alpha:1.0],0.5,[NSColor colorWithCalibratedRed:0.82 green:0.847 blue:0.89 alpha:1.0],1.0, nil];
}
NSRect bounds = [self bounds];
NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:bounds xRadius:3.5 yRadius:3.5];
[NSGraphicsContext saveGraphicsState];
[kDropShadow set];
[path fill];
[NSGraphicsContext restoreGraphicsState];
[kBackgroundGradient drawInBezierPath:path angle:-90.0];
[kBorderColor setStroke];
[path stroke];
}
It is not working, however. I don't think drawRect() method ever gets called. What am I missing? Please advise.
Thank you
I had an extra line at the end:
[path fill];
Removing it does the trick.

NSTextView double vision

I must be doing something wrong here:
My Cocoa app has a scrollview around a custom view which in turn has a textview. I only expect to see one "This is a " string but there the extra one up in the corner.
I have reduced the code to something very minimal and still do not understand what my error is, so here I am fishing for a clue.
The view controller for the custom view follows, but for simplicity here is a link to the project.
#import "TTTSimpleCtrlView.h"
#interface TTTSimpleCtrlView ()
#property (strong,nonatomic) NSTextView *tv1;
#property (strong,nonatomic) NSTextStorage *ts;
#end
#implementation TTTSimpleCtrlView
- (void) awakeFromNib {
NSFont *font = [NSFont fontWithName:#"Courier New Bold" size:20.0f];
NSMutableParagraphStyle *styleModel = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[styleModel setLineHeightMultiple:1.0];
// [styleModel setLineSpacing:fontRect.size.height * 2];
NSDictionary *textAttrs = [NSDictionary dictionaryWithObjectsAndKeys: font, NSFontAttributeName,
[NSColor blackColor] ,NSForegroundColorAttributeName,
[NSColor whiteColor], NSBackgroundColorAttributeName,
styleModel, NSParagraphStyleAttributeName,
nil];
NSString *pilcrowStr = #"This is a test.";
NSAttributedString *s = [[NSAttributedString alloc] initWithString:pilcrowStr attributes:textAttrs];
NSRect rect = [s boundingRectWithSize:NSMakeSize(INFINITY,INFINITY)options:0];
NSLayoutManager *lm = [[NSLayoutManager alloc] init];
NSTextContainer *tc = [NSTextContainer new];
[tc setContainerSize:s.size];
[lm addTextContainer:tc];
_ts = [[NSTextStorage alloc] init];
[_ts setAttributedString:s];
[_ts addLayoutManager:lm];
[lm replaceTextStorage:_ts];
rect.origin.x = 10;
rect.origin.y = rect.size.height;
NSTextView *v = [[NSTextView alloc] initWithFrame:rect textContainer:tc];
[v setDrawsBackground:YES];
[self addSubview:v];
}
- (BOOL) isFlipped {
return YES;
}
- (void)drawRect:(NSRect)rect
{
NSLog(#"drawRect & %lu subviews",self.subviews.count);
for (NSTextView *v in self.subviews) {
if(CGRectIntersectsRect(v.frame, rect) || CGRectContainsRect(rect, v.frame)) {
[v drawRect:rect];
NSLog(#"frame = %#",NSStringFromRect(v.frame));
}
}
[super drawRect:rect];
}
You are calling:
[super drawRect:rect];
and you are drawing the text yourself in your draw function.
In effect you are drawing the text and cocoa is drawing the text for you as well.
So don't call super.

Is it possible to print IKImageBrowserView In Cocoa programmatically?

I want to take print of IKImageBrowserView with (content) images. I tried the following code
if (code == NSOKButton) {
NSPrintInfo *printInfo;
NSPrintInfo *sharedInfo;
NSPrintOperation *printOp;
NSMutableDictionary *printInfoDict;
NSMutableDictionary *sharedDict;
sharedInfo = [NSPrintInfo sharedPrintInfo];
sharedDict = [sharedInfo dictionary];
printInfoDict = [NSMutableDictionary dictionaryWithDictionary: sharedDict];
[printInfoDict setObject:NSPrintSaveJob
forKey:NSPrintJobDisposition];
[printInfoDict setObject:[sheet filename] forKey:NSPrintSavePath];
printInfo = [[NSPrintInfo alloc] initWithDictionary:printInfoDict];
[printInfo setHorizontalPagination: NSAutoPagination];
[printInfo setVerticalPagination: NSAutoPagination];
[printInfo setVerticallyCentered:NO];
printOp = [NSPrintOperation printOperationWithView:imageBrowser
printInfo:printInfo];
[printOp setShowsProgressPanel:NO];
[printOp runOperation];
}
because IKImageBrowserView is Inherits from NSView but print preview is showing null image. Please help me to over come this problem. Thanks in advance.....
/*
1) allocate a c buffer at the size of the visible rect of the image
browser
*/
NSRect vRect = [imageBrowser visibleRect];
NSSize size = vRect.size;
NSLog(#"Size W = %f and H = %f", size.width, size.height);
void *buffer = malloc(size.width * size.height * 4);
//2) read the pixels using openGL
[imageBrowser lockFocus];
glReadPixels(0,
0,
size.width,
size.height,
GL_RGBA,
GL_UNSIGNED_BYTE,
buffer);
[imageBrowser unlockFocus];
//3) create a bitmap with those pixels
unsigned char *planes[2];
planes[0] = (unsigned char *) (buffer);
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:planes pixelsWide:size.width
pixelsHigh:size.height bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES
isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace bitmapFormat:0
bytesPerRow:size.width*4 bitsPerPixel:32];
/*
4) create a temporary image with this bitmap and set it flipped
(because openGL and the AppKit don't have the same pixels coordinate
system)
*/
NSImage *img = [[NSImage alloc] initWithSize:size];
[img addRepresentation:imageRep];
[img setFlipped:YES];
[imageRep release];
/*
5) draw this temporary image into another image so that we get an
image without any reference to our "buffer" buffer so that we can
release it after that
*/
NSImage *finalImage = [[NSImage alloc] initWithSize:size];
[finalImage lockFocus];
[img drawAtPoint:NSZeroPoint
fromRect:NSMakeRect(0,0,size.width,size.height)
operation:NSCompositeCopy fraction:1.0];
[finalImage unlockFocus];
//[NSString stringWithFormat:#"/tmp/%#.tiff", marker]
NSData *imageData = [finalImage TIFFRepresentation];
NSString *writeToFileName = [NSString stringWithFormat:#"/Users/Desktop/%#.png", [NSDate date]];
[imageData writeToFile:writeToFileName atomically:NO];
//6) release intermediate objects
[img release];
free(buffer);
After this I send imageData for print, which works great for me.

desktop wallpaper [duplicate]

I am trying to change the desktop image; the procedure I've come up with is below. The first time this code is run, the resized image is displayed on screen as wallpaper, but the next time there is no reaction. What am I doing wrong?
-(IBAction)click:(id)sender
{
NSData *sourceData;
NSError *error;
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
screenArray = [NSScreen screens];
screenCount = [screenArray count];
unsigned index = 0;
for (index; index < screenCount; index++)
{
screenz = [screenArray objectAtIndex: index];
screenRect = [screenz visibleFrame];
}
NSLog(#"%fx%f",screenRect.size.width, screenRect.size.height);
arrCatDetails = [strCatDetails componentsSeparatedByString:appDelegate.strColDelimiter];
NSString *imageURL = [NSString stringWithFormat:#"upload/product/image/%#_%#_%d.jpg",[arrCatDetails objectAtIndex:0],appDelegate.str104by157Name,iSelectedImgIndex];
NSString *ima = [imageURL lastPathComponent];
NSString *str = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
NSString *dataFilePath = [str stringByAppendingPathComponent:ima];
NSString *imagePath = [NSString stringWithFormat:#"file://localhost%#",dataFilePath];
NSURL *url = [[NSURL alloc] init];
url = [NSURL URLWithString:imagePath];
sourceData = [NSData dataWithContentsOfURL:url];
sourceImage = [[NSImage alloc] initWithData: sourceData];
resizedImage = [[NSImage alloc] initWithSize: NSMakeSize(screenRect.size.width, screenRect.size.height)];
NSSize originalSize = [sourceImage size];
[resizedImage lockFocus];
[sourceImage drawInRect: NSMakeRect(0, 0, screenRect.size.width, screenRect.size.height) fromRect: NSMakeRect(0, 0, originalSize.width, originalSize.height) operation: NSCompositeSourceOver fraction: 1.0];
[resizedImage unlockFocus];
NSData *resizedData = [resizedImage TIFFRepresentation];
NSBitmapImageRep* theImageRepresentation = [NSBitmapImageRep imageRepWithData:resizedData];
newimage = #"editwall.jpg";
newFilePath = [str stringByAppendingPathComponent:newimage];
NSData* theImageData = [theImageRepresentation representationUsingType:NSJPEGFileType properties:nil];
[theImageData writeToFile: newFilePath atomically: YES];
if([filemgr fileExistsAtPath:newFilePath] == YES)
{
imagePath1 = [NSString stringWithFormat:#"file://localhost%#",newFilePath];
urlz = [NSURL URLWithString:imagePath1];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:nil, NSWorkspaceDesktopImageFillColorKey, [NSNumber numberWithBool:NO], NSWorkspaceDesktopImageAllowClippingKey, [NSNumber numberWithInteger:NSImageScaleProportionallyUpOrDown], NSWorkspaceDesktopImageScalingKey, nil];
[[NSWorkspace sharedWorkspace] setDesktopImageURL:urlz forScreen:[[NSScreen screens] lastObject] options:options error:&error];
}
else
{
NSLog(#"No");
}
[sourceImage release];
[resizedImage release];
}
Why not try -[NSWorkspace setDesktopImageURL:forScreen:options:error:]? Apple has a sample project called DesktopImage to give you some idea how to use it.
Edit (after reading your code more carefully):
The problem you're having may be because of your call to +[NSDictionary dictionaryWithObjectsAndKeys:] See the nil at the end of the list of arguments? That's how you tell NSDictionary that your argument list is done. You can't put nil in the list, because it will stop reading the list at that point. If you want to specify a key that has no value, you have to use [NSNull null].
An aside: you've got a memory management issue in your code:
// allocates memory for an NSURL
NSURL * url = [[NSURL alloc] init];
// allocates more memory for an NSURL, and leaks
// the earlier allocation
url = [NSURL URLWithString:imagePath];
Just do one or the other:
// If you do it this way, you will have to call
// [url release] later
NSURL * url = [[NSURL alloc] initWithString:imagePath];
// This memory will be released automatically
NSURL * otherUrl = [NSURL URLWithString:imagePath];

Resources