Please, help is needed. In this code have to be stupid mistake but what it is? If I run this very simple code I can load and change bitmap image only once. At first time it runs ok but if I like to change the image again (press the button) the first image remains. Why?
XAML
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel>
<Button x:Name="AddProfilePicture" HorizontalAlignment="Center" Click="AddProfilePicture_Click">
<Grid Width="200" Height="200">
<Ellipse Width="200" Height="200">
<Ellipse.Fill>
<ImageBrush x:Name="ImageBrush_ProfilePicture" Stretch="UniformToFill"/>
</Ellipse.Fill>
</Ellipse>
</Grid>
</Button>
</StackPanel>
</Grid>
CODE
private async void AddProfilePicture_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker profilePictureFilePicker = new FileOpenPicker();
profilePictureFilePicker.ViewMode = PickerViewMode.Thumbnail;
profilePictureFilePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
profilePictureFilePicker.FileTypeFilter.Add(".jpg");
StorageFile userSelectedProfilePicture = await profilePictureFilePicker.PickSingleFileAsync();
//MAKE SURE U HAVE THIS FILE (ProfilePicture.jpg) IN FOLDER ALREADY....
StorageFile destinationFileImage = await StorageFile.GetFileFromPathAsync(ApplicationData.Current.LocalFolder.Path + #"\" + "ProfilePicture.jpg");
await userSelectedProfilePicture.CopyAndReplaceAsync(destinationFileImage);
Uri profilePictureBitmapURI = new Uri(ApplicationData.Current.LocalFolder.Path + #"\" + "ProfilePicture.jpg");
BitmapImage profilePictureBitmap = new BitmapImage(profilePictureBitmapURI);
ImageBrush_ProfilePicture.ImageSource = profilePictureBitmap;
}
This code doesn't have any extra check. It means the image 'ProfilePicture.jpg' have to be in a folder before running app. Code works well at first run but on the second run (press the button again and selecting new picture) cannot change output on screen even the source change in folder.
While creating BitmapImage set CreateOptions to IgnoreImageCache.
var profilePictureBitmap = new BitmapImage(profilePictureBitmapURI) {CreateOptions = BitmapCreateOptions.IgnoreImageCache};
Try to add the Load() method and see if that helps:
private async void AddProfilePicture_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker profilePictureFilePicker = new FileOpenPicker();
profilePictureFilePicker.ViewMode = PickerViewMode.Thumbnail;
profilePictureFilePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
profilePictureFilePicker.FileTypeFilter.Add(".jpg");
StorageFile userSelectedProfilePicture = await profilePictureFilePicker.PickSingleFileAsync();
//MAKE SURE U HAVE THIS FILE (ProfilePicture.jpg) IN FOLDER ALREADY....
StorageFile destinationFileImage = await StorageFile.GetFileFromPathAsync(ApplicationData.Current.LocalFolder.Path + #"\" + "ProfilePicture.jpg");
await userSelectedProfilePicture.CopyAndReplaceAsync(destinationFileImage);
Uri profilePictureBitmapURI = new Uri(ApplicationData.Current.LocalFolder.Path + #"\" + "ProfilePicture.jpg");
BitmapImage profilePictureBitmap = new BitmapImage(profilePictureBitmapURI);
ImageBrush_ProfilePicture.ImageSource = profilePictureBitmap;
ImageBrush_ProfilePicture.Load()
}
Related
I have a UWP that allows me to display a pdf from a website url. It's also able to display a pdf from the project folder.
However, I am trying to display a picture placed in the local app folder with a button.
I have tried searching through google and found no workable solution. Does anyone have any suggestions to help?
You can refer to the sample in the official documentation Image Class.
Setting Image.Source.
Setting Image.Source using code.
Or use FileOpenPicker to select a picture in a local folder.
Page.xaml
<Image x:Name="image"></Image>
<Button Content="Button" Click="Button_Click"/>
Page.xaml.cs
private async void Button_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker picker = new FileOpenPicker();
picker.FileTypeFilter.Add(".jpg");
picker.FileTypeFilter.Add(".jpeg");
picker.FileTypeFilter.Add(".png");
picker.FileTypeFilter.Add(".bmp");
picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
var file = await picker.PickSingleFileAsync();
if (file != null)
{
IRandomAccessStream ir = await file.OpenAsync(FileAccessMode.Read);
BitmapImage bi = new BitmapImage();
await bi.SetSourceAsync(ir);
image.Source = bi;
}
}
UPDATE
Put your image path in Source.
Page.xaml
<Image x:Name="image" Width="200" Source="Assets/StoreLogo.png" Visibility="Collapsed"></Image>
<Button Content="Button" Click="Button_Click"/>
Page.xaml.cs
private void Button_Click(object sender, RoutedEventArgs e)
{
if (image.Visibility == Visibility.Collapsed)
{
image.Visibility = Visibility.Visible;
}
else
{
image.Visibility = Visibility.Collapsed;
}
}
Save the folder path for loading
I uploaded images from a folder selected by a FilePicker but, I would like (after the first time I chose the folder) that when I start the app, automatically loads the selected folder, without having to retrieve it from the picker file every time.
MainPage.xaml:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button x:Name="btnPickFolder"
Content="Pick Folder"
Click="btnPickFolder_Click"
HorizontalAlignment="Left"
Margin="10,10,0,0"
VerticalAlignment="Top"/>
<Grid x:Name="GridShowImages" HorizontalAlignment="Stretch" Margin="20,52,20,20">
<GridView x:Name="ListViewImage" ItemsSource="{x:Bind listImage}">
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:SingleImage">
<Image Source="{x:Bind ImageToLoad}"
Margin="5"
Width="300"
Height="168.75"/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
</Grid>
MainPage.xaml.cs:
public sealed partial class MainPage : Page
{
ObservableCollection<SingleImage> listImage = new ObservableCollection<SingleImage>();
public MainPage()
{
this.InitializeComponent();
}
private async void btnPickFolder_Click(object sender, RoutedEventArgs e)
{
FolderPicker folderPicker = new FolderPicker();
folderPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
folderPicker.FileTypeFilter.Add("*");
StorageFolder SelectFolderToLoad = await folderPicker.PickSingleFolderAsync();
StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedFolderToken", SelectFolderToLoad);
foreach (var file in await SelectFolderToLoad.GetFilesAsync())
{
BitmapImage bmp = new BitmapImage();
IRandomAccessStream stream = await file.OpenReadAsync();
bmp.SetSource(stream);
listImage.Add(new SingleImage() { ImageToLoad = bmp });
StorageFolder StorageParent = await file.GetParentAsync();
}
}
}
SingleImage class:
public class SingleImage
{
public BitmapImage ImageToLoad { get; set; }
}
you can use the FutureAccesList (https://learn.microsoft.com/en-us/uwp/api/Windows.Storage.AccessCache.StorageApplicationPermissions#Windows_Storage_AccessCache_StorageApplicationPermissions_FutureAccessList) to keep access to the selected folder / file after your app restarts
I want to add a Background colour and 9 Foreground Image to 9 buttons from code.
I wish to change the images from C# not in WPF / xaml.
The Background colour works OK using:
button1.Background.SetValue(SolidColorBrush.ColorProperty, Windows.UI.Colors.Red);
Windows forms has an easy solution using:
pictureBox1.Image = Properties.Resources.P1; // this does not work for UWP
What I have tried so far ends up in error messages:
I have changed the Build Action property of P1.png from Content to PRIResource with no success.
string url = "../../Images/P1.png";
//string url = "PW.png";
image1.Source = new BitmapImage(new Uri(url, UriKind.Relative)); //.Uri cannot be converted into a Windows.Foundation.Uri.
//image1.Source = new BitmapImage(new Uri(url, UriKind.Absolute)); //format of url could not be determined
<Button x:Name="button1" Content="Button" Grid.Column="0" Grid.Row="0"
Tag="1" Background="Gray" Padding="0" UseLayoutRounding="False"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Click="button1_Click">
<Button.Foreground>
<ImageBrush Stretch="Fill" ImageSource="P1.PNG"/>
</Button.Foreground>
</Button>
Solution:
To insert image to Button in C# using VS2015, UWP and Windows 8.1:
Add an Image to the front of your Button. eg Name = button1 and imageX.
Ensure that you set “Build Action” Properties of *.png to Content.
enter code hereImageBrush imageBrush = new ImageBrush();
imageBrush.ImageSource = new BitmapImage(new Uri("ms-appx:///Images/PW.PNG"));
button1.Background = imageBrush;
BitmapImage bitImage = new BitmapImage();
bitImage.UriSource = new Uri("ms-appx:///Images/PW.PNG");
imageX.Source = bitImage;
Thanks Romasz for your assistance.
Currently I am able to select multiple files but when I click open, the selected images are not being shown. Instead, "Windows.UI.XAML.Media.Imaging.BitmapImage" appears as a text. The FlipView functionality is still there though. What am I doing wrong?
XAML.
<FlipView x:Name="flpView" Grid.Row="1" Margin="10, 10, 10, 10">
<Image x:Name="images" Stretch="UniformToFill" />
</FlipView>
Behind code.
public async Task flipviewload()
{
// Add code to perform some action here.
Windows.Storage.Pickers.FileOpenPicker openPicker = new Windows.Storage.Pickers.FileOpenPicker();
openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
openPicker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
// Filter to include a sample subset of file types.
openPicker.FileTypeFilter.Clear();
openPicker.FileTypeFilter.Add(".bmp");
openPicker.FileTypeFilter.Add(".png");
openPicker.FileTypeFilter.Add(".jpeg");
openPicker.FileTypeFilter.Add(".jpg");
var files = await openPicker.PickMultipleFilesAsync();
var images = new List<BitmapImage>();
if (files != null)
{
//foreach (StorageFile Images in files)
foreach (var file in files)
{
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.Source = bitmapImage;
images.Add(bitmapImage);
}
}
}
flpView.ItemsSource = images;
}
I also added Task foo = flipviewload(); in my public MainPage();
You get this result because default rendering calls ToString() on the item, which prints the name of the class. If you want to display the image you have to supply an ItemTemplate:
<FlipView x:Name="flpView" Grid.Row="1" Margin="10, 10, 10, 10">
<FlipView.ItemTemplate>
<DataTemplate>
<Image Stretch="UniformToFill" Source="{Binding}" />
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
I'm developping a silly application that:
- opens a pictures from media library,
- puts the chosen image in a grid element (which contains a TextBlok element)
- save the pictures in the "saved pictures" album.
My XAML code is:
<controls:PanoramaItem Header="Image Selection" Height="652">
<Grid Name="markedImage" Margin="0,0,4,89">
<Image x:Name="img" Stretch="Fill" Margin="0,0,0,10"></Image>
<TextBlock x:Name="text" Text="Hello!">
<i:Interaction.Behaviors>
<el:MouseDragElementBehavior ConstrainToParentBounds="True"/>
</i:Interaction.Behaviors>
</TextBlock>
</Grid>
and the code to open and save the chosen picture is:
private void photoChooserTask_Completed(object sender, PhotoResult e)
{
try
{
BitmapImage image = new BitmapImage();
image.SetSource(e.ChosenPhoto);
WriteableBitmap wbp = new WriteableBitmap(image);
this.img.Source = image;
height = image.PixelHeight;
width = image.PixelWidth;
MessageBox.Show("H: " + height + "\t" + "W: " + width);
}
catch
{
MessageBox.Show("Disconnect your device from Zune");
}
}
private void save_Click(object sender, System.EventArgs e)
{
WriteableBitmap marked = new WriteableBitmap(this.markedImage, null);
ThreadPool.QueueUserWorkItem(callback =>
{
MemoryStream ms = new MemoryStream();
marked.SaveJpeg(ms, (width * 2), (height * 2), 0, 100);
using (MediaLibrary lib = new MediaLibrary())
lib.SavePicture("Test", ms.ToArray());
});
MessageBox.Show("H: " + marked.PixelHeight + "\t" + "W: " + marked.PixelWidth);
// wbm.SaveToMediaLibrary("SavedPicture.jpg", true);
MessageBox.Show("Picture saved successfully");
}
I can't post pictures because I'm a new user, anyway pictures (orignal and saved pic) have the same height and width but they look different
I think that the problem is the grid dimension and Stretch property. I tried different combo but results were not good.
Some suggestion?
edit: i earned reputation point
original pics is
saved pics is
if you open both in another window, you can see the difference
The problem is quite simple to understand: basically, you're doing a 'screenshot' of your grid. Therefore, the size of the generated picture is the same as the size of the grid. Hence the down-sampled picture.
Fixing that however can be tricky. I can suggest two ways:
Recreate programmatically the grid and its contents in the code-behind, then create the WriteableBitmap from this new grid
Remove the grid from its parent control just before executing your image-generation code (then the grid will be able to use as much space as needed), and add it back afterwards:
<Grid x:Name="ParentGrid" Grid.Row="1" Width="200" Height="150">
<Grid Name="markedImage" Margin="0,0,4,89">
<Image x:Name="img" Source="Images/Test.jpg" Stretch="Fill" Margin="0,0,0,10"></Image>
<TextBlock x:Name="text" Text="Hello!">
<i:Interaction.Behaviors>
<el:MouseDragElementBehavior ConstrainToParentBounds="True"/>
</i:Interaction.Behaviors>
</TextBlock>
</Grid>
</Grid>
And the code-behind:
this.ParentGrid.Children.Remove(this.markedImage);
WriteableBitmap marked = new WriteableBitmap(this.markedImage, null);
MemoryStream ms = new MemoryStream();
marked.SaveJpeg(ms, 1349, 1437, 0, 100);
using (MediaLibrary lib = new MediaLibrary())
lib.SavePicture("Test", ms.ToArray());
MessageBox.Show("H: " + marked.PixelHeight + "\t" + "W: " + marked.PixelWidth);
MessageBox.Show("Picture saved successfully");
this.ParentGrid.Children.Add(this.markedImage);