I'm trying to load an image in a local path to a Silverlight image control. This is an out of browser application. When I load the image using a stream it's always flipped upside down.
Any idea why? This happens for large images only.
FileName here gives the full path to local file system, like C:\imageFullPath\image.jpg.
Please help. Following is the code.
------ In Model side------------------------
public BitmapImage DisplayImage
{
get
{
if (!string.IsNullOrWhiteSpace(FileName))
{
var b = new BitmapImage();
b.SetSource(System.IO.File.OpenRead(FileName));
return b;
}
return null;
}
}
------ In Silverlight View side------------------------
<Image Source="{Binding DisplayImage, Mode=TwoWay}" Width="450" Height="250" Margin="0,0,0,0"/>
What i see when debugging
BMP are normally stored "upside-down" with the pixels in reverse order from bottom to top, but can use a negative height in the file header to indicate the image is stored top-to-bottom, so perhaps you have such an image.
Does this happen with all images, or just that one?
You could try changing the way the image is loaded, using a Uri in the constructor instead of calling SetSource() with a Stream, as it may account for the header and read the file differently:
var b = new BitmapImage(new Uri(FileName));
return b;
Or, if that doesn't help, you can apply a transform to flip every image, but that doesn't solve the underlying problem:
<Image Source="{Binding DisplayImage, Mode=TwoWay}" Width="450" Height="250" Margin="0,0,0,0">
<Image.RenderTransform>
<ScaleTransform ScaleY="-1" />
</Image.RenderTransform>
</Image>
Related
My application is a windows 8 store app . It takes a photo with the camera, then i draw over the image, and i want to save both the image and the drawing. What i have come result is only the drawing. i lost the background image.
Below you have my implementation :
XAML code:
(in place of having an Image control for the photo taken and a canvas for the drawing, i binded the photo = CurrentPicture as the background of the canvas)
<Canvas Grid.Row="1"
Grid.Column="0"
x:Name="InkCanvas"
Background="{Binding CurrentPicture, Converter={StaticResource WPhotoToCanvasBackgroundConverter}}"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="0"
Width="1024"
Height="768" />
C# :
private async Task<IPhoto> RenderCanvasToPNG()
{
MemoryStream stream = await WriteableBitmapRenderExtensions.RenderToPngStream(InkCanvas);
var bitmap = new BitmapImage();
await bitmap.SetSourceAsync(System.IO.WindowsRuntimeStreamExtensions.AsRandomAccessStream(stream));
byte[] byteme = stream.ToArray();
var photo = new WPhotos(null, byteme, bitmap.PixelWidth, bitmap.PixelHeight, bitmap);
return photo;
}
Thank you a lot for your time :)
There isn't a direct way to extract the pixels from a BitmapImage or ImageBrush. I believe WriteableBitmapEx fakes this by finding the image's source URI and looking that up, but this method works only if the image was loaded from a URI. If it was streamed into the image then there is no way to extract it.
Instead, you can use RenderTargetBitmap to render your UIElements to a bitmap. Since this uses the Xaml rendering engine it has access to the ImageBrush used for the Canvas' background and should completely render the Canvas and its contents (barring non-renderable contents such as a MediaElement or SwapChainPanel).
I'm using PrintDialog.PrintVisual() to print my viewmodel. For this I use binding on a dictionary:
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="329" Height="204">
<Image Source="{Binding Details.Properties[Imagedata].ImageStream}" Stretch="Fill" Width="95" Height="122" Canvas.Left="14" Canvas.Top="41"/>
<Image Source="{Binding Details.Properties[Signature].ImageStream}" Stretch="Fill" Height="25" Width="100" Canvas.Left="122" Canvas.Top="143"/>
</Canvas>
If I put this Canvas on my WPF window, it's showing fine. But if I want to print it, it's using the first image on my second image. In debugger I checked after UpdateLayout the Image.Source - both are right. The next step is PrintDialog.Printvisual(canvas, "print"); The output is as described but not the same every time. Sometimes the first image is even repeated in the second Image.
Why does this happen?
UPDATE: I found a workaround: I search for all Image elements, copy the ImageSource into a MemoryStream and create a new BitmapImage out of it. It's not nice, but it works right now. If anybody could explain, why this works, it would be great.
I have an image that its size is relatively big (say 10K by 10K).
To show this image, I use an image control and set its stretch mode to StretchToFill.
Now I want to draw a line on this image and I have the line position (start and end point) based on original image size (say from (2000,1000) to (8000,6000).
How can I convert these values to screen coordinates so I can draw on image?
If I had the actual size of image, I can do this, but it seems that I can not bind to actual height and actual width of image in viewModel.
You could put the Image and the Line in a Viewbox:
<Viewbox Stretch="UniformToFill">
<Grid>
<Image Source="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"/>
<Line Stroke="White" StrokeThickness="5" X1="100" Y1="100" X2="1000" Y2="500"/>
</Grid>
</Viewbox>
I would like to paint Images to the XAML page in Windows Store App.
The main goal is that:
Adding Images (e.g. flower leaf) to a circle on the center like that:
I have a simple solution to that, but its is very redundant.
<Image Height="200" Width="200" Source="{Binding ActualImage.NormalUri}">
<Image.RenderTransform>
<RotateTransform Angle="12"></RotateTransform>
</Image.RenderTransform>
</Image>
... // And 28 other like these
<Image Height="200" Width="200" Source="{Binding ActualImage.NormalUri}">
<Image.RenderTransform>
<RotateTransform Angle="360"></RotateTransform>
</Image.RenderTransform>
</Image>
How can I do that with a binding of a Image collection? What XAML control should I use?
Use a custom class which inherits from ItemsControl. You can then override the necessary functions, such as ones to determine the angle to rotate between each item. I think it's likely you'll want to use this PrepareContainerForItemOverride for this.
One thing to note that you will have to do is to define a new ItemsPanel. The default is a StackPanel, which will not work. You'll likely want to use something like a Canvas, which allows you to explicitly position items in it.
The Solution of Nate Diamond is much more nicer and better, but I solved it from code-behind for earn the easier way:
foreach (Petal petalObject in MainPageViewModel.Petals)
{
var petalImage = new Image
{
Height = petalObject.Height,
Width = petalObject.Width,
RenderTransform = new RotateTransform() {Angle = petalObject.Angle},
Source = new BitmapImage(new Uri(petalObject.NormalUri)),
};
PetalsGrid.Children.Add(petalImage);
}
In my Windows Phone 7 application, I have a large image and i want to draw another small image (from an image folder) in specific position (x, y) on top of the large image. How can I do that?
You can put the images in a canvas and position them
<Canvas>
<Image Source="BigImage.jpg"/>
<Image Source="SmallImage.jpg" Canvas.Left="100" Canvas.Top="50" />
</Canvas>
Depending on your requirements/setup you could also nest them in a Grid and use the Margin properties of the images.