I found many samples of displaying images from a resource in a Windows Store app and got it to display images within a sample, but I would require the flipview to show images in a directory, or at least to show image file names I provide by code. With everything I tried so far the flipview remains empty. I maybe missing something obvious, this is the relevant part of the XAML:
<FlipView x:Name="flipView1" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="809,350,9,7" Width="548" Height="411" >
<FlipView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Path=Image }" Stretch="Uniform"/>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
this works, but it requires me to add the images a resource first....
ImageBrush brush1 = new ImageBrush();
brush1.ImageSource = new BitmapImage(new Uri("ms-appx:///Assets/P1000171.jpg"));
FlipViewItem flipvw1 = new FlipViewItem();
flipvw1.Background = brush1;
flipView1.Items.Add(flipvw1);
but (for example) this doesn't:
string name = String.Format(#"c:\temp\P1000171.JPG");
Uri uri = new Uri(name);
BitmapImage img = new BitmapImage(uri);
flipView1.Items.Add(img);
What do I miss?
In the meantime I've found the answer myself which I now add for future readers. The above example won't work because a Windows 8 app isn't allowed to access most of the PC's directories without the user having selected one using a FolderPicker. The program can re-use that directory later with:
StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedFolderToken", folder);
I've changed the above XAML here:
<Image Source="{Binding}" Stretch="UniformToFill"/>
The Task below will show all .JPG files in the Pictures library in a Flipview, if, in the Package.appxmanifest, Capabilities, "Pictures library" has been checked:
public async Task flipviewload()
{
IReadOnlyList<StorageFile> fileList = await picturesFolder.GetFilesAsync();
var images = new List<BitmapImage>();
if (fileList != null)
{
foreach (StorageFile file in fileList)
{
string cExt = file.FileType;
if (cExt.ToUpper()==".JPG")
{
Windows.Storage.Streams.IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
using (Windows.Storage.Streams.IRandomAccessStream filestream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
BitmapImage bitmapImage = new BitmapImage();
await bitmapImage.SetSourceAsync(fileStream);
images.Add(bitmapImage);
}
}
}
}
flpView.ItemsSource = images;
}
Related
I'm new to UWP development & I'm just showing image in my app from the Music Library.
Infact, I have added Music Library in the app's "Capabilities" & I can confirm that I have access to Music Library as I can read & write files in it.
But when I try to load a image in XAML, it just does not shows...
<Image Height="200" Width="200" Source="C:/Users/Alex Mercer/Music/Album/albumArt.png" />
Please help me understand & solve the problem.
😃 Thanks a lot!
Although we enable the corresponding capabilities, accessing files through paths is still strictly restricted in UWP.
In fact, it is not a good idea to write the full path in XAML, because you cannot guarantee that the path must exist on the device where the application is installed.
To display the pictures in the music library, you can do this:
xaml
<Image Height="200" Width="200" x:Name="AlbumImage" Loaded="AlbumImage_Loaded"/>
xaml.cs
private async void AlbumImage_Loaded(object sender, RoutedEventArgs e)
{
try
{
var albumFolder = await KnownFolders.MusicLibrary.GetFolderAsync("Album");
var albumPic = await albumFolder.GetFileAsync("albumArt.png");
var bitmap = new BitmapImage();
using (var stream = await albumPic.OpenAsync(FileAccessMode.Read))
{
await bitmap.SetSourceAsync(stream);
}
AlbumImage.Source = bitmap;
}
catch (FileNotFoundException)
{
// File or Folder not found
}
catch (Exception)
{
throw;
}
}
I want to convert a pdf file to an image UI control in UWP using c#, xaml.
I've read another way to use the Flip Viewer, but I need each image file of the converted PDF file.
so I modified a bit of the existing sample To open a pdf file.
And my problem is that the quality of the converted image file is extremely bad.
I can not even see the letters.
but this quality problem is same on other pdf sample.
Take a look at my code.
private PdfDocument pdfDocument;
private async void LoadDocument()
{
pdfDocument = null;
//Output means my image UI control (pdf image will be added)
Output.Source = null;
//PageNumberBox shows current page
PageNumberBox.Text = "1";
var picker = new FileOpenPicker();
picker.FileTypeFilter.Add(".pdf");
StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
try
{
pdfDocument = await PdfDocument.LoadFromFileAsync(file);
}
catch (Exception ex)
{
}
if (pdfDocument != null)
{ // I use this text to move page.
PageCountText.Text = pdfDocument.PageCount.ToString();
}
}
uint pageNumber;
if (!uint.TryParse(PageNumberBox.Text, out pageNumber) || (pageNumber < 1) || (pageNumber > pdfDocument.PageCount))
{
return;
}
Output.Source = null;
// Convert from 1-based page number to 0-based page index.
uint pageIndex = pageNumber-1 ;
using (PdfPage page = pdfDocument.GetPage(pageIndex))
{
var stream = new InMemoryRandomAccessStream();
await page.RenderToStreamAsync(stream);
BitmapImage src = new BitmapImage();
Output.Source = src;
await src.SetSourceAsync(stream);
}
}
And this is my xaml code.
<Grid>
<ScrollViewer >
<TextBlock Name="ViewPageLabel"VerticalAlignment="center">Now page</TextBlock>
<TextBox x:Name="PageNumberBox" InputScope="Number" Width="30" Text="1" TextAlignment="Right" Margin="5,0,5,0"
AutomationProperties.LabeledBy="{Binding ElementName=ViewPageLabel}"/>
<TextBlock VerticalAlignment="Center">of <Run x:Name="PageCountText"/>.</TextBlock>
</ScrollViewer>
</Grid>
Is there any suggestions?
Please help me.
Thanks for reading this.
Ran into this issue recently, didn't see any definitive answer here, so here it goes:
JosephA is on the right track, but PdfPageRenderOptions does not have anything about image fidelity/quality or anything like that like I had hoped. However, it does allow you to specify image dimensions. All you have to do is scale up the dimensions.
I suspect what's going on is that the PDF has a scale that it would "like" to use, which is smaller than the image you want to draw. Without specifying dimensions, it's drawing the "small" image and then it's getting scaled up, causing the blurriness.
Instead, if you tell it to draw the image at a higher resolution explicitly, it will do PDF magic to make those lines crisper, and the resulting raster image won't have to scale/blur.
PdfPage page = _document.GetPage(pageIndex);
await page.RenderToStreamAsync(stream, new PdfPageRenderOptions {
DestinationWidth = (uint)page.Dimensions.MediaBox.Width * s,
DestinationHeight = (uint)page.Dimensions.MediaBox.Height * s
});
Something like this helps, where "s" is the scale factor to achieve the dimensions you need.
PdfPage.Dimensions has a number of different properties other than just "MediaBox" that you may want to explore as well depending on your use case.
It sounds like you are encountering the common problem where you need to dynamically adjust the resolution the PDF page is rendered at to an image.
I am not familiar with the that PDF library however it appears you need to use the RenderToStreamAsync() overload that takes a PdfPageRenderOptions parameter to accomplish this.
This is the code I am using for binding image in XAML
<Border toolkit:TiltEffect.IsTiltEnabled="true" Height="350" Width="400" Grid.ColumnSpan="3">
<Grid Height="350" Width="400" Margin="70,0,70,0" x:Name="Container1">
<Grid.Background>
<ImageBrush ImageSource="{Binding ImageCollection[0]}" Stretch="Uniform" AlignmentX="Left" AlignmentY="Center"/>
</Grid.Background>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<i:InvokeCommandAction Command="{Binding ImageTapCommand}" CommandParameter="CONTAINER0"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Grid>
</Border>
Likewise I am using 4 border for displaying my recent images.
In my ViewModel I am using the below method for reading image from isolated storage.
public Stream GetFileStream(string filename, ImageLocation location)
{
try
{
lock (SyncLock)
{
if (location == ImageLocation.RecentImage)
{
filename = Constants.IsoRecentImage + #"\" + filename;
}
using (var iSf = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!iSf.FileExists(filename)) return null;
var fs = iSf.OpenFile(filename, FileMode.Open, FileAccess.Read);
return fs;
}
}
}
catch (Exception ex)
{
return null;
}
}
And after getting the stream I will use this below written method four building the WritableBitmap for UI binding
private WriteableBitmap BuildImage(Stream imageStream)
{
using (imageStream)
{
var image = new BitmapImage();
image.SetSource(imageStream);
return new WriteableBitmap(image);
}
}
In this case my issue is after navigating to and from my page for two - three times. The app crashes on BuildImage() method where I am using " image.SetSource(imageStream);" method. I tried many alternatives but failed. The exception I am getting is "System.OutOfMemoryException "
I tried Image control instead of Image brush.
I tried Bitmap instead of WritableBitmap etc. but the result is same.
The app crashing rate will reduce if I use small images. But the crash rate is high with the images taken through camera.
I am trying for a solution to this issue for last one week, But didn't find any alternative to fix the issue.
I found a link that talks about similar issue But didn't get many to solve the issue
Try this,
var bitmapImage = new BitmapImage();
bitmapImage.SetSource(stream);
bitmapImage.CreateOptions = BitmapCreateOptions.None;
var bmp = new WriteableBitmap((BitmapSource) bitmapImage);
bitmapImage.UriSource = (Uri) null;
return bmp;
Silverlight caches images by default to improve performance. You should call
image.UriSource = null after using the BitmapImage to dispose of the resources.
Are you reseting/disposing the IsolatedStorageFileStream and the IsolatedStorageFile after you use them?
Have you tried forcing the garbage collector to run to see if that makes any difference.
GC.Collect();
This is not intended as a solution - you should never have to call GC.Collect, but it might help determine whether your problem is a memory leak or just a delay in the memory being reclaimed.
How to read an existing html file in the WebBrowser control in WP7?
I have tried:
Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("abc.htm");
StreamReader reader = new StreamReader(stream);
string html = reader.ReadToEnd();
Browser.NavigateToString(html);
Browser.Navigate(new Uri("abc.htm", UriKind.Relative));
var rs = Application.GetResourceStream(new Uri("abc.htm", UriKind.Relative));
StreamReader sr = new StreamReader(rs.Stream);
string html = sr.ReadToEnd();
Browser.NavigateToString(html);
All three are not working. The methods 1 and 3 gives NullReferenceException because the stream returns null, basically it is not reading my html file.
What is the problem here? How can i fix it?
When you use number 3, make sure your HTML file has its build type set to 'Content'.
If you want to use option 2 you must first copy the file to isolated storage if it needs to reference any other files as it's not possible to use relative paths (to other docs, images, js, css, etc.) within a document if loaded directly from the XAP.
Ok, so here's a sample:
in MainPage.xaml:
<Grid x:Name="LayoutRoot" Background="Transparent">
<phone:WebBrowser x:Name="MyBrowser"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
</Grid>
in MainPage.xaml.cs
public MainPage()
{
InitializeComponent();
var rs = Application.GetResourceStream(new Uri("abc.html", UriKind.Relative));
StreamReader sr = new StreamReader(rs.Stream);
string html = sr.ReadToEnd();
this.MyBrowser.NavigateToString(html);
}
make sure you have the file "abc.html" (check for typo, your sample code is "abc.htm") in your project's root folder. Build action as 'Content' and 'copy to output directory' as 'Do not copy'. It should display the page in the browser.
For the first and third :
set the Build Action Property of the html file to "Resource"
otherwise it will give you NullReferenceException
For the second :
browser control in WP7 cannot navigate directly to a html file added in the project. To do this the html file must be located in Isolated Storage.
Try that, i hope it'll work.
(Mark answer, if its helpful).
It works fine if you add the command inside a button like:
private void htmlLoader(object sender, EventArgs e)
{
var rs = Application.GetResourceStream(new Uri("abc.html", UriKind.Relative));
StreamReader sr = new StreamReader(rs.Stream);
string html = sr.ReadToEnd();
this.MyBrowser.NavigateToString(html);
}
In my application i had done this to map my uri in app.xaml.cs, now the thing is if my application deactivates my application exits on MainPage.xaml rather than Eula.xaml. Else the app exits on the same page on which it starts.
In App.xaml
<UriMapper:UriMapper x:Name="mapper">
<UriMapper:UriMapping Uri="/MainPageOrEULA.xaml"/>
</UriMapper:UriMapper>
and in App.xaml.cs
// Get the UriMapper from the app.xaml resources, and assign it to the root frame
UriMapper mapper = Resources["mapper"] as UriMapper;
RootFrame.UriMapper = mapper;
// Update the mapper as appropriate
IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication();
if (isoStorage.FileExists("DataBase/MyPhoneNumber.txt"))
{
mapper.UriMappings[0].MappedUri = new Uri("/MainPage.xaml", UriKind.Relative);
}
else
{
mapper.UriMappings[0].MappedUri = new Uri("/EULA.xaml", UriKind.Relative);
}
Please guide me for the same.
Regards,
Panache.
I suggest that rather than having a whole separate page (which interrupts navigation as you've noticed), just put a grid or usercontrol containing the EULA on the front page that isn't visible. When the user first opens the page, you show the grid/usercontrol, but on subsequent runs, you don't.
<Grid x:Name="LayoutRoot">
<Grid Name="EULA" Visibility="Collapsed" >
<TextBlock Text = "You agree ...." />
<Button Grid.Row="1" Content="I Agree" Click="AgreeClick" />
</Grid>
<Grid Name="MainGrid" >
....
Then in your code behind you can add your test to the loaded event
private void MainPageLoaded()
{
IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication();
if (!isoStorage.FileExists("DataBase/MyPhoneNumber.txt"))
{
EULA.Visibility = Visibility.Visible;
MainGrid.Visibility = Visibility.Collapsed;
}
}
Then when the "I agree" button is clicked you can store the file and show the main grid
private void AgreeClick(....)
{
// Create isolated storage file
....
// Hide eula control
EULA.Visibility = Visibility.Collapsed;
MainGrid.Visibility = Visibility.Visible;
}