I want to load local html file which in the local folder to the webview, but WebView doesn't support 'ms-aspx:///' protocal, I found a solution to read the html file to stream, and then convert it to string, using NavigateToString method to load the html, it works well. But, If there's an image in the html file, the image couldn't display, anyone can help?
I have solved.
Solution:
Convert the image file to base64 string
StorageFolder appFolder = ApplicationData.Current.LocalFolder;
StorageFile file = await appFolder.GetFileAsync("SplashScreen.png");
using (var stream = await file.OpenAsync(FileAccessMode.Read))
{
var reader = new DataReader(stream.GetInputStreamAt(0));
var bytes = new byte[stream.Size];
await reader.LoadAsync((uint)stream.Size);
reader.ReadBytes(bytes);
base64 = Convert.ToBase64String(bytes);
}
Use StringBuilder to create the html string
sb.Append("<html><head><title>Image test</title></head><body><p>This is a test app!</p><img src=\"data:image/png;base64,");
sb.Append(base64);
sb.Append("\" /></body></html>");
TestWebView.NavigateToString(sb.ToString());
Try using the ms-appx-web:// scheme instead of ms-aspx:// to load html from a WebView. If that doesn't work, you may need to use the ms-appdata:// scheme to access the image if it's in your application data folder.
Some further resources that might help:
How to load a local HTML-File into Webview
URI schemes
How to reference content
Related
I create a file pdf from html template using Spring Boot, flying saucer, thymeleaf. But image is not displaying in my file.
Project structure:
code html:
<div class="col-xs-6 invoice-col-2">
<img src="../static/images/mastercard.png" alt="mastercard"></img>
</div>
When I change img tag to:
<img src="../static/images/mastercard.png" alt="mastercard" th:src="#{static/images/mastercard.png}"></img>
When I create PDF file, I get an error:
org.thymeleaf.exceptions.TemplateProcessingException: Link base "static/images/mastercard.png" cannot be context relative (/) or page relative unless you implement the org.thymeleaf.context.IWebContext interface (context is of class: org.thymeleaf.context.Context)
Try using Spring's classpath: prefix. This loads your file directly from the classpath, no matter if you are running from a .jar or within your IDE. Here is an example:
<img alt="mastercard" th:src="#{classpath:static/images/mastercard.png}" />
More information about classpath: can be found in the official documentation.
In order to embed an image in a PDF generated by Flying Saucer,
1) Convert the image to a base64 encoded string.
Path path = Paths.get("src/main/resources/static/images/mastercard.png");
String base64Image = convertToBase64(path);
Function to convert image stored in a path like shown above, to a base64 encoded string
private String convertToBase64(Path path) {
byte[] imageAsBytes = new byte[0];
try {
Resource resource = new UrlResource(path.toUri());
InputStream inputStream = resource.getInputStream();
imageAsBytes = IOUtils.toByteArray(inputStream);
} catch (IOException e) {
System.out.println("\n File read Exception");
}
return Base64.getEncoder().encodeToString(imageAsBytes);
}
2) Set the base64 encoded image in the thymeleaf context
Context context = new Context();
String image = "data:image/png;base64, " + base64Image;
context.setVariable("image", image);
String html = templateEngine.process("template", context);
3) In HTML, set the value of image as shown below:
<img th:src="${image}" style="width: 200px; height=100px"/>
4) Finally, render the HTML template to PDF
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(html); // html -> String created in Step 2
renderer.layout();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
renderer.createPDF(baos)
Now you have the byteArrayOutputStream of the generated PDF, with which you can choose to store them to a file server or serve it to a client in a format of your choice.
Use standard html src atribute and relative path from root of the project.
You can put your image in the root of the project and use it like this:
<img src="mastercard.png" />
If you want to resource folders you can set it like this:
<img src="src/main/resources/static/images/mastercard.png" />
I faced the same issue but reading image file from disk is little costly, I would suggest you go with uri-data
http://www.tothenew.com/blog/using-data-urls-for-embedding-images-in-flying-saucer-generated-pdfs/
Because you anyway going to read image to generate PDF, better keep it in template.
I am using Below Code to save image but it save image after filesavepicker save image but I want to save image direct into local folder without using
filesavepicker,Please suggest me any Solution for this, thanks in Advance.
webcam private async Task SavePhoto(IRandomAccessStream mediaStream)
{
FileSavePicker photoSavePicker = new FileSavePicker();
photoSavePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
var mediaFile = await photoSavePicker.PickSaveFileAsync();
await SaveStreamToFileAsync(mediaStream, mediaFile);
}
I want to save this stream data in image format direct to local folder without using filesavepicker.
Create the StorageFile inside the app's LocalData. Then pass this StorageFile to your function.
StorageFolder dirLocal = Windows.Storage.ApplicationData.Current.LocalFolder;
StorageFile mediaFile = await dirLocal.CreateFileAsync("mediaFile.abc");
SaveStreamToFileAsync(mediaStream, mediaFile);
Trying to read an image that is stored in the pictures library via an URI the image is never displayed (in an Image control). Reading the same image via a stream works (assuming the app hat the Picture Library capability declared of course). Reading images from the application's data folder via an URI works.
Does someone know what could be wrong?
Here is how I (unsucessfully) try to read an image via an URI:
var imageFile = (await KnownFolders.PicturesLibrary.GetFilesAsync()).FirstOrDefault();
string imagePath = imageFile.Path;
Uri uriSource = new Uri(imagePath);
var bitmap = new BitmapImage(uriSource);
this.Image.Source = bitmap;
Here is how I sucessfully read the same image via a stream:
var imageFile = (await KnownFolders.PicturesLibrary.GetFilesAsync()).FirstOrDefault();
BitmapImage bitmap;
using (var stream = await imageFile.OpenReadAsync())
{
bitmap = new BitmapImage();
await bitmap.SetSourceAsync(stream);
}
this.Image.Source = bitmap;
I need to read the image via URI because this is the fastest way to read images and is async by nature, working perfectly with data binding.
There is no URI for the pictures library. You'll need to get the StorageFile and stream it in.
The file URI you use doesn't work because the app doesn't have direct access to the PicturesLibrary and so cannot reference items there by path. The StorageFile object provides brokered access to locations that the app doesn't natively have permissions to.
i have a question. If there is a possibility at windows phone 8 at visual studio to create button event to read text file? i know about streamReader and if i declare wchich exacly file i want to read, but if i want to choose from list of files wchich i want to display. i did research on the Internet but i didint find an answer. I know i can use isolatedStorage to read music, video, image but not text files, on the app i created few files with text in it and i want users to have posibility to display one from this file, whichever they want to see. So, can you tell me how to do this?
You can use IsolatedStorage to read any file type you wish. You must of been using something like a Launcher that filters out the file type based on the Chooser.
You can open a file like this:
private async Task<string> ReadTextFile(string file_name)
{
// return buffer
string file_content = "";
// Get the local folder
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
if (local != null)
{
// Get the file
StorageFile file;
try
{
file = await local.GetFileAsync(file_name);
}
catch (Exception ex)
{
// no file, return empty
return file_content;
}
// Get the stream
System.IO.Stream file_stream = await file.OpenStreamForReadAsync();
// Read the data
using (StreamReader streamReader = new StreamReader(file_stream))
{
file_content = streamReader.ReadToEnd(); // read the full text file
streamReader.Close();
}
// Close the stream
file_stream.Close();
}
// return
return file_content;
}
If you want to get the PackageLocation (files that you added into the project like assets and images) then replace the LocalFolder with
Windows.ApplicationModel.Package package = Windows.ApplicationModel.Package.Current;
Windows.Storage.StorageFolder installedLocation = package.InstalledLocation;
With Windows Phone 8.1, File Pickers are allowed, consisting the same functionality you are expecting, so probably you might want to upgrade your app to WP8.1.
Here's more info on this API : Working with File Pickers
I'd like to create an application that receives formatted text (RTF) or html, renders it an show it page by page..
Is there any control that aims to do that?
I tried to use the RichEditBox control to load a file but it stucks during the operation:
var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(#"myFile.rtf");
using (var memstream = await file.OpenReadAsync())
{
MainText.Document.LoadFromStream(Windows.UI.Text.TextSetOptions.ApplyRtfDocumentDefaults, memstream);
}
I tried to load an HTML file this way:
var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(#"myFile.htm");
var stream = await file.OpenAsync(FileAccessMode.Read);
string app;
using (StreamReader rStream = new StreamReader(stream.AsStream()))
{
app = rStream.ReadToEnd();
}
myWebView.NavigateToString(app);
But I cannot find a way to "count" the lenght of the parsed text to chunk it in pages..
There is any other way or library to do that? Any example online?
If you want to show your HTML contents in pages then you can use RichTextBlock with RichTextBlockOverflow. RTF is not supported to RichTextBlock.
how to inject RTF file to RichTextBlock in c#/xaml Windows store app
Showing Html in WinRT with RichTextBlock or other component
XAML text display sample