Image from WebView dragged onto IKImageView - objective-c

I have WebView where I load content of webarchive. In the same view I have IKImageView outlet. Image drag n drop from web view onto image view doesn't work for me.
What is weird, it works when I drag photo e.g. from iPhoto onto the same image view.
Also, I can drag image from my web view onto NSScrollView (which creates a link to the image) and I can drag the same photo onto a new Mail message (created an image as expected).
IKImageView has "Supports Drag and Drop" enabled in the IB.
What am I missing here?

IKImageView is probably expecting a pasteboard of NSFilenamesPboardType, how does the webview handle dragging images?

It turned out, that the best way to handle d'n'd in my case is via WebArchivePboardType.
Then:
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
NSPasteboard *pboard;
NSDragOperation sourceDragMask;
sourceDragMask = [sender draggingSourceOperationMask];
pboard = [sender draggingPasteboard];
// Create image data from webarchive stored in a pasteboard.
NSData *image = [pboard dataForType:WebArchivePboardType];
WebArchive *webArchive = [[WebArchive alloc] initWithData:image];
// Let's see what are we dragging.
for (WebResource *subresource in [webArchive subresources])
{
NSString *mimeType = [subresource MIMEType];
if ([mimeType hasPrefix:expectedMimeTypeStartsWith])
{
NSData *data = [subresource data];
CFDataRef imgData = (CFDataRef)data;
CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData (imgData);
CGImageRef image;
if ([mimeType hasSuffix:#"png"])
{
image = CGImageCreateWithPNGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault);
}
else if ([mimeType hasSuffix:#"jpeg"])
{
image = CGImageCreateWithJPEGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault);
}
[self setImage:image imageProperties:nil];
}
}
return YES;
}

Related

App Crashes when too many images are in TableView

I have a table that I am populating with information stored in Runner Objects. Each Runner object has a property called fileName that corresponds to an image saved in the document directory.
If I start with an empty table, I can add runners and their photos just fine until I reach about 8 runners. When I try to add a photo for the 8th or so runner, the app crashes. It seems to be a memory issue, but I don't see how this can be when all I'm storing locally are references to images in the directory.
I pass a runner object to my set up cell method in my RunnerCell class and set up the cell like so:
if (currentRunner.fileName != nil) {
if ([manager fileExistsAtPath:fullPath]){
UIImage *originalImage = [[UIImage alloc] initWithContentsOfFile:fullPath];
if ([currentRunner.photoOrientation isEqual: #"portrait"]) {
CGImageRef imageRef = [originalImage CGImage];
UIImage *rotatedImage = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:UIImageOrientationRight];
self.runnerImageView.image = rotatedImage;
} else {
self.runnerImageView.image = originalImage;
}
self.addPhotoLabel.hidden = true;
}
}
As per documentation states that you mustn't load image to a UITableViewCell on main thread. That is why your app is crashing.
Because when you load image on main thread it became too much laggy when you scroll because dequereusable cell reassign cell and again load image for upcoming indexpath's cell and until the image loads it block the main thread which cause laggy behaviour of tableview.
Please load your cached image in a background thread. use this code.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
if ([currentRunner.photoOrientation isEqual: #"portrait"]) {
CGImageRef imageRef = [originalImage CGImage];
UIImage *rotatedImage = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:UIImageOrientationRight];
dispatch_sync(dispatch_get_main_queue(), ^(void) {
self.runnerImageView.image = rotatedImage;
});
} else {
dispatch_sync(dispatch_get_main_queue(), ^(void) {
self.runnerImageView.image = originalImage;
});
}
});

UIScrollView loading images -makes scroller be slowly

