Asset Catalog images inside a UIWebView - ios

Xcode 9 has taken another step forward with vectors inside of iOS projects. It will apparently retain the source PDF so that images may be generated as needed with full quality.
I'm wondering if it's yet possible to access these images from the HTML inside of a UIWebView?
I can imagine three possible ways of doing this:
Some magic that you place within your HTML or CSS that iOS will recognize and replace. For example:
<img src={{Asset Name}}>
Knowing the naming scheme to get at the asset. For example:
<img src="some/path/asset~ipad#3x">
"Render" the image outside the UIWebView and pass it in.
Are any of these possible? Is there another way?
Given how far we've come with vectors, I'd hate to have to pre-render every image variation and package them outside the asset catalog if I don't have to.

Today i needed to render the UIImage from XCAsset's into an UIWebView.
My requirement was to prepare the appropriate HTML and load it into the UIWebView as follows
self.myWebView.loadHTMLString(html, baseURL: nil)
In order to load images from XCAsset's, first loaded the image into an UIImage, then convert it back to Base64 Encoding, then put the image into the <img> tag.
The code looks like following
let redClockImage = UIImage.init(named: "clock-red")!
let imageData:Data = UIImagePNGRepresentation(self)!
let base64String = imageData.base64EncodedString()
let html = """
//my html
<img src="data:image/png;base64, \(base64String)" />
//rest of my html
"""
//then i load this html into the webview
self.myWebView.loadHTMLString(html, baseURL: nil)
For Convenience i moved the UIImage -> Base64 String conversion into an extension.

Related

PDFKit and PDFDocument Annotations not visible in Adobe Acrobat

After I remove/add the annotations I save the file to disk (is this even necessary to properly save the annotations?). I then have the document in a UIActivityViewController inside a UIActivityItemProvider.
The annotations are viewable in the print preview, PDF Expert, Firefox, Gmail browser, Preview, etc. - just not Acrobat (and exporting to .doc)
Using Acrobat Reader Build 19.21.20061.361316; using Xcode 11.3
The PDF I am editing or here
Example annotation:
// Open PDF etc
if annotation.fieldName == "form1[0].Page1[0].WE_FACTR[0]" {
annotation.setValue("30.0", forAnnotationKey: .widgetValue)
page.removeAnnotation(annotation)
page.addAnnotation(annotation)
}
// save PDF to file
// PDF File is in the UIACtivityViewController
I was wondering if anyone had a workaround for missing annotations in PDFKit for Adobe Reader.
When I asked #steipete from PSPDFKit he told me that this is why people use his framework. There is a drop-in replacement call PDFXKit that he suggested.
It didn't work with PSPDFKit either! XFA forms don't seem to be supported.
I had the same issue, I am opening a PDF with a form in the app and fill it up with data from different textField. Unfortunately as it was very well explained by mkl, all the annotations are visible on all Pdf reader expect the one that most people use...Acrobat...
I have been looking for days for a solution and since that unfortunately PDFKit does not have at this time an option to flatten a PDF, I have to come up with an "ugly" solution. But at least for my needs it works.
Once I have updated the PDF form with all the annotation, I convert it to an image and then convert it back to a PDF. I have now a "flatten" pdf...
It is not great and I hope that Apple will add a function to flatten a pdf in their PDFkit in the future.
if there is a better solution, Let me know!
convert to image
func pdfToImage(url: URL) -> [UIImage]? {
let pdfDocument = PDFDocument(url: url)!
let numbPages = pdfDocument.pageCount
var imagePdf = [UIImage]()
for i in 0...numbPages-1 {
let page = pdfDocument.page(at: i)!
let bounds = page.bounds(for: .mediaBox)
let renderer = UIGraphicsImageRenderer(bounds: bounds, format: UIGraphicsImageRendererFormat.default())
let img = renderer.image { (context) in
context.cgContext.saveGState()
context.cgContext.translateBy(x: 0, y: bounds.height)
context.cgContext.concatenate(CGAffineTransform.init(scaleX: 1, y: -1))
page.draw(with: .mediaBox, to: context.cgContext)
context.cgContext.restoreGState()
}
imagePdf.append(img)
}
return imagePdf
}
convert back to PDF
func imageToPDF(image: [UIImage])-> PDFDocument? {
let pdfDocument = PDFDocument()
for (index,image) in image.enumerated() {
let pdfPage = PDFPage(image: image)
pdfDocument.insert(pdfPage!, at: index)
}
return pdfDocument
}
and then I just call those functionss
let imageFromPdf = pdfToImage(url: pdfURL)!
let flattenPDF = imageToPDF(image: imageFromPdf)
flattenPDF?.write(to: pdfURL2)
Your PDF has a XFA/AcroForm hybrid form definition. That means that the form is defined twice in the PDF, once using AcroForm objects, the "native" PDF form format, and once using a XFA XML stream, a meanwhile deprecated alternative form technique allowing more dynamic forms.
If your PDF is opened in a PDF processor supporting XFA (which foremost means Adobe viewers plus very few other processors), the XFA form definition is processed (e.g. displayed) and all the normal PDF content is ignored, merely values in the AcroForm form definition are updated to match the XFA form values.
If your PDF is opened in a PDF processor not supporting XFA (i.e. essentially all except Adobe products), the normal PDF content including the Acroform form definition is processed.
This explains your observation
The annotations are viewable in the print preview, PDF Expert, Firefox, Gmail browser, Preview, etc. - just not Acrobat (and exporting to .doc)
(As I only see now you found out about XFA yourself and edited a remark pointing there into your question.)
The usual solution in this situation is to remove the XFA form definition. Once it is removed, all processors (the Adobe viewers, too) will only process the normal PDF content including the AcroForm form definition.
To do so you merely have to remove XFA entry in the AcroForm dictionary of the PDF.
If a usage rights signature is present in the document (as is in yours), that removal will invalidate it. In such a case you should also remove the Perms entry in the Catalog.
Unfortunately I do not know your libraries, so I cannot show the code to implement this with them.

