iclems / iOS-htmltopdf

MIT License
305 stars 79 forks source link

Offline PDF with images. #11

Closed alexomul closed 10 years ago

alexomul commented 10 years ago

Is there any way to generate a pdf from a local html string that contains images saved in the "Documents" folder?

martinjuhasz commented 10 years ago

you just need to use the methods that contain the baseURL: attribute and set it to your documents directory

alexmiclea commented 10 years ago

Yeah, i managed to figure it out. Thanks for your help!

Sun3 commented 10 years ago

How would you handle the image if it is stored as an external binary fields in Core Data? Any guidance is appreciated.

martinjuhasz commented 10 years ago

what i did to get coreData binary images into my generated PDF was to subclass NSURLProtocol and register it right before you generate your PDF with [NSURLProtocol registerClass:[YOURURLProtocol class]];

this way you could deliver your nsdata directly to the webview, which is great.

Sun3 commented 10 years ago

@martinjuhasz Thanks for the tip.

I did not see your tip until now but what I ended up doing was using the Base64 encoding.

NSString *stringImageBase64 = [UIImageJPEGRepresentation([[UIImage imageWithData:[imagesNamesArray objectAtIndex:0], 0.5) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
htmlString = [htmlString stringByAppendingString:[NSString stringWithFormat:@"<div align=\"left\"><img src=\"data:image/png;base64,%@\" align=\"absmiddle\" /> </div>", stringImageBase64]];
martinjuhasz commented 10 years ago

this was also my first try. but using this method results in an enormous usage of memory. my app crashed several times if many (or big) images where added to the pdf html string.

yveveke commented 9 years ago

@martinjuhasz I checked your forked version, but I don't see your NSURLProtocol subclass. Is it possible to post those changes?

martinjuhasz commented 9 years ago

you don't need to make changes for this in iOS-htmltopdf.

f.e. use a "fake" url in your html that helps you to identify the image you need

<img src="mjimage://12345" />

now you create a NSURLProtocol subclass

@interface MJUPDFImageURLProtocol : NSURLProtocol

@end

+ (BOOL)canInitWithRequest:(NSURLRequest*)theRequest
{
    if ([theRequest.URL.scheme caseInsensitiveCompare:@"mjimage"] == NSOrderedSame) {
        return YES;
    }
    return NO;
}
- (void)startLoading
{
    // load image data as NSData using self.request (where you can find f.e. the id i used before
    NSData *data = ....
    // and then return in to the client (the webview that  iOS-htmltopdf uses
    [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
    [[self client] URLProtocol:self didLoadData:data];
    [[self client] URLProtocolDidFinishLoading:self];
}

then, before using iOS-htmltopdf register this subclass

[NSURLProtocol registerClass:[MJUPDFImageURLProtocol class]];
[NDHTMLtoPDF createPDFWithHTML:htmlContent pathForPDF ..... ];
[NSURLProtocol unregisterClass:[MJUPDFImageURLProtocol class]];

i hope this helps

rankers commented 9 years ago

What was the solution with regard to using the base URL - I am still unable to get this to work even when I set my base URL to be the documents directory, I reference an image like such <img src="photo.png" > and I have the photo.png in the documents directory.

The corresponding html is working, just the pdf not showing the image.

iclems commented 9 years ago

Have you tried the same thing in a UIWebView to see if it displays?

On Tue Feb 10 2015 at 12:12:18 PM rankers notifications@github.com wrote:

What was the solution with regard to using the base URL - I am still unable to get this to work even when I set my base URL to be the documents directory, I reference an image like such and I have the photo.png in the documents directory.

The corresponding html is working, just the pdf not showing the image.

— Reply to this email directly or view it on GitHub https://github.com/iclems/iOS-htmltopdf/issues/11#issuecomment-73682809.

rankers commented 9 years ago

Hmmm I have commented out the code that creates the UIWebView with an alpha of 0.0, and a tiny frame so I can take a look at the view - the image isn't showing.

I have resolved this by doing

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSURL *imageURL = [NSURL fileURLWithPath:[documentsDirectory stringByAppendingString:@"/photo.png"]];
    NSString *html =  [NSString stringWithFormat:@"<img src=\"%@\" >", imageURL];

Which means I reference full paths instead of relative ones. I think I was doing this before but just using an NSString instead of creating an NSURL out of the string.

Cheers