ms-appx not working for image in uwp assets folder - c#

I've been stuck on this one problem for a bit and all I've found on the web seems to be a small variation of the same code involving a URI with the ms-appx scheme or baseURI. Nothing seems to work however.
Basically I have a UWP app with several pages. When I navigate to one of the pages I want to add an image from the assets folder of the app to a canvas on this page. When I do this in XAML the figure is added without difficulty.
<Grid Name="basicGrid" >
<Grid.Background>
<ImageBrush ImageSource="/Assets/kamelenrace_background.png"
Stretch="UniformToFill"/>
</Grid.Background>
<Canvas Name="GameCanvas">
<Image Source="\Assets\kameel1.png"/>
</Canvas>
</Grid>
When I try to add the figure in C# code nothing works (one example I've tried)
private Image player1 = new Image();
private Image player2 = new Image();
private bool singlePlayMode;
public CamelRacePage()
{
this.InitializeComponent();
BitmapImage p1 = new BitmapImage(new Uri("ms-appx:///Assets//kameel1.png"));
player1.Source = p1;
Canvas.SetLeft(player1, GameCanvas.Width / 2);
Canvas.SetTop(player1, GameCanvas.Width / 2);
GameCanvas.Children.Add(player1);
}
While I might be able to make it work for now using the XAML, I would really like to understand why the C# code isn't working. I'm still learning...
any help would be much appreciated...

I would really like to understand why the C# code isn't working
The issue is caused by the incorrect values of Canvas.Left and Canvas.Top setting by code snippet. Since you didn't set the Height and Width values for GameCanvas, so that you will not get the GameCanvas.Width value. If you debug the code snippet you will find the value is NaN, so that with Canvas.Left and Canvas.Top values to NaN, you cannot see the Image.
You could just delete the two code lines the code snippet will work. Or if you want to get the actual Width of GameCanvas you should get ActualWidth property. For example:
Canvas.SetLeft(player1, GameCanvas.ActualWidth / 2);
Canvas.SetTop(player1, GameCanvas.ActualHeight / 2);
GameCanvas.Children.Add(player1);
By the way, using XAML to set style and layout will be better.

Related

Wrong images loaded

I was developing an UWP app. I am using UWP "Image" control to show images in my app. All images are loaded properly most of the time. But occasionally few images not loading properly. Sometimes it is loaded in cropped version and sometimes loaded a black box which is never set from app. My code to set image:
XAML:
<Image x:Name="FavoritePen"
Source="{Binding FavPenSource, Mode=OneWay}"
Height="44"
Width="44"
Margin="0,10,10,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="Uniform"/>
CS:
private string favPenSource =
"ms-appx:///Assets/Images/NoteList/ic_main_tb_favorite_on.svg";
public string FavPenSource
{
get
{
return favPenSource;
}
set
{
SetProperty(ref favPenSource, value);
}
}
Black box loaded:
Wrong image loaded with cropped version:
Additionally, this is a very rare case, may be 1/100 frequency.
I googled and tried many solutions but it didn't help. I found that some people faced same issue but didn't find a proper solution yet. (Issue_1 , Issue_2, Issue_3 , Issue_4)
Can anyone please help me to solve the issue!!
Add View Box element, This is the x, y coordinates of the image inside the element along with the height and width. The default size is 300×150 size. Since I do not see the full container source, check if the SVG element is not beyond the parent container. You can remove the Horizontal/Vertical Alignment.
Sometimes it is loaded in cropped version and sometimes loaded a black box which is never set from app. My code to set image:
The problem is the svg file has been specified height and width property, when you render them with fix size image control, the svg content will display beyond the bound.
For this problem, please edit svg content and set it's height and width property as auto
<svg width="auto" height="auto" viewBox="0 0 469 476" version="1.1" xmlns="http://www.w3.org/2000/svg">

how to stretch/resize svgs in uwp's xaml?

