Console Error: failed to find PDF header: `%PDF' not found - iphone

When I try to print the current screenshot (for an iPad view) I get this weird error in console window:
failed to find PDF header: %PDF not found.
I wonder why this error is fired in console window ? why it's mentioning something related to PDF although I do not use any PDF related stuff in the whole project.
The code Im using to print the screenshot is :
- (IBAction)print:(id)sender {
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)])
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [UIScreen mainScreen].scale);
else
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//saving the file to documents directory
NSData * imageData = UIImagePNGRepresentation(viewImage);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
documentsDirectory = [documentsDirectory stringByAppendingPathComponent:#"Screenshot.png"];
[imageData writeToFile:documentsDirectory atomically:YES];
NSString *myFilePath = [documentsDirectory stringByAppendingPathComponent:#"Screenshot.png"];
UIImage *screenShot = [UIImage imageWithData:imageData];
NSData *myData = [NSData dataWithData:UIImagePNGRepresentation(screenShot)];
self.pic = [UIPrintInteractionController sharedPrintController];
if (self.pic && [UIPrintInteractionController canPrintData:myData] ) {
self.pic.delegate = self;
//filling up print info
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral;
printInfo.jobName = [myFilePath lastPathComponent];
printInfo.duplex = UIPrintInfoDuplexLongEdge;
self.pic.printInfo = printInfo;
self.pic.showsPageRange = YES;
self.pic.printingItem = myData;
void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
^(UIPrintInteractionController *pic, BOOL completed, NSError *error) {
if (!completed && error)
NSLog(#"FAILED! due to error in domain %# with error code %u",
error.domain, error.code);
};
[self.pic presentFromRect:self.printButton.frame inView:self.view animated:YES completionHandler: completionHandler]; // iPad
}
}
The file path (Screenshot.png) is correct, and it is correctly saved to documents directory.

It would help to know which line, exactly, causes that console output. You could step through it in the debugger to find out.
My guess is that it's the call to -[UIPrintInteractionController canPrintData:]. If you read the documentation for that method, you'll see that it has to check if that data contains PDF. It looks like it tries and fails, printing a message along the way.
Since generally no end users watch the iOS console, this is not a very important bug, apparently not important enough for Apple to fix.

This happened to me as well. I checked through every line and I found out that this is because you are printing data. And if you directly print image this weird warning will disappear. Because from Apple's file of the UIPrintInteractionController framework:
#NSCopying public var printingItem: AnyObject? // single NSData, NSURL, UIImage, ALAsset
The printingItem can be any one of the above four types. My guess is Apple takes data as PDF data by default, and apparently, this is no header data in the data you generated from UIImage.

Related

Iphone-saving full size image to document directory hangs my app

I am working on an app similar to photo app in iPhone. The flow is I get images through UIImagePickerController. When I use Actual image and further save that image to documents,
My app hangs. I saw on profile tool that allocation goes to 19 to 20 mb. If there is any solution to that.
Getting image from UIImagepicker controller
Saving it to documents.
-(NSString *)saveImageInDocumentsAtPath:(NSNumber *)number
{
NSString *fileName=[NSString stringWithFormat:#"image%#.png",number];
NSString *imagePath= [[NSString alloc] initWithFormat:#"%#/%#", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0],fileName];
UIImage *image = self.selectedImage.image;
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:imagePath atomically:YES];
return imagePath;
}
A typical image is going to be around 3Megabytes, if I am not mistaken (depending on the iPhone and its camera). So going from 19 to 20 is not unreasonable. Why you are at 19 to begin with ay be another question. See if you're loading in too many other images, large files etc.
If you use AV Foundation instead of ImagePicker, you have some other options for handling the images.
And you can write the image to the filesystem asynchronously.
This looks like a great opportunity for some error checking in your code.
Why not try this?
-(NSString *)saveImageInDocumentsAtPath:(NSNumber *)number
{
NSString *fileName=[NSString stringWithFormat:#"image%#.png",number];
NSArray * docDirectoryArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
if(docDirectoryArray)
{
NSString *imagePath= [[NSString alloc] initWithFormat:#"%#/%#", [docDirectoryArray objectAtIndex:0],fileName];
UIImage *image = self.selectedImage.image;
if(image)
{
NSData *imageData = UIImagePNGRepresentation(image);
if(imageData)
{
BOOL success = [imageData writeToFile:imagePath atomically:YES];
if(success)
{
// only return the image path in the success == YES case
return imagePath;
} else {
NSLog( #"did not save file to %#", imagePath);
}
} else {
NSLog( #"could not get image data out of the image");
}
} else {
NSLog( #"no image selected");
}
}
// you might want to check in the caller to make certain the imagePath is NULL
return NULL;
}

Storing and retrieving images on iPhone efficiently

I have an application which donwloads several images and stores them on the phone. In total it will probably required around 20 images tops. I need to be able to retrieve any of these images at will depending on what screen the user is on. These images will be stored indefinitely, so I don't want to use temp directory.
At present I have a class named Images with these methods
- (void) cacheImage: (NSString *) ImageURLString : (NSString *)imageName
{
NSURL *ImageURL = [NSURL URLWithString: ImageURLString];
// Generate a unique path to a resource representing the image you want
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex: 0];
NSString *docFile = [docDir stringByAppendingPathComponent: imageName];
// Check for file existence
if(![[NSFileManager defaultManager] fileExistsAtPath: docFile])
{
// The file doesn't exist, we should get a copy of it
// Fetch image
NSData *data = [[NSData alloc] initWithContentsOfURL: ImageURL];
UIImage *image = [[UIImage alloc] initWithData: data];
// Is it PNG or JPG/JPEG?
// Running the image representation function writes the data from the image to a file
if([ImageURLString rangeOfString: #".png" options: NSCaseInsensitiveSearch].location != NSNotFound)
{
[UIImagePNGRepresentation(image) writeToFile: docFile atomically: YES];
}
else if([ImageURLString rangeOfString: #".jpg" options: NSCaseInsensitiveSearch].location != NSNotFound ||
[ImageURLString rangeOfString: #".jpeg" options: NSCaseInsensitiveSearch].location != NSNotFound)
{
[UIImageJPEGRepresentation(image, 100) writeToFile: docFile atomically: YES];
}
}
}
- (UIImage *) getCachedImage : (NSString *)imageName
{
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* cachedPath = [documentsDirectory stringByAppendingPathComponent:imageName];
UIImage *image;
// Check for a cached version
if([[NSFileManager defaultManager] fileExistsAtPath: cachedPath])
{
image = [UIImage imageWithContentsOfFile: cachedPath]; // this is the cached image
}
else
{
NSLog(#"Error getting image %#", imageName);
}
return image;
}
-(void)getImages
{
//example
NSString *image1URL = #"http://test/image1.png";
NSString *image2URL = #"http://test/image2.png";
NSString *image3URL = #"http://test/image3.png";
[self cacheImage:sLogo: #"Image1"];
[self cacheImage:sBlankNav: #"Image2"];
[self cacheImage:buttonLarge :#"Image3"];
}
-(void) storeImages
{
image1 = [self getCachedImage:#"Image1"];
image2 = [self getCachedImage:#"Image2"];
image3 = [self getCachedImage:#"Image3"];
}
So I use the code like this
Images *cache = [[Images alloc]init];
[cache storeImages];
The get images method is called once when the app first starts to get the images, it isn't called again after that, unless the images on the server are updated and I need to retrieve the updated ones.
The code works, but the problem is when I navigate to a screen that uses it, there is a very slight delay before the screen loads as it is loading the images.
My application is a tabbed application, so it begins on tab 1, I click tab 2 which implements the code, there will be a slight pause the first time it loads. It doesn't last very long, but it is noticeable and is very annoying. After that it is fine, as it is already loaded. However with navigation controller, every time you move from the first VC to the second VC, the method will be called again, so each time you navigate the delay will be there.
The images are not very big, biggest one is 68kb, others are much smaller than that. At present I am just testing with 5 images. Is there a more efficient way of storing and retrieving images, or am I doing something wrong with my code? I need to be able to retrieve these images without any noticeable delay in order for my application to remain fluid and not jerky or clunky.
Thanks in advance!!
You have two options to do the image loading work on a background thread - use Grand Central Dispatch or NSInvocationOperation. GCD might be considered the cleaner of the two:
dispatch_queue_t q = dispatch_get_global_queue(0, 0);
dispatch_queue_t main = dispatch_get_main_queue();
dispatch_async(q, ^{
//load images here
dispatch_async(main, ^{
// show on main thread here
});
});
you have delay because you're downloading data synchronously
// NSData *data = [[NSData alloc] initWithContentsOfURL: ImageURL];
Try some smart library like SDWebImage:
it lets you download image asynchronously while you still can display a local image (a proxy image). By the way, you still get cache image for free. So even if u are on local, you can still catch previously downloaded images
https://github.com/rs/SDWebImage
A must have

Saving in NSDocumentDirectory

Having weird problem with my NSDocumenDirectory saving.
Here is a sneak preview:
First I pick images ( in my imagePickerViewController):
in my PreviewController:
So at first try, it was okay.
Then I revisit the imagePickerViewController to add another image:
in my PreviewController:
This is where the problem occurs. At the image above, it recopies the last image from the old preview (like a duplicate). I dunno what Im doing wrong in my codes. But Im saving it when a file exist. Kindly see:
for (int i = 0; i < info.count; i++) {
NSLog(#"%#", [info objectAtIndex:i]);
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask ,YES );
NSString *documentsDir = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDir stringByAppendingPathComponent:[NSString stringWithFormat:#"firstSlotImages%d.png", i]];
if ([[NSFileManager defaultManager] fileExistsAtPath:savedImagePath]) {
NSLog(#"file doesnt exist");
} else {
ALAssetRepresentation *rep = [[info objectAtIndex: i] defaultRepresentation];
UIImage *image = [UIImage imageWithCGImage:[rep fullResolutionImage]];
//----resize the images
image = [self imageByScalingAndCroppingForSize:image toSize:CGSizeMake(256,256*image.size.height/image.size.width)];
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:savedImagePath atomically:YES];
NSLog(#"saving at:%#",savedImagePath);
}
}
What I need is to just reAdd AGAIN the same image with the new one.
Same as, like the last preview.
The four images are passed in the sequence that they show in the preview, so in the first example the orange cat is third, and in the second example, the orange cat is fourth. The new image isn't saving because it is third, and you already have a file named "firstSlotImages2.png". If you re-save each image without checking if the file exists, you should get the result you are looking for.
There's a key in the media info: UIImagePickerControllerMediaURL which returns an NSURL, convert it to a string and get the the lastPathComponent. Use this as the file name to save to the directory you are saving it to. You can then save the reference to these images by saving this same file name either in an NSMutableArray, or an NSMutableDictionary

Image storage as byte code locally from XML parsing & display if it is stored Otherwise go for parsing.

I am having an app in which at the time of launcing the app XML parsing is giving Main category from URL like hp, dell, etc...I am displaying it in the Tableview.
Then on click of particular cell i can get the detail of main category means its subcategory like http://www.dealsbell.com/findcoupon.php?store=hp
Here also i am getting data properly after parsing.
But my concern over here is, in ( http://www.dealsbell.com/findcoupon.php?store=hp ) this link i am getting images.
Each particular subcategory will have a same image. So i want to do something like that the image if first time loaded from the URL then it will display image from parsing otherwise i would like to store that image as its byte code in folder / file / in any way in my device on first parsing.
If once the image is stored to the particular way in my device next time when i will go to see the subcategory it will first check this image is stored locally to my device or not.
If yes then it should go to the particular location to fetch this local image & display it to each cell otherwise will parse & display image.
I hope you are getting, what i want to ask.
Please guide me, how can this be possible & what is the way to get result.
If any example or link you can suggest, then it will be more efficient to me.
Thanks in advance.
There are probably two ways to achive this.
Get NSData out of Image and hold that in UserDefaults or database.
Dump image in application folder and pick image from that place.
So whenever you try to load image for subcatogory check at one of place and if present use that. IF in case you have stored image and if any updated image comes,then remove previous copy and store new one.
-(void) SaveImageinDocumentWithName:(UIImage*) aUIImage Name:(NSString*) aName
{
if(aUIImage)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSMutableString* str = [[NSMutableString alloc] initWithCapacity:300];
[str appendString:documentsDirectory];
[str appendString:#"/"];
[str appendString:aName];
NSFileManager *fileManager = [NSFileManager defaultManager];
[UIImagePNGRepresentation(aUIImage) writeToFile:str atomically:YES];
if(str)
{
[str release];
str = nil;
}
if(fileManager)
{
[fileManager release];
fileManager = nil;
}
[pool release];
}
}
-- Getting saved image
-(UIImage*)GetSavedImageWithName:(NSString*) aFileName
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSMutableString* str = [[NSMutableString alloc] initWithCapacity:300];
[str appendString:documentsDirectory];
[str appendString:#"/"];
[str appendString:aFileName];
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL success = [fileManager fileExistsAtPath:str];
NSData *dataToWrite = nil;
UIImage* image = nil;
if(!success)
{
}
else
{
image = [[UIImage alloc] initWithContentsOfFile:str];
}
if(dataToWrite)
{
[dataToWrite release];
dataToWrite = nil;
}
if(str)
{
[str release];
str = nil;
}
if(fileManager)
{
[fileManager release];
fileManager = nil;
}
return image;
}
Parse dealsbell.com/wp-content/uploads/mobile/hp.gif and take only hp.gif
NSString *strImage = [NSString stringWithFormat:#"%#",aBook.image];
UIImage* image = [self GetSavedImageWithName:strImage];
if(image) // This means Image exists
{
// Do what you want
}
else
{
NSURL *url4Image = [NSURL URLWithString:strImage];
NSData *data = [NSData dataWithContentsOfURL:url4Image];
if(data != NULL)
{
image =[[UIImage alloc] initWithData:data];
[self SaveImageinDocumentWithName:image Name:strImage]; // save for future ref.
}
else
{
image =[UIImage imageNamed:#"icon.png"];
}
}

what's wrong in this initialization

I want to load uimage with image in path like this
/var/mobile/Applications/429E283A-6E89-4BCE-861F-252C5327F711/Library/Application Support/Students/43y. F./1.2.840.113564.3.1.2.180.0.0.90.20081228203734483950/1.2.840.113564.10.1.226230117146661685815524478531105858244/Thumbnail.bmp
I used the following code
UIImage* theImage = [UIImage imageNamed:ThumbnailPath];
if (theImage !=nil) {
cell.imageView.image = theImage;
}
else {
NSLog(#"Error");
}
where ThumbnailPath is the path
but the uiimage always nil, and I am sure the file exists , can any one please fix it for me
Best regards
UIImage* theImage = [UIImage imageWithContentsOfFile:ThumbnailPath];
if (theImage !=nil) {
cell.imageView.image = theImage;
}
else {
NSLog(#"Error");
}
hope this helps
I dont thing UIImage imageNamed can load from .bmp files..Read this and this SO threads about handling .bmp files in iphone
Refer UIImage class for load image.
How are you getting the value for "ThumbnailPath"
Are you using + pathForResource:ofType:inDirectory: method under NSBundle class.
If not consider using that.
If yes please edit your question and include the part of your code where you set the value for ThumbnailPath.
May Be this can help you
+(UIImage*)getImageFromDocumentDirectoryWithName:(NSString*)imageName
{
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
NSString *aPath= [documentsDir stringByAppendingPathComponent:imageName];
UIImage *myimage=nil;
NSFileManager *fileManager = [NSFileManager defaultManager];
if([fileManager fileExistsAtPath:aPath])
{
myimage =[UIImage imageWithContentsOfFile:aPath];
}
return myimage;
}
You can use add this functon in desired class and use it accordingly