Rather than declaring an image and setting the source from the xaml file, can someone do the initialization part, set the image coordinates, and set the source completely in the code?
// Create Image Element
Image myImage = new Image();
myImage.Width = 200;
// Create source
BitmapImage myBitmapImage = new BitmapImage();
// BitmapImage.UriSource must be in a BeginInit/EndInit block
myBitmapImage.BeginInit();
myBitmapImage.UriSource = new Uri(#"C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Water Lilies.jpg");
// To save significant application memory, set the DecodePixelWidth or
// DecodePixelHeight of the BitmapImage value of the image source to the desired
// height or width of the rendered image. If you don't do this, the application will
// cache the image as though it were rendered as its normal size rather then just
// the size that is displayed.
// Note: In order to preserve aspect ratio, set DecodePixelWidth
// or DecodePixelHeight but not both.
myBitmapImage.DecodePixelWidth = 200;
myBitmapImage.EndInit();
//set image source
myImage.Source = myBitmapImage;
You need to create a new Image specifying the source:
Image myImage = new Image();
BitmapImage bitmapImage = new BitmapImage(new Uri("/YourSource", UriKind.Relative)); //Or UriKind.Absolute depending in the path
myImage.Source = bitmapImage;
If you want to place the image into some coordenates you can place a Canvas behind and place the image using Canvas coordenates. Use:
_myCanvas.Children.Add(myImage); //To add your image to Canvas, declared on Xaml or previously created and added to your control
Canvas.SetTop(myImage, 100); //Set Y coordenate relative to Canvas initial point
Canvas.SetLeft(myImage, 100); // Set X
Related
I am loading an image into an ink canvas, the input image is always monochromatic, I am then drawing on that image with a white pen and intending to save it.
When the image is loaded some of the pre-existing lines which I know to be 1 pixel thick have an edge added to them which isn't monochromatic.
The way I have though to fix this is by rendering the bitmap and then discarding all pixels with a value of less than 255.
I have tried to use the pixel format BlackWhite, however this generates the error:
An unhandled exception of type 'System.ArgumentException' occurred in PresentationCore.dll
Additional information: 'BlackWhite' PixelFormat is not supported for this operation.
The line of code rendering the bitmap
RenderTargetBitmap rtb = new RenderTargetBitmap((int)inkCanvas.ActualWidth, (int)inkCanvas.ActualHeight, 96, 96, System.Windows.Media.PixelFormats.BlackWhite);
I'm not sure if the issue lies in how I loaded it into the ink canvas so that code is also included below
private void LoadImagetoCanvas(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog openFileDlg = new Microsoft.Win32.OpenFileDialog();
Nullable<bool> result = openFileDlg.ShowDialog();
if (result == true)
{
global.canvas1filepath = openFileDlg.FileName;
System.Windows.Controls.Image myImage = new System.Windows.Controls.Image();
myImage.Source = new BitmapImage(new Uri(global.canvas1filepath));
BitmapImage bmp = new BitmapImage(new Uri(global.canvas1filepath, UriKind.Absolute));
global.canvas1imagexpixels = (int)bmp.Width;
global.canvas1imageypixels = (int)bmp.Height;
ImageBrush canvas1Background = new ImageBrush();
canvas1Background.ImageSource = new BitmapImage(new Uri(global.canvas1filepath, UriKind.Relative));
inkCanvas1.Background = canvas1Background;
}
}
I'll compile an answer here - thanks to Sinatr & Clemens for their help with the theory and examples
The solution is based in the XMAL code for the ink canvas i'm using, I found adding the two following properties removed any edges to the 1 pixel wide lines I was drawing:
RenderOptions.BitmapScalingMode="NearestNeighbor" RenderOptions.EdgeMode="Aliased"
I am applying a blur in a background thread to increase performance. This function is returning a RenderTargetBitmap. When this is done I'm invoking through the Dispatcher an update on the image and add it as content to the page. This is done like the following:
System.Windows.Controls.Image image = new System.Windows.Controls.Image();
Thread screenshotThread = new Thread(new ThreadStart(delegate()
{
RenderTargetBitmap img = CaptureScreen(0, 0, actualWidth, actualHeight);
//System.Windows.Controls.Image image = imgBlur;
//image = new System.Windows.Controls.Image();
Application.Current.Dispatcher.Invoke(() =>
{
image.Source = img;
image.Width = actualWidth;
image.Height = actualHeight;
PageContainer.Children.Add(image);
});
}));
screenshotThread.SetApartmentState(ApartmentState.STA);
screenshotThread.Start();
I'm adding the image to the PageContainer, this is a Grid. After running this piece of code, the image has been added to the page. However, the imagesource is null.. No image is currently visible. How can I make this image appear?
You have created the Imagecontrol and the RenderTargetBitmap on different thread. I am surprised you did not get an exception. Try adding img.Freeze(); before setting it to the Image.Source.
I want to assign height and width of dynamically created image to a canvas .
Here is my code
Image image=new Image();
BitmapImage bm=new BitmapImage();
bm.UriSource=new Uri("url",Urikind.RelativeOrAbsolute);
image.Source=bm;
MyCanvas.Height=image.Height;
MyCanvas.Width=image.Width;
but it gives 0.0 value when i check in debug mode ,when I change image.Height to image.ActualHeight it gives NaN .
How to resolve this.
You should use the ActualWidth and ActualHeight properties of the Image control. The Width and Height are the dimensions you want the control to have; by default their value is double.NaN, which means "Auto".
But anyway, it still won't be enough:
at this point, the image has not finished loading, so its width and height are not accessible yet. You need to initialize the image like that:
BitmapImage bm=new BitmapImage();
bm.BeginInit();
bm.UriSource=new Uri("url",Urikind.RelativeOrAbsolute);
bm.EndInit();
the Image control is not yet part of the visual tree, so its dimensions can't be computed
So ActualWidth and ActualHeight will still not give your the correct values... A better way would be to set the canvas size according to the width and height of the BitmapImage:
MyCanvas.Height= bm.Height;
MyCanvas.Width = bm.Width;
I solved it in this way
BitmapImage bm = new BitmapImage();
bm.UriSource=new Uri("ms-appx:///" + d.source, UriKind.RelativeOrAbsolute);
bm.ImageOpened += (sender, e1) =>
{
DrawCanvas.Height = bm.PixelHeight;
DrawCanvas.Width = bm.PixelWidth;
};
I have a Canvas that has 400 children. Each of the children is a rectangle and is filled with an Image. If I want to find a certain image, how would I go doing about that?
//My code to fill a rectangle
Image img = new Image();
img.Source = new BitmapImage(new Uri(#"hero.png", UriKind.Relative));
img.Margin = rec.Margin;
ImageBrush imgbrush = new ImageBrush();
imgbrush.ImageSource = img.Source;
rec.Fill = imgbrush;
//My attempt at finding that certain rectangle
foreach (Rectangle rec in canvas1.Children)
{
if (rec.Fill = ImageBrush.ImageSourceProperty) // I tried to compare the rectangle with the image's source
{
}
}
You may use names for for every specific Image then using FindName Method
object wantedNode = stackPanel.FindName("dog");
Why not store the objects in an array (key/pair) that you can later iterate through?
I'm writing an application for the surface that requires displaying data in a table (i.e. DataGrid). This is great, except the table captures the touch interactions for the ScatterViewItem control (basically a panel that can be spun, shrunk, and moved by the user). This prevents the user from easily manipulating the ScatterViewItem.
To solve this problem, I thought it would be easy to draw the control to an image and just put that up. It seems I was wrong. Here are all my attempts:
http://pastie.org/private/gfkkv9f6apgrqi1ucspwpa (no need to read this, unless you think it will be useful. That's why it's in pastie and not on here)
I'm putting the DataGrid inside of another Grid, because otherwise it won't measure properly:
Grid g = new Grid();
g.Children.Add(dataTable);
SurfaceScrollViewer viewer = new SurfaceScrollViewer();
viewer.Content = Utility.SaveWPFControlAsImage(g);
If we change that last line to
viewer.Content = g;
We get a good table:
If we don't, we get:
SaveWPFControlAsImage is as follows:
public static System.Windows.Controls.Image SaveWPFControlAsImage(FrameworkElement e)
{
e.Measure(new System.Windows.Size(double.PositiveInfinity, double.PositiveInfinity));
RenderTargetBitmap targetBitmap =
new RenderTargetBitmap((int)e.DesiredSize.Width,
(int)e.DesiredSize.Height,
96d, 96d,
PixelFormats.Default);
targetBitmap.Render(e);
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(targetBitmap));
MemoryStream stream = new MemoryStream();
encoder.Save(stream);
BitmapImage bmp = new BitmapImage();
bmp.BeginInit();
bmp.StreamSource = new MemoryStream(stream.ToArray());
bmp.EndInit();
return new System.Windows.Controls.Image()
{
Source = bmp,
};
}
So maybe I'm just not rendering it right, or, maybe, I'm just going about this at the wrong angle...
In WPF you have a VisualBrush which allows you to capture a live preview of a given control. Also if you don't want any input of a given control, you can always set IsHitTestVisible="False".