Since the creators update came out, uwp can use svg images as briefly explained here (minute 3).
I have this svg (48x48) and i can use it fine, if (and only if) i set the image's width&height to 48 and the strech to none:
<Image Source="ms-appx:///Assets//check.svg" Height="48" Width="48" Stretch="None"/>
If i set the stretch to fill, the image disappears. If i increase the width and height i can see that the icon is pinned to the upper left corner of the image (screenshot with a different svg but same size). Isn't Stretch=Fill and a fixed height/width the intended way to scale an image?
It looks to my as if the stretching algorithm does not grasp that my svg is supposed to be 48x48. Am i doing it wrong, or are there workarounds?
Okay, so here is how I solved this!
YouTube Video for this!
Open the SVG file
The SVG file Width and Height - set these to auto!
I've been having the same issue all morning and was about to completely give up on Svg support, seems mad that you can't get a scalable format to scale properly...
But, I had one more go and I think I've worked this out.
It seems that you need to tell the SvgImageSource to rasterize at the SVG's original design size and then get the Image to scale it. Not sure it's a particularly helpful approach, but certainly solves it as of build 15063.
<Image Width="24" Stretch="Uniform" VerticalAlignment="Center">
<Image.Source>
<SvgImageSource UriSource="ms-appx:///Assets/salesorder.folder.plain.svg"
RasterizePixelHeight="48"
RasterizePixelWidth="48" />
</Image.Source>
</Image>
So if the SVG was 48x48 we turn it into a bitmap at 48x48 using the RasterizePixelHeight and RasterizePixelWidth values and then the image scales that to 24x24.
Hope that helps.
Update
I just re-read your question and realised that you were looking to increase the scale whereas I've been working to decrease it. Looks as though the technique still works, but as you scale up you're going to lose any sharpness of image due to the bitmap scale process. I think this points to a fundamental flaw in the current implementation. They seem to be rendering the svg as a bitmap, and we have to tell it the original size to get it to render properly, and then they allow the bitmap code to do the rest of the work.
I think it's somewhat debateable whether this is true support or an odd half way house. Somewhere someone suggested that Adobe Illustrator can generate XAML paths, I think I'm going to look at that to see whether I can get a better quality output, shame though because I really like Inkscape :-(
For me, it worked with modifying SVG file like this:
Add appropriate preserveAspectRatio property to svg tag. For me it was "xMinYMin meet".
Set viewbox property of svg tag to this template "0 0 ActualHeight ActualWidth", in my case it was "0 0 1050 805".
Set height and width of svg tag to "auto".
Now svg element is relative to Height, Width and Stretch properties you provide in your XAML page or view.
It might be needed to rebuild the project for XAML Designer to take effect.
SVG File:
<svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 1050 805" width="auto" height="auto" ... > ... </svg>
XAML File:
<Image
Width="200"
Source="ms-appx:///Assets/Photos/Illustrations/sample.svg"
Stretch="UniformToFill" />
For me it works only if you set RasterizePixelHeight and RasterizePixelWidth to the svg original resolution (e.g. document properties in Inkscape).
For me it worked without setting those Properties, but adding preserveAspectRatio="xMinYMin" to the <svg ...> tag and deleting width and height from the <svg ...> tag.

C# WPF element position not in correct place

I'm developing a vision processing application using WPF and EmguCV 3.0. My issue is that the element isn't positioned correctly on-screen. I have viewed what the padding is, and it returns all sides as 0. The ImageBox element from Emgu, which is what I am using to display the images, is encapsulated in a Windows Forms Host control. I have two other ImageBox elements, which display properly. Each of the ImageBox elements are within their own tab in a TabControl. On startup, I set the width and height properties of all the ImageBoxes and their canvases.
An additional thing to note is that the other two ImageBoxes also overflow out of their boundaries, but are reset back into the boundaries after switching back and forth between the tabs. This only happens once.
Here is a link to screenshots of what the UI looks like. http://imgur.com/a/RwG17
Additionally, here is the XAML and C# code for the ImageBoxes.
<TabItem x:Name="ImageTabControlHSV">
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="HSV" />
</StackPanel>
</TabItem.Header>
<Canvas x:Name="HSVImageCanvas">
<WindowsFormsHost>
<emui:ImageBox x:Name="HSVImageBox"/>
</WindowsFormsHost>
</Canvas>
</TabItem>
//Width and height properties are gotten from camera image.
HSVImageBox.Width = ratioWidth;
HSVImageBox.Height = ratioHeight;
HSVImageCanvas.Width = width;
HSVImageCanvas.Height = height;
HSVImageCanvas.MaxHeight = height;
HSVImageCanvas.MaxWidth = width;
Any help or suggestions would be greatly appreciated.
UPDATE: Putting a counter for how many times the problematic ImageBox has been selected and using Canvas.SetTop() and Canvas.SetLeft() seems to be a workaround. I would still like to know why the canvas is changing its position.
You might try performing a Canvas.SetTop(HSVImageCanvas, HSVImageCanvas.Top) and Canvas.SetLeft(HSVImageCanvas, HSVImageCanvas.Left).
Doug

WP7 development, change size of Image control from the code

I am developing picture viewer application and I want to add new function to it.
Till this time, I have fixed size of Image control in the XAML
Height="422" Width="444",but I want to use all possible space on the page and it is Width="447" Height="585"
<StackPanel Height="422" Width="444">
<Image Height="414" HorizontalAlignment="Center" Margin="9,6,0,0" Name="image2" Stretch="Uniform" VerticalAlignment="Center" Width="441" />
</StackPanel>
Code behind
var stream = new IsolatedStorageFileStream(path, FileMode.Open, _file);
var image = new BitmapImage();
image.SetSource(stream);
stream.Close();
if (image1 != null) image1.Source = image;
So, my question is:
How I can set the size of the Image control from the code behind, so the picture will fit to the Width="447" Height="585" size, I have both portrait and landscape oriented pictures?
I need to have portrait and landscape orientation support, so when orientation is change I would like to picture fit to new size Width="585" Height="447", how I can manage that? (I guess if I will find solution to the first, than only think I need is right event to handle this) Similar to this (http://stackoverflow.com/questions/6857142/handling-size-of-image-after-orientation-change-wp7), but I need to see some code t in order to understand.
Please, post some code or link to the tutorial, in order to prevent “classic” dialog where one person now how to do it and think it is simple and other person have now idea how it work.
You can directly change the size of image control through it's Width and Height properties.
image2.Width = "447";
image2.Height = 585;
If you want to fit in your picture in the Image Control properly then you can use property Stretch
image2.Stretch = Stretch.UnifromToFill;
For handling the orientation change handle the OrientationChanged event of your page and do the image manipulation inside it
Try this one,
when change the orientation then the following event is reaised.
private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
{
if (this.Orientation == PageOrientation.Portrait)
{
optionsup.VerticalOffset = 447;
optionsup.HorizontalOffset = 585;
}
else
{
optionsup.VerticalOffset = 585;
optionsup.HorizontalOffset = 447;
}
}
initially orientation is PortraitUp then
optionsup.VerticalOffset = 447;
optionsup.HorizontalOffset = 585;
I poor in english, if any mistakes dont mind.
Thanks for your answers guys, I did it this way: I have made <Image Height="Auto" Width="Auto" and Name="image1" Stretch="UniformToFill"/> So, the Silverlight will do all job for me.

How do you get the REAL position of objects in silverlight?

How do you get the REAL position of objects in silverlight?
I have a header image centered on the screen. When I make the browser window smaller, obviously, the header's left side goes off the screen. Finding out the actual position is good to know if you want to position objects on top of the image.
I capture the Content_Resized and I run a little test:
if (App.Current.Host.Content.ActualWidth > header.Width)
{
TEST = Canvas.GetLeft(header);
}
else
{
TEST = Canvas.GetLeft(header);
}
TEST always returns zero.
EDIT: header sits on a grid instead of a canvas. "Well, there is your problem..." So a better question might be this. How would I get the margins of an image sitting on a grid?
I probably should just answer the question but how to find the position of an element relative to another is probably something that has been answered before (by myself and others) here and elsewhere on the tinternet.
However if your goal is to place an item over an image then place the image in a Grid and then add the item as child of the Grid. That way you assign the relative position over the image as the margin of the item and let Silverlight's layout system do the rest.
As a general rule if you feel that you need to write code to move stuff about when the size of things change then unless you are writing a custom panel or something you're probably not using Silverlight layout system properly.
Edit:
Try this experiment:-
<Grid x:Name="LayoutRoot">
<Grid x:Name="headerContainer" Margin="50, 60, 0, 0" HorizontalAlignment="Left" VerticalAlignment="Top">
<Image Source="YourLargeImage" />
<Image Source="YourSmallerImage" HorizontalAlignment="Center" VerticalAlignment="Top" />
</Grid>
</Grid>
Now try changing the inner grid's Margin to move its position around the screen. Note the smaller image always remains at the top center of the large image.
I got it working.
First of all, these images are on a grid, not a canvas. But switching the grid to a canvas caused lots of other problems one of which is that I could not have the header image centered like before.
The solution was to change the margin of the smaller image sitting on top of the larger header image when the content resized like this:
blankbarimage.Margin = new Thickness((App.Current.Host.Content.ActualWidth - header.Width) / 2, 0, 0, 0);
and, by the way, you create a content resized method like this:
App.Current.Host.Content.Resized += new EventHandler(Content_Resized);
So, to answer my own question, the way you get the REAL position of object in silverlight is (if they are on a grid) by looking at their margin settings.

Categories