Wkwebview cannot display images in html having path of library directory - ios

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.

Related

Render Images in document.directory in a markdown file in swift(SwiftyMarkdown)

Am using SwiftyMarkdown framework to render my .md file to have dynamic formatted data in my VC. But i am not able to load images in my document directory referenced in .md file. I can load images if they are available in Bundle.
Any other option or framework to fix this issue? I want to dynamically load images from server and save them documents directory and refer them in .md file which is also saved in same documents directory/folder. So the url of image and .md file is same.
"MyFile.md" in documents directory contains below content
Continue your walk, joining up with your original perimeter path of the item. "
In my VC viewdidload, i access the url path and load nsattributed string to my textview using SwiftyMarkdown frmaework
let url = self.getDocumentsDirectory().appendingPathComponent("MyFile.md")
if let md = SwiftyMarkdown(url: url) {
textView.attributedText = md.attributedString()
}
The formatted text is loaded but no image as its not available in my Bundle. But its saved in the same document directory as that of "MyFile.md"
Hope its clear!

Load Server URL dicom files inside Imebra in iOS?

I am using https://imebra.com/ in my application, when I load a local files it reading the DICOM file and I am able to see the Image. when, I am sending Cloud url path to imebra It is showing an error and below I shared sample code.I want to send a single or multiple url to Imebra. I don't know how to proceed.
let filePath = Bundle.main.path(forResource: fileName, ofType: "dcm") // i want to send url(https://raw.githubusercontent.com/ivmartel/dwv/master/tests/data/bbmri-53323851.dcm) here
let dataSet = try ImebraCodecFactory.load(fromFile: filepath)
_ = try dataSet.getString(ImebraTagId(group: 0x10, tag: 0x10), elementNumber: 0, defaultValue: "")
_ = try dataSet.getString(ImebraTagId(group: 0x10, tag: 0x10), elementNumber: 1, defaultValue: "")
thanks in advance.
Imebra can load local DICOM files or from remote PACS (using the DIMSE protocol).
Imebra cannot load an image directly from an URL because it uses a posix call to open the local file.
To open a file from an URL you should first load the remote file. See this answer Simple Swift file download with URL to see how to load a file to a local temporary file.
Alternatively, you could load the file to a NSData object and pass its content to an Imebra Memory object, then pass to ImebraCodecFactory a StreamReader using a MemoryStreamInput.
Disclaimer: I'm the author of Imebra

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.

Asset Catalog images inside a UIWebView

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.

Base64 Encode Image and Save it later to a file

I have an application where an admin can upload an image. I save the image in a file and also base64 encode (using Base64.strict_encode method of ruby) & save in my DB. This is so that when later someone deleted the physical file from the HDD/Server, I can still generate it back by base64 decoding it (Base64.decode method) and save in a file.
But the encoding and decoding didn't go well as the image get damaged and I'm unable to view it after save.
I checked the output of the Base64.strict_encode against the result when I used http://www.base64-image.de/ to encode the file, they were different.
Can anyone help me with this? What am I doing wrong? What am I not doing?
ENCODING THE IMAGE DURING UPLOAD:
imageLoc = image.image.to_s
logger.info '>>>>>>' + (Base64.strict_encode64(open(imageLoc).read)).to_s
image_data = Base64.strict_encode64(File.open(imageLoc, 'rb').read)
CategoryImage.update_image_data(image.id,image_data)
DECODING WHEN IMAGE FILE IS LOST:
File.open(File.join(APP_CONFIG['image_storage_location'], image[:image]), 'wb') { |f|
content = image[:image_data]
content.gsub!('\\r', "\r")
content.gsub!('\\n', "\n")
f.write(Base64.decode64(content))
f.close
}
ENCODED IMAGE FROM THE SITE (base64-image.de): https://shrib.com/cYLKfEe1?v=nc
ENCODED IMAGE FROM MY CODE: https://shrib.com/CODE-encoded%20image?v=nc
EDIT
When I replaced the encoded image data in my DB with the one I generated from the above named website, my image was regenerated and viewable. So the real is with the encoding.
Had once a similar issue, solved it by replacing the File.read method with IO.binread(imageLoc). Hope it helps. :)

Resources