cocoa nsimage does not get saved - cocoa

I'm new to cocoa and programming, sorry if this is something basic.
I'm using ARC. I have an NSImageView component, which is controlled by DropZone class. I drag & drop an image into it, but once I try to call in the scalling method I got, it tells me that the ": ImageIO: CGImageSourceCreateWithData data parameter is nil" I assume I'm doing something wrong, just don't know what yet.
Here's my method in DropZone.m
- (void)scaleIcons:(NSString *)outputPath{
NSImage *anImage;
NSSize imageSize;
NSString *finalPath;
anImage = [[NSImage alloc]init];
anImage = image;
imageSize = [anImage size];
imageSize.width = 512;
imageSize.height = 512;
[anImage setSize:imageSize];
finalPath = [outputPath stringByAppendingString:#"/icon_512x512.png"];
NSData *imageData = [anImage TIFFRepresentation];
NSBitmapImageRep *rep = [NSBitmapImageRep imageRepWithData:imageData];
NSData *dataToWrite = [rep representationUsingType:NSPNGFileType properties:nil];
[dataToWrite writeToFile:finalPath atomically:NO];
}
The DropZone.h
#interface DropZone : NSImageView <NSDraggingDestination>{
NSImage *image;
}
- (void)scaleIcons:(NSString *)outputPath;
#end
And here's how I call it it my AppDelegate.m
- (IBAction)createIconButtonClicked:(id)sender {
NSFileManager *filemgr;
NSString *tempDir;
filemgr = [NSFileManager defaultManager];
tempDir = [pathString stringByAppendingString:#"/icon.iconset"];
NSURL *newDir = [NSURL fileURLWithPath:tempDir];
[filemgr createDirectoryAtURL: newDir withIntermediateDirectories:YES attributes: nil error:nil];
DropZone *myZone = [[DropZone alloc] init];
[myZone scaleIcons:tempDir];
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:#"Done!"];
[alert runModal];
}
the image get's pulled from the pastebaord:
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender{
if ([NSImage canInitWithPasteboard:[sender draggingPasteboard]]) {
image = [[NSImage alloc]initWithPasteboard:[sender draggingPasteboard]];
[self setImage:image];
[self setImageAlignment: NSImageAlignCenter];
}
return YES;
}
For some reason my "image" gets lost. Could somebody help?

The problem is that you're creating a new instance of DropZone in your app delegate, but I'm assuming that you created the image view in IB and changed its class to DropZone. Is that correct? If so, you need to have an IBOutlet in the app delegate connected to the image view in IB, and have this:
[self.iv scaleIcons:tempDir];
where iv is my IBOutlet.

Without knowing where "image" comes from, I would say your problem is in these lines...
anImage = [[NSImage alloc]init];
anImage = image;
You should just grab the image from the imageView...
anImage = [myImageView image];

Related

Using DLImageLoader-iOS

Is there anyone that can help me combine this
https://github.com/AndreyLunevich/DLImageLoader-iOS
With my code below... I am not understanding as my images are loaded from an NSString in core data and not a URL (maybe I cannot use this helper file)
My code is:
SCTableViewSection *Section3 = [self.tableViewModel sectionAtIndex:0];
Section3.cellActions.lazyLoad = ^(SCTableViewCell *cell, NSIndexPath *indexPath)
{
DLImageView *imageView = (DLImageView *)[cell viewWithTag:1];
NSString *imageString = (NSString *)[cell.boundObject valueForKey:#"thumbnail"];
NSString *fullName = [NSString stringWithFormat:#"Documents/%#", imageString];
NSString *imagePath = [NSHomeDirectory() stringByAppendingPathComponent:fullName];
UIImage *originalImage = [UIImage imageWithContentsOfFile:imagePath];
NSLog(#"added image from lazyload");
// size of actual thumbnail to display in cell
CGSize destinationSize = CGSizeMake(154,95); // size of actual thumbnail
UIGraphicsBeginImageContext(destinationSize);
[originalImage drawInRect:CGRectMake(0,0,destinationSize.width,destinationSize.height)];
UIImage *thumbnail = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[UIView transitionWithView:imageView
duration:2.25f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
imageView.image = thumbnail;
} completion:nil];
};

UIImageView image not returning nil but image not showing

I have an image view and it pulls url from the internet this is the url that I got from the RSS Feed -
its an image pulled from rss feed .xml here is code I use to get image.
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *URL = [NSURL URLWithString:#"www.something.com/rss/hi.xml"];
NSData *data = [NSData dataWithContentsOfURL:URL];
// Assuming data is in UTF8.
NSString *string = [NSString stringWithUTF8String:[data bytes]];
NSString *webStringz = string;
NSString *mastaString;
mastaString = webStringz;
NSScanner *theScanner2;
NSString *imageURL2;
theScanner2 = [NSScanner scannerWithString: mastaString];
// find start of tag
[theScanner2 scanUpToString: #"<media:content url=\"" intoString: nil];
if ([theScanner2 isAtEnd] == NO) {
// find end of tag
[theScanner2 scanUpToString: #"\" " intoString: &imageURL2];
imageURL2 = [imageURL2 stringByReplacingOccurrencesOfString:#"<media:content url=\"" withString:#""];
imageURL2 = [imageURL2 stringByReplacingOccurrencesOfString:#"\n" withString:#""];
imageURL2 = [imageURL2 stringByReplacingOccurrencesOfString:#" " withString:#""];
//Download Image
NSURL * imageURL = [NSURL URLWithString:[imageURL2 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation([UIImage imageWithData:[NSData dataWithContentsOfURL:imageURL]])];
UIImage * image = [UIImage imageWithData:imageData];
[imageView setImage:image];
NSLog(#"Image URL #1: %#", imageURL2);
mastaString = [mastaString stringByReplacingOccurrencesOfString:imageURL2 withString:#""];
if (imageView.image == nil) {
NSLog(#"IS NIL");
}
else if (image == nil) {
NSLog(#"IS NIL");
}
// Do any additional setup after loading the view.
}
}
In my NSLOG it says the image url and its valid.
It DOES NOT show the IS NIL
It DOES NOT show the IS NIL 2
But the ImageView is not showing the image? Why? Its all linked up and everything?
Thanks
It must be that you didn't create the image view when the first time you access the view of UIViewController. Note that self.view will trigger viewDidLoad method if it is nil, but then the imageView is nil. So you'b better create the imageView in viewDidLoad method.

How to draw EPS data on NSView

I'm struggling with the problem to draw an eps file on a NSView.
When I first load the eps file from a file and draw it with drawInRect: the image is displayed correctly. However, the image will not be drawn when I load it from an archive file.
I've prepared a dirty small example that you can copy/paste and try out. Create a new Cocoa App project and add this to the delegate method.
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Just a sample eps file
NSURL *url = [NSURL URLWithString: #"http://embedded.eecs.berkeley.edu/concurrency/latex/figure.eps"];
NSImage *epsImage = [[[NSImage alloc] initWithContentsOfURL: url] autorelease];
// Encode data
NSMutableData *mutableData = [[[NSMutableData alloc] init] autorelease];
NSKeyedArchiver *coder = [[[NSKeyedArchiver alloc] initForWritingWithMutableData: mutableData] autorelease];
[coder encodeObject: epsImage forKey: #"image"];
[coder finishEncoding];
NSString *dataFile = [#"~/Desktop/image.data" stringByExpandingTildeInPath];
[mutableData writeToFile: dataFile atomically: YES];
// Decode data
NSData *data = [NSData dataWithContentsOfFile: dataFile];
NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData: data];
NSImage *loadedImage = [decoder decodeObjectForKey: #"image"];
// Draw image
NSRect rect;
rect.origin = NSZeroPoint;
rect.size = loadedImage.size;
NSView *view = [[NSApp mainWindow] contentView];
[view lockFocus];
[loadedImage drawInRect: rect fromRect: rect operation: NSCompositeSourceOver fraction: 1.0];
[view unlockFocus];
}
To prove that the first loaded image draws correctly just change the line [loadedImage drawInRect:...] to [epsImage drawInRect:...].
I'm using NSKeyedArchiver and NSKeyedUnarchiver here for simulating encodeWithCoder: and initWithCoder:. So please focus on the fact that NSImage with NSEPSImageRep representation, which does not contain a preview (from a resource fork?) and loaded purely as eps commands, is not drawn on a NSView correctly.
Any help is appreciated.
Due to the way that cacheing works on NSImage, I've often found it more effective to actually grab the NSImageRep if I know what the type is.
In our code, we found that the most reliable way to save off images is in their original format, but that requires either saving off the data in its original format somewhere else, or requesting the data from the NSImageRep. Unfortunately, there's not a generic -(NSData*)data method of NSImageRep, so we ended up specifically checking for various types of NSImageRep and saving them off depending on what we knew them to be.
Fortunately, loading is simple, as NSImage::initWithData: will figure out the type based on the data.
Here's our long-standing code for doing this. Basically, it prefers PDF then EPS then it makes a TIFF of anything it doesn't understand.
+ (NSData*) dataWithImage:(NSImage*)image kindString:( NSString**)kindStringPtr
{
if (!image)
return nil;
NSData *pdfData=nil, *newData=nil, *epsData=nil, *imageData=nil;;
NSString *kindString=nil;
NSArray *reps = [image representations];
for (NSImageRep *rep in reps) {
if ([rep isKindOfClass: [NSPDFImageRep class]]) {
// we have a PDF, so save that
pdfData = [(NSPDFImageRep*)rep PDFRepresentation];
PDFDocument *doc = [[PDFDocument alloc] initWithData:pdfData];
newData = [doc dataRepresentation];
if (newData && ([newData length]<[pdfData length])) {
pdfData = newData;
}
break;
}
if ([rep isKindOfClass: [NSEPSImageRep class]]) {
epsData = [(NSEPSImageRep*)rep EPSRepresentation];
break;
}
}
if (pdfData) {
imageData=pdfData;
kindString= #"pdfImage";
} else if (epsData) {
imageData=epsData;
kindString=#"epsImage";
} else {
// make a big copy
NSBitmapImageRep *rep0 = [reps objectAtIndex:0];
if ([rep0 isKindOfClass: [NSBitmapImageRep class]]) {
[image setSize: NSMakeSize( [rep0 pixelsWide], [rep0 pixelsHigh])];
}
imageData = [image TIFFRepresentation];
kindString=#"tiffImage";
}
if (kindStringPtr)
*kindStringPtr=kindString;
return imageData;
}
Once we have the NSData*, it can be saved in a keyed archive, written to disk or whatever.
On the way back in, load in the NSData* and then
NSImage *image = [[NSImage alloc] initWithData: savedData];
and you should be all set.

Copy partial screenshot to Pasteboard

So, the code to copy part of my screen to the pasteboard works because it was successfully coping it to my photo album. But, I want to be able to paste the partial screenshot into a new SMS message. I know it will have to be done manually (long hold on message and Paste), but it either pasted nothing, or does not have the Paste option (as it's saving it as a String). The middle portion of the code is the part I'm struggling with. Any help would be great. I've changed the forPasteboardType to "image" but that does not work either.
//Capture part of Screen Shot
UIGraphicsBeginImageContext(self.view.bounds.size);
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(c, 0, 98); //
[self.view.layer renderInContext:c];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//Send Screenshot to Pasteboard
UIPasteboard *pasteBoard = [UIPasteboard pasteboardWithName:UIPasteboardNameGeneral create:YES];
pasteBoard.persistent = YES;
NSData *data = UIImagePNGRepresentation(viewImage);
[pasteBoard setData:data forPasteboardType:(NSString *)kUTTypePNG];
/////// Open SMS
MFMessageComposeViewController *controller = [[[MFMessageComposeViewController alloc] init] autorelease];
if([MFMessageComposeViewController canSendText])
{
controller.body = #"Hello from me, paste image here -->";
controller.recipients = [NSArray arrayWithObjects:#"123456789", nil];
controller.messageComposeDelegate = self;
[self presentModalViewController:controller animated:YES];
}
////// End SMS
}
//Capture part of Screen Shot
UIGraphicsBeginImageContext(self.view.bounds.size);
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(c, 0, 98); //
[self.view.layer renderInContext:c];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//Send Screenshot to Pasteboard
UIPasteboard *pasteBoard = [UIPasteboard pasteboardWithName:UIPasteboardNameGeneral create:YES];
pasteBoard.persistent = YES;
NSData *data = UIImagePNGRepresentation(viewImage);
[pasteBoard setData:data forPasteboardType:(NSString *)kUTTypePNG];
NSString *stringURL = #"sms:";
NSURL *url = [NSURL URLWithString:stringURL];
[[UIApplication sharedApplication] openURL:url];

xcode iphone - jerky scroll UITableView CellForRowAtIndexPath

Almost sorted with my 1st app, just a simple news app but when I load it onto my iPhone the scroll seems jerky can someone have a look at my function and see if i'm doing something wrong.
I need the image on the right hand side thats why i'm using custom cells.
Thanks
For any help
#define DATELABEL_TAG 1 #define MAINLABEL_TAG 2 #define PHOTO_TAG 3
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MainNewsCellIdentifier = #"MainNewsCellIdentifier";
UILabel *mainLabel, *dateLabel;
UIImageView *photo;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: MainNewsCellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier: MainNewsCellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
dateLabel = [[[UILabel alloc] initWithFrame:CGRectMake(15.0,15.0,170.0,15.0)] autorelease];
dateLabel.tag = DATELABEL_TAG;
dateLabel.font = [UIFont systemFontOfSize:10.0];
dateLabel.textAlignment = UITextAlignmentLeft;
dateLabel.textColor = [UIColor darkGrayColor];
dateLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin; //| UIViewAutoresizingFlexibleHeight;
[cell.contentView addSubview:dateLabel];
mainLabel = [[[UILabel alloc] initWithFrame:CGRectMake(15.0,28.0,170.0,60.0)] autorelease];
mainLabel.tag = MAINLABEL_TAG;
mainLabel.font = [UIFont boldSystemFontOfSize:14.0];
mainLabel.textColor = [UIColor blackColor];
mainLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin;
mainLabel.numberOfLines = 0;
//mainLabel.backgroundColor = [UIColor greenColor];
[cell.contentView addSubview:mainLabel];
photo = [[[UIImageView alloc] initWithFrame:CGRectMake(190.0,15.0,85.0,85.0)] autorelease];
photo.tag = PHOTO_TAG;
photo.contentMode = UIViewContentModeScaleAspectFit;//UIViewContentModeScaleAspectFit; //
[cell.contentView addSubview:photo];
}
else {
dateLabel = (UILabel *)[cell.contentView viewWithTag:DATELABEL_TAG];
mainLabel = (UILabel *)[cell.contentView viewWithTag:MAINLABEL_TAG];
photo = (UIImageView *)[cell.contentView viewWithTag:PHOTO_TAG];
}
NSUInteger row = [indexPath row];
NSDictionary *stream = (NSDictionary *) [dataList objectAtIndex:row];
NSString *title = [stream valueForKey:#"title"];
NSString *titleString = #"";
if( ! [title isKindOfClass:[NSString class]] )
{
titleString = #"";
}
else
{
titleString = title;
}
CGSize maximumSize = CGSizeMake(180, 9999);
UIFont *dateFont = [UIFont fontWithName:#"Helvetica" size:14];
CGSize dateStringSize = [titleString sizeWithFont:dateFont
constrainedToSize:maximumSize
lineBreakMode:mainLabel.lineBreakMode];
CGRect dateFrame = CGRectMake(15.0, 28.0, 170.0, dateStringSize.height);
mainLabel.frame = dateFrame;
mainLabel.text = titleString;
dateLabel.text = [stream valueForKey:#"created"];
NSString *i = [NSString stringWithFormat:#"http://www.website.co.uk/images/%#", [stream valueForKey:#"image"]];
NSData *imageURL = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:i]];
UIImage *newsImage = [[UIImage alloc] initWithData:imageURL];
photo.image = newsImage;
[imageURL release];
[newsImage release];
return cell;
}
The problem is this:
NSString *i = [NSString stringWithFormat:#"http://www.website.co.uk/images/%#", [stream valueForKey:#"image"]];
NSData *imageURL = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:i]];
UIImage *newsImage = [[UIImage alloc] initWithData:imageURL];
You effectively say here, that as soon as the cell needs to be displayed, the image must be fetched and presented. This will cost some time - too much for a good user experience.
You should fetch the images before or while you present the table view, and cache them, e.g. in an array. Or you must handle things asynchronously, meaning that you do the loading in the background, and not wait with return cell; until the image is actually downloaded. This will be a little harder to get right.
Even if you asynchronously download images, you'll still have a jerky scroll.
Why? It's lazy image decompression. ios performs decompression at the moment it will be displayed on the screen. You have to manually decompress the images in a background thread.
Decompression does not merely mean instantiating a UIImage object. It can be somewhat complicated. The best solution, is to download SDWebImage and use the image decompressor that's included. SDWebImage will asynchronously download and perform decompression for you.
To read more about the issue see: http://www.cocoanetics.com/2011/10/avoiding-image-decompression-sickness/

Resources