I am new learner to WPF. here I got a question.
I have a image, width:360, height:360. Here I want to crop this image like below:
( 0,0 ) to (120,120) save to the first ImageSource object,
(120,0 ) to (240,120) save to the second ImageSource object,
(240,0 ) to (360,120) save to the third ImageSource object;,
……
pls see more details in below picture:
My code sample below:
private void CutImage(string img)
{
int iLeft = 0;
int iTop = 0;
int count = 0;
Image thisImg = new Image();
BitmapImage src = new BitmapImage();
src.BeginInit();
src.UriSource = new Uri(img, UriKind.Relative);
src.CacheOption = BitmapCacheOption.OnLoad;
src.EndInit();
thisImg.Source = src;
for (int i = 0; i < 3; i++)
{
iTop = i * 120;
for (int j = 0; j < 3; j++)
{
iLeft = j * 120;
Canvas canvas = new Canvas();
Rectangle destRect = new Rectangle();
destRect.SetValue(Canvas.LeftProperty, (double)0);
destRect.SetValue(Canvas.TopProperty,(double)0);
destRect.Width = destRect.Height = 120;
Rect srcRect = new Rect();
srcRect.X = iLeft;
srcRect.Y = iTop;
srcRect.Width = srcRect.Height = 120;
thisImg.Clip = new RectangleGeometry(srcRect);
thisImg.Clip.SetValue(Canvas.TopProperty, (double)iTop);
thisImg.Clip.SetValue(Canvas.LeftProperty, (double)iLeft);
thisImg.Clip.SetValue(Canvas.WidthProperty, (double)120);
thisImg.Clip.SetValue(Canvas.HeightProperty,(double)120);
objImg[count++] = (ImageSource)thisImg.GetValue(Image.SourceProperty);
}
}
}
but it doesn't work as I expected, seems that all the ImageSource objects store the same image, not the corping part. Any one can help me ? thx.
Use CroppedBitmap to do this:
private void CutImage(string img)
{
int count = 0;
BitmapImage src = new BitmapImage();
src.BeginInit();
src.UriSource = new Uri(img, UriKind.Relative);
src.CacheOption = BitmapCacheOption.OnLoad;
src.EndInit();
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
objImg[count++] = new CroppedBitmap(src, new Int32Rect(j * 120, i * 120, 120, 120));
}
Just do:
private static BitmapSource CaptureScreen(Visual target, double dpiX, double dpiY)
{
if (target == null)
{
return null;
}
Rect bounds = VisualTreeHelper.GetDescendantBounds(target);
RenderTargetBitmap rtb = new RenderTargetBitmap((int)(bounds.Width * dpiX / 96.0),
(int)(bounds.Height * dpiY / 96.0),
dpiX,
dpiY,
PixelFormats.Pbgra32);
DrawingVisual dv = new DrawingVisual();
using (DrawingContext ctx = dv.RenderOpen())
{
VisualBrush vb = new VisualBrush(target);
ctx.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
}
rtb.Render(dv);
return rtb;
}
VisualBrush part1 = new VisualBrush(yourVISUAL);
part1.ViewBoxUnits = ..Absolute;
part1.ViewBox = new Rect(x, y, width, height);
BitmapSource bitmapSource = CaptureScreen(part1, 96, 96);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
encoder.Save(fileStream);
}
Related
I am trying to Convert an Image to a PathGeometry. I upload a picture, and then I do canny edge detection and now I want to convert that in to a PathGeometry. My over all plan it to fill it with different colors.
So I tried this :`public Shape MakeSape(Brush customColor, double[,] image)
{
Path graphPath = new Path();
graphPath.Fill = customColor;
graphPath.Stroke = Brushes.Black;
PathFigure pf = new PathFigure();
pf.StartPoint = new Point(0, 0);
pf.IsClosed = true;
int row = image.GetLength(0);
int column = image.GetLength(1);
for (int y = 0; y < row; y++)
{
for (int x = 0; x < column; x++)
{
if (image[y, x] >= LowThreshold)
{
pf.Segments.Add(new LineSegment(new Point(x, y), true));
}
}
}
PathGeometry pg = new PathGeometry();
pg.Figures.Add(pf);
graphPath.Data = pg;
ImageAsShape = graphPath;
return graphPath;
}`
And that looked like it should work, but I am just getting all black.
This is the same question asked before and the answer is also verified but in My Project I am using WebApi 2 and want return image from Ihttpactionresult
I have searched and lot and done some code Which I don't know if I am doing right..
I also Looked at ImageReizer but it saves the resized Images in the folder. Idon't want to save the Image.
Here is My Controller Action
[HttpGet]
[Route("GetFile")]
public IHttpActionResult GetFile(string filename, int w = 0, int h = 0)
{
//string filePath = "fdsafsa";
//int width = 0;
//var fileStream = File.Open("/ProjectFiles", FileMode.Open);
//var content = new StreamContent(fileStream);
//content.Headers.ContentType = new MediaTypeHeaderValue("png");
var imageFile = HttpContext.Current.Server.MapPath(#filename);
if(File.Exists(imageFile))
{
var srcImage = Image.FromFile(imageFile);
var newImage = new Bitmap(w, h);
var graphics = Graphics.FromImage(newImage);
var stream = new MemoryStream();
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.DrawImage(srcImage, new Rectangle(0, 0, w, h));
newImage.Save(stream, ImageFormat.Png);
//var content = new StreamContent(stream);
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new ByteArrayContent(stream.ToArray());
result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
return Ok(result);
}
This is the html where I want to render the Image
<img src="/api/Public/GetFile?filename=/ProjectFiles/Project_2087/art-therapy-career2_73937984-7e03-4067-91bf-2dd4fc10b328.jpg&w=100&h=100" alt="image" />
How can I show the resized Image dynamically without storing the resize image on the server. I don't want to save the resize Images.
I need help soon.
Thanks for your help.
Another approach ......
[HttpGet]
[Route("GetFileStream")]
public IHttpActionResult GetFileStream(string filename, int w = 0, int h = 0)
{
var imagePath = HttpContext.Current.Server.MapPath(#filename);
var result = getResizedImage(imagePath, w, h);
return Ok(result);
}
byte[] getResizedImage(String path, int width, int height)
{
Bitmap imgIn = new Bitmap(path);
double y = imgIn.Height;
double x = imgIn.Width;
double factor = 1;
if (width > 0)
{
factor = width / x;
}
else if (height > 0)
{
factor = height / y;
}
System.IO.MemoryStream outStream = new System.IO.MemoryStream();
Bitmap imgOut = new Bitmap((int)(x * factor), (int)(y * factor));
Graphics g = Graphics.FromImage(imgOut);
g.Clear(Color.White);
g.DrawImage(imgIn, new Rectangle(0, 0, (int)(factor * x), (int)(factor * y)), new Rectangle(0, 0, (int)x, (int)y), GraphicsUnit.Pixel);
imgOut.Save(outStream, getImageFormat(path));
return outStream.ToArray();
}
**
This is the Working Code with Mvc
**
This is the code I found working for Simple Mvc Application
An Action
public ActionResult Thumb(string filename = "Azalea.jpg", int w = 0, int h = 0)
{
string path = Path.Combine(Server.MapPath("~/images2"), filename);
//Bitmap bitmap = new Bitmap(filepath);
//if (bitmap == null)
//{
// return new EmptyResult();
//}
//MemoryStream ms = new MemoryStream();
//bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
Bitmap imgIn = new Bitmap(path);
double y = imgIn.Height;
double x = imgIn.Width;
double factor = 1;
if (w > 0)
{
factor = w / x;
}
else if (h > 0)
{
factor = h / y;
}
System.IO.MemoryStream outStream = new System.IO.MemoryStream();
Bitmap imgOut = new Bitmap((int)(x * factor), (int)(y * factor));
Graphics g = Graphics.FromImage(imgOut);
g.Clear(Color.White);
g.DrawImage(imgIn, new Rectangle(0, 0, (int)(factor * x), (int)(factor * y)), new Rectangle(0, 0, (int)x, (int)y), GraphicsUnit.Pixel);
imgOut.Save(outStream, getImageFormat(path));
outStream.Seek(0, SeekOrigin.Begin);
FileStreamResult fileStreamResult = new FileStreamResult(outStream, "image/png");
return fileStreamResult;
}
In cshtml page
<img src="~/Home/Thumb/#Model.ImageName?w=700&h=300" alt="image" />
How to use this With web Api2 ?
Answer of My Question after long search.Please Improve this
[HttpGet]
[Route("GetFileStream")]
public IHttpActionResult GetFileStream(string filename, int w = 0, int h = 0)
{
var imagePath = HttpContext.Current.Server.MapPath(#filename);
return new FileResult(imagePath, w, h, "image/jpeg");
}
public class FileResult : IHttpActionResult
{
private readonly string filePath;
private readonly string contentType;
private readonly int width;
private readonly int height;
public FileResult(string filePath, int width, int height, string contentType = null)
{
this.filePath = filePath;
this.contentType = contentType;
this.width = width;
this.height = height;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
return Task.Run(() =>
{
var result = getResizedImage(filePath, width, height);
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(result)
//Content = new StreamContent(File.OpenRead(filePath))
};
var contentType = this.contentType ?? MimeMapping.GetMimeMapping(Path.GetExtension(filePath));
response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
return response;
}, cancellationToken);
}
}
static byte[] getResizedImage(String path, int width, int height)
{
Bitmap imgIn = new Bitmap(path);
double y = imgIn.Height;
double x = imgIn.Width;
double factor = 1;
if (width > 0)
{
factor = width / x;
}
else if (height > 0)
{
factor = height / y;
}
System.IO.MemoryStream outStream = new System.IO.MemoryStream();
Bitmap imgOut = new Bitmap((int)(x * factor), (int)(y * factor));
Graphics g = Graphics.FromImage(imgOut);
g.Clear(Color.White);
g.DrawImage(imgIn, new Rectangle(0, 0, (int)(factor * x), (int)(factor * y)), new Rectangle(0, 0, (int)x, (int)y), GraphicsUnit.Pixel);
imgOut.Save(outStream, getImageFormat(path));
//outStream.Seek(0, SeekOrigin.Begin);
//System.Web.Mvc.FileStreamResult fileStreamResult = new System.Web.Mvc.FileStreamResult(outStream, "image/png");
//return fileStreamResult;
return outStream.ToArray();
}
string getContentType(String path)
{
switch (Path.GetExtension(path))
{
case ".bmp": return "Image/bmp";
case ".gif": return "Image/gif";
case ".jpg": return "Image/jpeg";
case ".png": return "Image/png";
default: break;
}
return "";
}
static ImageFormat getImageFormat(String path)
{
switch (Path.GetExtension(path))
{
case ".bmp": return ImageFormat.Bmp;
case ".gif": return ImageFormat.Gif;
case ".jpg": return ImageFormat.Jpeg;
case ".png": return ImageFormat.Png;
default: break;
}
return ImageFormat.Jpeg;
}
Please Help in improving this answer,
Thanks,
Sanuj
You can pass your byteArray to View, then use something like this:
Create your image model:
public class ImageData
{
public string Name { get; set; }
public byte[] Content { get; set; }
. . .
}
Then in controller assign and return your model to View():
#{
string imageBase = Convert.ToBase64String(Model.ImageContent);
string imageSource = string.Format("data:image/gif;base64,{0}", imageBase);
}
<img src="#imageSource" alt="#Model.ImageName" width="100" height="100" />
I created an animated image to move on my canvas then I created another animated image ;
I want to hide just my first image after it's movement and before moving another;
I tried to set opacity of my drawing visual or image brush or etc zero;but all of my image
hide;
List<EllipseGeometry> eg = new List<EllipseGeometry>();
Path ballPath;
int c = 0;
foreach (Polyline p in pl)
{
if (p.Points.Count > 1)
{
ballPath = new Path();
FormattedText formattedText = new FormattedText(" " + (anl[c].DOffset).ToString() + "\n " + anl[c].playername + " ", CultureInfo.GetCultureInfo("en-us"),
FlowDirection.LeftToRight,
new Typeface("arial"),
20,
Brushes.Black);
formattedText.MaxTextWidth = 500;
formattedText.MaxTextHeight = 500;
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
drawingContext.DrawImage(il[c].Source, new Rect(4, 0, 26, 26));//30
drawingContext.DrawText(formattedText, new Point(1, 2));
drawingContext.Close();
RenderTargetBitmap bmp = new RenderTargetBitmap((int)formattedText.WidthIncludingTrailingWhitespace, (int)formattedText.Height, 96, 96, PixelFormats.Pbgra32);
bmp.Render(drawingVisual);
ImageBrush b = new ImageBrush(bmp);
b.Stretch = Stretch.Uniform;
ballPath.Fill = b;
mainwindow.animecan.Children.Add(ballPath);
////
int jy = 0;
for (int i = 0; i < anl.Count; i++)
{
try
{
if (anl[i].offset == m)
jy = anl[i].offset;
}
catch
{
}
}
if (multi && p.Uid == jy.ToString())//اگر آفست مالتی اسپید شده باشه
{
eg.Add(new EllipseGeometry(ms[ih].p1, 27, 27));
ballPath.Data = eg.First();// animatedEllipseGeometry;
PathFigure myPathFigure = new PathFigure();
PointCollection pe = new PointCollection();
pe.Add(ms[ih].p1);
pe.Add(ms[ih].p2);
myPathFigure.StartPoint = eg.First().Center;
myPathFigure.Segments.Add(
new PolyLineSegment(pe, true));
PathGeometry myPathGeometry = new PathGeometry();
myPathGeometry.Figures.Add(myPathFigure);
myPathGeometry = new PathGeometry();
myPathGeometry.Figures.Add(myPathFigure);//
PointAnimationUsingPath centerPointAnimation1 = new PointAnimationUsingPath();
centerPointAnimation1.PathGeometry = myPathGeometry;
centerPointAnimation1.Duration = TimeSpan.FromSeconds(ms[ih].sspeed);
centerPointAnimation1.BeginTime = TimeSpan.FromSeconds(ms[ih].delay);
centerPointAnimation1.FillBehavior = FillBehavior.HoldEnd;
eg.First().BeginAnimation(EllipseGeometry.CenterProperty, centerPointAnimation1);
eg.Remove(eg.First());
}
c++;
I believe that your problem is caused because your whole code block is executed 'at once' (before updating the UI), rather than 'line by line'. In order to make your call to the Visibility property update before execution reaches the end of the code block, you'll need to queue it on the Dispatcher object. Try this:
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate
{
yourControl.Visibility = Visibility.Collapsed;
});
I am calling a method that has a Grid.Children.Clear() functionality. When calling it from different methods it works well. But when I call my the method from an xmpp_onmessage method. I am experiencing an error. “The calling thread cannot access this object because a different thread owns it.”
Here is the method that containts Grid.Children.Clear()the :
private void ConstructChatView(Boolean isChat)
{
System.Uri resourceUri = new System.Uri("Public/Images/chat_green-textarea.png", UriKind.Relative);
StreamResourceInfo streamInfo = Application.GetResourceStream(resourceUri);
System.Uri resourceUri2 = new System.Uri("Public/Images/chat_green-textarea-tail.png", UriKind.Relative);
StreamResourceInfo streamInfo2 = Application.GetResourceStream(resourceUri2);
System.Uri resourceUri3 = new System.Uri("Public/Images/chat_blue-textarea.png", UriKind.Relative);
StreamResourceInfo streamInfo3 = Application.GetResourceStream(resourceUri3);
System.Uri resourceUri4 = new System.Uri("Public/Images/chat_blue-textarea-tail.png", UriKind.Relative);
StreamResourceInfo streamInfo4 = Application.GetResourceStream(resourceUri4);
BitmapFrame temp = BitmapFrame.Create(streamInfo.Stream);
var brush = new ImageBrush();
brush.ImageSource = temp;
BitmapFrame temp2 = BitmapFrame.Create(streamInfo2.Stream);
BitmapFrame temp3 = BitmapFrame.Create(streamInfo3.Stream);
var brush2 = new ImageBrush();
brush2.ImageSource = temp3;
BitmapFrame temp4 = BitmapFrame.Create(streamInfo4.Stream);
int ctr = 0;
chatGrid.Children.Clear();
if (isChat == true)
{
for (int i = 0; i < _messageView.Count; i++)
{
if ((!_messageView.ElementAt(i).Message.ToString().Trim().Equals("")))
{
RowDefinition chatGridRow1 = new RowDefinition();
RowDefinition chatGridRow2 = new RowDefinition();
RowDefinition chatGridRow3 = new RowDefinition();
chatGrid.RowDefinitions.Add(chatGridRow1);
chatGrid.RowDefinitions.Add(chatGridRow2);
chatGrid.RowDefinitions.Add(chatGridRow3);
if (_messageView.ElementAt(i).IsMe == true)
{
TextBlock Message = new TextBlock();
Message.Foreground = Brushes.White;
Message.Padding = new Thickness(10, 10, 10, 10);
Message.HorizontalAlignment = HorizontalAlignment.Right;
Message.Margin = new Thickness(0, 0, 5, 0);
Message.Background = brush2;
Message.TextWrapping = TextWrapping.Wrap;
Message.Text = _messageView.ElementAt(i).Message;
Grid.SetRow(Message, ctr);
Grid.SetColumn(Message, 0);
ctr++;
Image Bluetail = new Image();
Bluetail.Source = temp4;
Bluetail.HorizontalAlignment = HorizontalAlignment.Right;
Bluetail.Height = 10;
Bluetail.Width = 20;
Bluetail.Margin = new Thickness(0, -(0.7), 10, 0);
Grid.SetRow(Bluetail, ctr);
ctr++;
Label Sender = new Label();
Sender.Foreground = Brushes.White;
Sender.Margin = new Thickness(0, 0, 0, 10);
Sender.HorizontalAlignment = HorizontalAlignment.Right;
Sender.Content = "Sent By : " + _messageView.ElementAt(i).Name.ToString() + " " + _messageView.ElementAt(i).DateCreated.ToString();
Grid.SetRow(Sender, ctr);
Grid.SetColumn(Sender, 0);
ctr++;
chatGrid.Children.Add(Message);
chatGrid.Children.Add(Bluetail);
chatGrid.Children.Add(Sender);
}
else
{
TextBlock Message = new TextBlock();
Message.Foreground = Brushes.White;
Message.Padding = new Thickness(10, 10, 10, 10);
Message.HorizontalAlignment = HorizontalAlignment.Left;
Message.Margin = new Thickness(5, 0, 0, 0);
Message.Background = brush;
Message.TextWrapping = TextWrapping.Wrap;
Message.Text = _messageView.ElementAt(i).Message;
Grid.SetRow(Message, ctr);
Grid.SetColumn(Message, 0);
ctr++;
Image Greentail = new Image();
Greentail.Source = temp2;
Greentail.HorizontalAlignment = HorizontalAlignment.Left;
Greentail.Height = 10;
Greentail.Width = 20;
Greentail.Margin = new Thickness(10, -(0.7), 5, 0);
Grid.SetRow(Greentail, ctr);
ctr++;
Label Sender = new Label();
Sender.Foreground = Brushes.White;
Sender.Margin = new Thickness(0, 0, 0, 10);
Sender.HorizontalAlignment = HorizontalAlignment.Left;
Sender.Content = "Sent By : " + _messageView.ElementAt(i).Name.ToString() + " " + _messageView.ElementAt(i).DateCreated.ToString();
Grid.SetRow(Sender, ctr);
Grid.SetColumn(Sender, 0);
ctr++;
chatGrid.Children.Add(Message);
chatGrid.Children.Add(Greentail);
chatGrid.Children.Add(Sender);
}
}
}
}
else
{
for (int i = 0; i < _messageView.Count; i++)
{
if (_messageView.ElementAt(i).IsMe == true && (!_messageView.ElementAt(i).Message.ToString().Trim().Equals("")))
{
RowDefinition chatGridRow1 = new RowDefinition();
RowDefinition chatGridRow2 = new RowDefinition();
RowDefinition chatGridRow3 = new RowDefinition();
chatGrid.RowDefinitions.Add(chatGridRow1);
chatGrid.RowDefinitions.Add(chatGridRow2);
chatGrid.RowDefinitions.Add(chatGridRow3);
TextBlock Message = new TextBlock();
Message.Foreground = Brushes.White;
Message.Margin = new Thickness(0, 10, 300, 0);
Message.Padding = new Thickness(10, 10, 10, 10);
Message.HorizontalAlignment = HorizontalAlignment.Left;
Message.Background = brush;
Message.TextWrapping = TextWrapping.Wrap;
Message.Text = _messageView.ElementAt(i).Message;
Grid.SetRow(Message, ctr);
Grid.SetColumn(Message, 0);
ctr++;
Image Greentail = new Image();
Greentail.Source = temp2;
Greentail.HorizontalAlignment = HorizontalAlignment.Left;
Greentail.Height = 10;
Greentail.Width = 20;
Greentail.Margin = new Thickness(5, -(0.7), 0, 0);
Grid.SetRow(Greentail, ctr);
ctr++;
Label Sender = new Label();
Sender.Foreground = Brushes.White;
Sender.Margin = new Thickness(0, 0, 0, 10);
Sender.Content = "Sent By : " + _messageView.ElementAt(i).Name.ToString() + " " + _messageView.ElementAt(i).DateCreated.ToString();
Grid.SetRow(Sender, ctr);
Grid.SetColumn(Sender, 0);
ctr++;
chatGrid.Children.Add(Message);
chatGrid.Children.Add(Greentail);
chatGrid.Children.Add(Sender);
}
}
}
//for (int i = 0; i < _messageView.Count; i++)
//{
// if (_messageView.ElementAt(i).IsMe == true && (!_messageView.ElementAt(i).Message.ToString().Trim().Equals("")))
// {
// }
//}
ctr = 0;
scrollView.ScrollToEnd();
}
Any ideas? thanks
Most UI elements may only be modified in the UI thread. As your event handler is apparently invoked in a different thread, you have to use the Dispatcher to invoke your code in the UI thread.
private void ConstructChatView(Boolean isChat)
{
Dispatcher.Invoke((Action)(() => chatGrid.Children.Clear()));
}
EDIT: You may also pass more code to the Invoke call by using an anonymous method:
private void ConstructChatView(Boolean isChat)
{
Dispatcher.Invoke((Action)(() =>
{
// more code here
}));
}
Of course you may also put a bunch of code in another method and pass that to the Invoke call:
private void ConstructChatView(Boolean isChat)
{
Dispatcher.Invoke((Action)(() => ConstructChatViewInUI(isChat)));
}
private void ConstructChatViewInUI(Boolean isChat)
{
...
}
I want to create a new blank image of size 100x100.
Paint it in red and save the image as 'test.png'.
Can I access/change the pixel values of the created image.
How can I do it in WPF.
You can use a WritableBitmap for that, then you can use a BitmapEncoder to encode the image and save it.
var bitmap = new WriteableBitmap(100, 100, 96, 96, PixelFormats.Pbgra32, null);
var rect = new Int32Rect(0, 0, 100, 100);
var channelCount = 4;
var pixels = new byte[100 * 100 * channelCount];
for (int i = 0; i < 100 * 100 * channelCount; i+=channelCount)
{
pixels[i + 2] = (byte)255; // Set red channel
pixels[i + 3] = (byte)255; // Set alpha channel
}
bitmap.WritePixels(rect, pixels, channelCount * 100, 0);
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmap));
using (var stream = new FileStream(#"C:\Users\Public\Test.png", FileMode.Create))
{
encoder.Save(stream);
}
If you wanna uses Shapes instead you can do this
var rtb = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Pbgra32);
var rectangle = new Rectangle();
rectangle.BeginInit();
rectangle.Height = 100;
rectangle.Width = 100;
rectangle.Stroke = Brushes.Red;
rectangle.Fill = Brushes.Red;
rectangle.StrokeThickness = 1.0;
rectangle.Margin = new Thickness(0, 0, 0, 0);
rectangle.EndInit();
rectangle.Arrange(new Rect(new Size(100, 100)));
rectangle.UpdateLayout();
rtb.Render(rectangle);
var png = new PngBitmapEncoder();
png.Frames.Add(BitmapFrame.Create(rtb));
using (Stream fs = File.Create("test.png"))
{
png.Save(fs);
}