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">
Related
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.
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
I'm trying to display an image on a splash screen and it's being stretched upon display. The image I'm trying to display is a simple bmp file. Any ideas why?
In SplashWindow.xaml:
<Window ... SizeToContent="WidthAndHeight">
<Grid>
...
<Image Grid.Row="0" Source="{Binding SplashImage}"></Image>
</Grid>
</Window>
In SplashViewModel.cs
public ImageSource SplashImage
{
get
{
return ImageUtilities.GetImageSource(_splashImageFilenameString);
}
}
From ImageUtilities.cs
public static ImageSource GetImageSource(string imageFilename)
{
BitmapFrame bitmapFrame = null;
if(!string.IsNullOrEmpty(imageFilename))
{
if(File.Exists(imageFilename))
{
bitmapFrame = BitmapFrame.Create(new Uri(imageFilename));
}
else
{
Debug.Assert(false, "File " + imageFilename + " does not exist.");
}
}
return bitmapFrame;
}
In your XAML, set the "Stretch" property to "None" (I believe it defaults to "Fill"):
<Image Grid.Row="0" Source="{Binding SplashImage}" Stretch="None"></Image>
You can also explicitly set the Width and Height properties if you like.
typically you want:
<Image Source="{Binding ImagePath}" Stretch="Uniform" />
this value will enlarge the image as much as possible while still fitting entirely within your parent control. It will not distort it, it will maintain the source's aspect ratio. If you use
Stretch="None"
it will display the image (or what fits of the image, it will clip) at it's native size which is not always what you want.
Anyhow, you have some choices but setting Stretch to what you want will effect the way the image stretches or not.
WPF doesn't display things in pixels (at least not on the surface). WPF displays things in device-independent units, specifically 1/96ths of an inch.
Image files have DPI/resolution information in their metadata which tells the computer how big that image is in inches. If your image file has been programmed to say it is 8 inches wide, that's going to be equal to 768 units in WPF, regardless of how many pixels the image is.
You can use an image editing program like Photoshop or equivalent to change the DPI of your image, or just give it an explicit Width and Height when you display it in WPF.
I have an image element in one xaml that is accessed and displayed on a different xaml. Interestingly the image automatically resizes itself to fit the grid while also maintaining the aspect ratio.
However I have Path elements that serve as borders to the images. When the Path elements are displayed they display at their normal size and I just cannot get them fit the image as borders no matter how I set the dimensions, whether it's programmatically or in xaml. These Path elements are imported from an Adobe Illustrator file.
This is how the code from XAML files looks,
<ImageDisplay.xaml>
<grid>
<image name="imageToDisplay"/>
</grid>
</ImageDisplay.xaml>
<ImageBorder.xaml>
<Path Element 1>
<Path Element 2>
<Path Element 3>
<Path Element 4>
</ImageBorder.xaml>
<SubMain.xaml>
<local:ImageDisplay />
<local:ImageBorder />
<otherelements />
</SubMain.xaml>
<Main.xaml>
<SubMain.xaml />
<SubMain.xaml />
<SubMain.xaml />
</Main.xaml>
So in the Main.xaml the SubMain.xaml is allotted a certain width and height and the ImageDisplay elements re-size and fit themselves perfectly without the help of code. But the same does not happen for ImageBorder element. What might I be doing wrong here?
You can use ActualWidth and ActualHeight of the image after it autoresizes and set the width and height of paths.
Image class
Path class
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.