I have a scroll view with many UIViews, and these views have UIImageViews-that i load images into, while scrolling.
So every page has 4 of these views,that are preloaded to scroller at start, and i load the next page images while scrolling.
I do that in another thread , and still, scroller not entirely scrolls fast, if you look good it has some tiny flicks .
here is the function that loads them :
-(void)loadMainImageToIndex:(int)index
{
NSDictionary *dic=[mainData objectAtIndex:index];
NSString *userImageUrl=[dic objectForKey:#"url"];
NSURL *userUrl=[NSURL URLWithString:userImageUrl];
[self downloadImageWithURL:userUrl completionBlock:^(BOOL succeeded, NSData *tdata)
{
if (succeeded)
{
//load back
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^
{
UIImage *image=[UIImage imageWithData:tdata scale:0.25];
if (image)
{
UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
[image drawAtPoint:CGPointZero];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
dispatch_async(dispatch_get_main_queue(), ^
{
UIImageView *view=[mainImagesArray objectAtIndex:index];
});
}
}];
The url is loaded Asynch.
Turned out that the views shadow cause this thing :
//self.layer.shadowOffset=CGSizeMake(6.0, 6.0);
//self.layer.shadowColor=[UIColor blackColor].CGColor;
//self.layer.shadowRadius = 3;
//self.layer.shadowOpacity = 0.7;
Removing this solves the problem.
self.layer.shouldRasterize = YES; //solve the problem,

Image of NSView with background

I'm trying to get an image of a view, so I can put it in a NSImageView.
I'm using NSViews bitmapImageRepForCachingDisplayInRect: method.
However, this method does only return the contents of the view, without background of the window.
How can I get the image of the whole view, as it looks on the screen, with background-color etc.?
Current Code
- (NSImage *)imageOfView:(NSView *)view {
NSBitmapImageRep* rep = [view bitmapImageRepForCachingDisplayInRect:view.bounds];
[view cacheDisplayInRect:view.frame toBitmapImageRep:rep];
return [[NSImage alloc] initWithCGImage:[rep CGImage] size:view.bounds.size];
}
This statement from the project
/* Get the index for the chosen display from the CGDirectDisplayID array. */
NSInteger displaysIndex = [menuItem tag];
/* Make a snapshot image of the current display. */
CGImageRef image = CGDisplayCreateImage(displays[displaysIndex]);

Image shows up blurred in UIImageView

I am creating an app where a user can load their schedule into the app, and it is subsequently displayed.
When the image is allowed to be edited before loading, it shows up perfectly:
Once the user "chooses" the image, it shows up in the UIImageView blurred:
Here it is slightly zoomed in:
I know that the image resolution is okay because image displays perfectly beforehand. How can I stop this from being blurred?
I am using the basic method of zooming an UIImageView in an UIScrollView.
Here is the code I use to assign the image. zoomscroll is the UIScrollView and myschedule is the UIImageView:
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[self dismissModalViewControllerAnimated:YES];
//Obtaining saving path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *imagePath = [documentsDirectory stringByAppendingPathComponent:#"myschedule.png"];
//Extracting image from the picker and saving it
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:#"public.image"]){
UIImage *editedImage = [info objectForKey:UIImagePickerControllerEditedImage];
NSData *webData = UIImagePNGRepresentation(editedImage);
[webData writeToFile:imagePath atomically:YES];
myschedule.image = editedImage;
[zoomscroll addSubview:myschedule];
zoomscroll.contentSize = CGSizeMake(myschedule.frame.size.width , myschedule.frame.size.height);
zoomscroll.minimumZoomScale = 1.0;
zoomscroll.maximumZoomScale = 4.0;
}
}
Thank you!
iOS doesn't redraw views when it zooms them, it just scales the view up or down. The underlying implementation is basically a textured OpenGL polygon, which is why zooming is so fast. Regenerating the texture at a higher res is slow, so iOS doesn't do that unless you explicitly tell it to.
There are various ways you can fix this. The simplest is probably to set the contentSize of your scrollview to the actual size of the image and then zoom out initially, so that instead of zooming a small version of the image up to 400% (which results in blurring) the user is zooming back in from 25% up to 100%. Something like this:
myschedule.image = editedImage;
myschedule.frame = CGRectMake(0, 0, editedImage.size.width, editedImage.size.height);
[zoomscroll addSubview:myschedule];
zoomscroll.contentSize = editedImage.size;
zoomscroll.minimumZoomScale = 0.25;
zoomscroll.maximumZoomScale = 1.0;
zoomscroll.zoomScale = zoomscroll.minimumZoomScale;

Obj-C View to PDF only renders first page

I've got a UIView extension class called UIView+PDFView which takes the current view, splits it into pages, and renders a PDF document. My issue lies in the rendering part; I can successfully 'create' pages for content, however all pages after the first are blank. My end goal is to take the current view, 'scale' the width equal to the page, and paginate the rest of the view within a PDF.
What the issue isn't:
Attaching the PDF to e-mail
Sending the PDF to a printer/print simulator
Only printing one page while actually generating the PDF correctly
Correctly resizing the view (SO Question 4919388)
I do this before I send to method. Verified by making frame 10px tall, still prints one (and only one) full page
Correctly translating the view. Verified by making both a translation and a scale; both correctly changed the view, however neither rendered on more than the first page.
My code is as follows:
#interface UIView (PDFView)
-(id)createPDFAndSaveToDocumentsWithFileName:(NSString*)aFilename andDocumentInfo:(NSDictionary *)documentInfo;
#end
#implementation UIView (PDFView)
-(id)createPDFAndSaveToDocumentsWithFileName:(NSString*)aFilename andDocumentInfo:(NSDictionary *)documentInfo {
// http://developer.apple.com/library/ios/DOCUMENTATION/GraphicsImaging/Reference/CGPDFContext/Reference/reference.html#//apple_ref/doc/constant_group/Auxiliary_Dictionary_Keys
// Creates a mutable data object for updating with binary data, like a byte array
NSMutableData *pdfData = [NSMutableData data];
// Points the pdf converter to the mutable data object and to the UIView to be converted
CGSize pageSize = CGSizeMake(self.bounds.size.width, 792);
UIGraphicsBeginPDFContextToData(pdfData, CGRectZero, documentInfo);
CGContextRef pdfContext = UIGraphicsGetCurrentContext();
NSInteger currentPage = 0;
BOOL done = NO;
do {
CGRect currentPageRect = CGRectMake(0, (pageSize.height*currentPage), pageSize.width, pageSize.height);
UIGraphicsBeginPDFPageWithInfo(currentPageRect, nil);
// draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData
[self.layer renderInContext:pdfContext];
// If we're at the end of the view, exit the loop.
if ((pageSize.height*currentPage) > self.bounds.size.height) {
done = YES;
} else {
currentPage++;
}
} while (!done);
// remove PDF rendering context
UIGraphicsEndPDFContext();
if (aFilename == nil) {
return pdfData;
} else {
// Retrieves the document directories from the iOS device
NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString* documentDirectory = [documentDirectories objectAtIndex:0];
NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename];
// instructs the mutable data object to write its context to a file on disk
[pdfData writeToFile:documentDirectoryFilename atomically:YES];
NSLog(#"documentDirectoryFileName: %#",documentDirectoryFilename);
return nil;
}
}
i think your problem lies
CGRect currentPageRect = CGRectMake(0, (pageSize.height*currentPage), pageSize.width, pageSize.height);
instead of that try using either of the below statements
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0.0, 0.0, 612.0, 792.0), nil);
UIGraphicsBeginPDFPage();
everytime you wish to add a new page to the context use the above statements and you would be able to add pages to the context.
if you wish to use the default size of the page i.e. 612 X 792 you can directly use UIGraphicsBeginPDFPage();
for custom page size you can use UIGraphicsBeginPDFPageWithInfo(CGRectMake(0.0, 0.0, 612.0, 792.0), nil);
I think that should solve your problem.