Wkwebview cannot display images in html having path of library directory

I have studied similar questions but couldnot find solution.
I am using WkWebView. It renders a html from library directory so i did loadfileurl.
It has option of displaying an image, we select the image from gallery/take camera , then from image data wecreate a file in library directory and sendthe path to web .
I tried both path var/... and also appended file://
both cases image is not displaying.
Please help.
Any suggestions appreciated.
An alternative would be to encode the images as base64 strings and insert them into the HTML before rendering. You could either save the images as images or the base64 string, depending on whether you need to use them in another context.
// Get the base64 representation of the image
let image = UIImage(named: icon) // This could also be loaded from the file system
let data = image!.pngData()
let b64String = String(data: data!.base64EncodedData(), encoding: String.Encoding.utf8)!
let finalString = "data:image/png;base64," + b64String
// Insert into HTML string before rendering in webview
let myHTML = baseHTML.replacingOccurrences(of: "#PLACEHOLDER#", with: finalString)
You will need to have #PLACEHOLDER# in your HTML file at the point where you would have the path to the image.

How to refer a local image file from UIWebView's HTML on iPhone?

I would like to use <img src="temp.jpg" /> in my UIWebView's HTML.
How can I refer to a local file named temp.jpg to save precious loading time?
Of course the obvious choice would be <img src=".\temp.jpg" /> but I have no idea where my root is...
This will create a URL object that contains the location of your file on disk. You can then use this to output a valid file:// URL string that can be used within img tags.
NSURL* fileURL = [[NSBundle mainBundle] URLForResource:#"temp" withExtension:#"jpg"];
NSLog(#"<img src=\"%#\" />", fileURL.absoluteString);
NSURL *url=[[NSBundle mainBundle] bundleURL];
[webView loadHTMLString:string baseURL:url];
This let's the root be the app's main bundle.
I was searching a lot for a solution and found the following which
in my case working fine, I have a local HTML string and a local image
I convert the image into base 64
you may use this website to convert image to base64 encoding
Converter
and rewrite the HTML string to have the base64 image in the image tag like the following
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD/4QCMRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAABIAAAAAQAAAEgAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAABmgAwAEAAAAAQAAABkAAAAA/+0AOFBob3Rvc2hvcCAzLjAAOEJJTQQEAAAAAAAAOEJJTQQlAAAAAAAQ1B2M2Y8AsgTpgAmY7PhCfv/AABEIABkAGQMBEQACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2wBDAAkGBxISEhISEhAQFRUXFRUVEhIQDxAQEBUVFRIWFxUVExUYHSggGBolGxUVITEhJSorLi4uFx8zODMtNygtLiv/2wBDAQoKCg4NDhcQEBctHR0dLS0tLS0rLS0rLS0tLTctLS0tLS4tLS0tLS0tLS0uKy0tLS0tLS0vLSstLS0tLS0rLS3/3QAEAAT/2gAMAwEAAhEDEQA/APTbvxzYRSPE85DoxR18qU4YYyMgc9R0rN1YJ2bO2ll2IqxUoRun5ohPxBsO0sh/3bec/wDstQ8TT7/gdCyXGP7K/wDAo/5iR+PrRnjjQTku6ICYSiguwUElscc0LERbsipZLiYxlKVkkm977a9Dq63PIP/Q6bWbLSftc/nzxLNvLOjXZjJyqnlQeDjHHoRWUqMJO7O+jmWIoxUYSVl5JlOW50RHQLNYsn/LQteM5Xn0zWboJSVo3XU0eb4t/wDLy3okizaeJ9CjlRYRCzl0VWitmcBmkVVzIRgckd62jShHZHPUzDE1FadWTXa56dVnIf/R6/xH8J7W9upbqS4ulaRlYpE0SoCsapwSpPRB3oASD4Pacv3nvG+t0y/+ggUAalh8NNMiIYWxYgggzTTS8g5BwzYzkCgDrsUAf//S9xoAKACgAoA//9k=" alt="Red dot" >
for Testing the result tye the following Online HTML editor
W3School
hope it will help for others or maybe get a better solution, best of luck
I have no idea where my root is...
UIWebView looks up files relative to the HTML file you loaded in it. So perhaps it will be your app bundle.

iphone image caching from initWithString in webview

i am parsing json from SBJson parser. I am using SDWebIamge for image caching. My JSON data has one tag namely "content" which has text + image links in between text. Just for example something like this
<p>This is sample text.<\/p>\n<p><a href=\"http:\/\/xyz.com\/08\/15.jpg\"><img class=\"aligncenter size-full wp-image-1273\" title=\"15\" src=\"http:\/\/xyz.com\/08\/15.jpg\" alt=\"\" width=\"422\" height=\"720\" \/><\/a><\/p>\n<p><a href=\"http:\/\/xyz.com\/08\/16.jpg\"><img class=\"aligncenter size-full wp-image-1274\" title=\"16\" src=\"http:\/\/xyz.com\/08\/16.jpg\" alt=\"\" width=\"680\" height=\"1024\" \/><\/a><\/p>\n<p> <\/p>\n
which i parse and store in my NSString variable.Then i have a webview which i load from this NSString by
NSString *htmlString = [[NSString alloc] initWithString:myObj.Content];
which loads the text and fetches link images as well by default as we all know web view does.I am saving this JSON data to file for offline viewing which is working great thanks to SDWebimage.But my issue is when i load the save content to webview it shows only text no image cause these is no image cashing in the NSString links which i loaded.So how can i cache the images in my webview so that next time when i load my webview from string it will show images from the link in my NSString data.
Thanks
You can use an existing implementation to do this - something like ASIWebPageRequest or ProxyingUIWebView should to the trick.
Alternatively you could try to implement this yourself. One option is something like the following:
Parse the HTML string and detect any img tags and their src attributes
Download and store any images detected
Display the stored (downloaded images) in place of the online originals by modifying the path to the images in the img tags in your HTML string.
Note this is a far from optimal solution and is only an example of one possible implementation.

Outputting a byte arrain into the src attribute of an img tag

I'm using ASP.NET MVC and have a model which has an image (byte array) in one of the fields. I'm trying to output this image into the src attribute of the img tag. I'm looking to do something like <img src='<%= Model.VenueImage %>'>. How can I do this?
Maybe Inline Images with Data URLs idea?
Inline images use the data URI scheme
to embed images directly within web
pages. As defined by RFC 2397, data
URIs are designed to embed small data
items as "immediate" data, as if they
were referenced externally. Using
inline images saves HTTP requests over
externally referenced objects.
System.Drawing.Image image = GetImageFromSomewhere(...);
byte[] imageData = ImageToByteArray(image);
string imageBase64 = Convert.ToBase64String(imageData);
string imageSrc = string.Format("data:image/gif;base64,{0}", imageBase64);
and then somewhere in the page:
<img src= "<%= ImageSrcBytes %>" />
AFAIK this will work for Opera 7.2+, Firefox, Safari, Netscape, Mozilla and IE8+ (IE8 up to 32kb).
For earlier version of IE there is a workaround - MHTML.
The example how to do it is here.
The browser uses the src attribute to issue a separate request to the server, to get the contents of the image. It does not display the bytes in the src as the image itself.
So you will need to remember those bytes (session?) and use a handler (the url you put into the src attribute) to let the browser request them.

Resources