Issue while saving a Transparent Canvas in WPF - wpf

I have created a Grid in WPF with Red background. The Grid contains a transparent Canvas with some fixed size. Now while trying to export the Canvas as Image, I am getting an image with black background. But when there is some color in Canvas (say White or Red), I am getting a proper image. Can anybody please tell me why the image is generating with black background if a Canvas has a transparent color.
Example:
Grid grid = new Grid();
grid.Background = new SolidColorBrush(Colors.Red);
grid.Width = 500;
grid.Height = 300;
Canvas c = new Canvas();
c.Width = 500;
c.Height = 300;
c.Background = new SolidColorBrush(Colors.Transparent);
c.MouseLeftButtonUp += new MouseButtonEventHandler(c_MouseLeftButtonUp);
grid.Children.Add(c);
LayoutRoot.Children.Add(grid);
Inside MouseEvent handler of Canvas, I am saving it as jpg image.

Inside MouseEvent handler of Canvas, I am saving it as jpg image.
Save it as PNG. These type of images are specialized in saving transparent backgrounds.

Related

Painting change on Graphics not shown unless minimizing window

I created painting app, where i can paint on Panel, however, the change (what i paint) is shown only when i minimize window (form) and then open it again. I want to see what i paint immediately.
Steps to reproduce:
Panel panel = new Panel();
//adding panel to view
Bitmap bitmap = new Bitmap(width, height);
Graphics g = Graphics.FromImage(bitmap);
panel.BackgroundImage = bitmap;
//painting something on g
Solution was to use PictureBox instead of Panel, Painting on it became visible and more smooth.

RenderTargetBitmap renders a canvas wrong

I am trying to save the content of a WPF Canvas in an image with the code:
Rect rect = new Rect(canvas.RenderSize);
RenderTargetBitmap rtb = new RenderTargetBitmap((int)rect.Right,
(int)rect.Bottom,
96d,
96d,
PixelFormats.Default);
rtb.Render(canvas);
BitmapEncoder pngEncoder = new PngBitmapEncoder();
pngEncoder.Frames.Add(BitmapFrame.Create(rtb));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
pngEncoder.Save(ms);
ms.Close();
System.IO.File.WriteAllBytes("D://logo.png", ms.ToArray());
The canvas has a default horizontal alignment of 'Center' and it seems like this is an issue as the rendered image is actually the size of the canvas but includes the blank left margin, only showing part of the actual canvas content. But the blank space isn't even part of the canvas itself.
I tried to wrap the canvas in a grid and put it in a center column but it still renders the blank space from the left. If I align the image left horizontally it indeed renders the whole canvas, but I kind of need it to be centered. Is there any way I can modify the code to only include the canvas content and not the margin?

Is it possible to change an ImageBrush color inside WPF?

I'm trying to do something quite simple, but I'm not sure if it's possible. I have this image:
Inside my board game project, I use this to indicate the mouse position in the board and stuff like that (being the board a 8x8 grid with a rectangle inside). I'm also setting the grid cell background brush as, say, a SolidColorBrush with Blue color and .25 opacity, while the rectangle that lies above it with the target, or vice-versa, because I couldn't achieve my desired effect, which is, the part that is black to turn full blue, as my brush, while the rest remains with the opacity and etc. The way I did, it was possible to make the black part become blueish, with a transluscent background, but the color in the border isn't quite right yet:
I don't know if I was able to make myself clear, but I guess the picture shows what is my goal.
The code:
ImageBrush targetBrush = new ImageBrush();
targetBrush.ImageSource = new BitmapImage(new Uri("Resources/GameScreen/selectedTile.png", UriKind.Relative));
targetBrush.Opacity = 1;
SolidColorBrush backBrush = new SolidColorBrush(Colors.Blue);
backBrush.Opacity = .25;
tile.Children.Add(new Rectangle());
foreach (object target in tile.Children)
{
if (target.GetType() == typeof(Rectangle))
{
((Rectangle)target).Fill = backBrush;
}
}
tile.Background = targetBrush;
Thanks in advance.
As the image is just a mask you could use a Rectangle with a blue Fill and an OpacityMask set to your image.

Render a "not visible" WPF controls to an bitmap image

Render a WPF control to a bitmap image is not a trivial task as I found out today. As I know now dealing with the parent control margin is a problem, as Rick Strahl wrote in his blog
http://www.west-wind.com/weblog/posts/2007/Sep/10/Rendering-a-WPF-Container-to-Bitmap
So far I am able to create bitmaps of any control that is visible inside a window but what I really need to do is create bitmaps of invisible controls. I just create them in code - simples shapes like rectangle and ellipse - and want to save them as bitmaps to disk.
For me this turn out to be a personal nightmare. Since my ActualHeight and ActualWidth is always 0 I use Height and Width instead. But all I get is a empty image in the size of my control.
How can I create a bitmap of any control without adding it to a visible window?
New elements haven't had their layout performed. You need to call Measure and Arrange on the control before you render it.
Canvas c = new Canvas();
Rectangle r = new Rectangle
{
Fill = Brushes.Orange,
Width = 200,
Height = 100
};
Ellipse e = new Ellipse
{
Fill = Brushes.DodgerBlue,
Width = 100,
Height = 100
};
Canvas.SetLeft(e, 150);
c.Children.Add(r);
c.Children.Add(e);
var size = new Size(250,100);
c.Measure(size);
c.Arrange(new Rect(size));
RenderTargetBitmap bmp = new RenderTargetBitmap(250, 100, 96, 96, PixelFormats.Pbgra32);
bmp.Render(c);
PngBitmapEncoder enc = new PngBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bmp));
using(var s = File.OpenWrite("image.png"))
enc.Save(s);

Rendering Two rectangles in a canvas in silverlight

I have added canvas in the xaml file. From code iam creating two rectangles and adding it to the canvas. Here the size of both the triangles are same. When I run the application both the triangles are coming one upon the other I mean they are overlapping. But when I add them to a Stack panel they are coming one after the other?
Can anyone tell me how can I render two rectangles in my example one after the other without overlapping each other using Canvas?
Here is the sample code of my app;
Rectangle rect1 = new Rectangle();
rect1.Margin = new Thickness(1.5, 2, 1, 1);
rect1.Height = 40;
rect1.Width = 60;
rect1.Stroke = new SolidColorBrush(Colors.Black);
myCanvas1.Children.Add(rect1);
Rectangle rect2 = new Rectangle();
rect2.Height = 40;
rect2.Width = 60;
rect2.Stroke = new SolidColorBrush(Colors.Black);
myCanvas1.Children.Add(rect2);
Thanks in advance
Padma
A StackPanel arranges its Child elements automatically so that they don't overlap. A Canvas doesn't, as it arranges its Child elements according to their Canvas.Left and Canvas.Top attached properties.
Assign your Rectangles those properties to arrange them manually how you like.

Resources