How to use texture image .jpg as Windows.Media.pen C# - c#

I have a texture image as .jpg and I want to use this image as Windows.Media.pen
I use Windows.Media.pen for drawing skeleton data in DrawingContext which I got it from microsoft kinect.
How can I use texture image .jpg as Windows.Media.pen?
solved the problem.
ImageSource image = new BitmapImage(new Uri(#"...\texture.jpg", UriKind.Relative));
var brush = new ImageBrush(image);
var pen = new Pen(brush, 10);
drawingContext.DrawLine(pen, XPos, YPos);

Welcome to StackOverflow :D
Not sure if you'd get what you've been expecting as you can see below but here's how to do it :
You need to use ImageBrush to be able to assign an image to a Pen.
Original image :
Result :
Code :
ImageSource image = new BitmapImage(new Uri(#"..\..\5c5f910416e2b92bb73fa59c56fe695d.png", UriKind.Relative));
var brush = new ImageBrush(image);
var pen = new Pen(brush, 50);
var drawingVisual = new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
drawingContext.DrawRectangle(null, pen, new Rect(new Size(200, 200)));
}
var renderTargetBitmap = new RenderTargetBitmap(200, 200, 96, 96, PixelFormats.Pbgra32);
renderTargetBitmap.Render(drawingVisual);
Content = new Image {Source = renderTargetBitmap, Stretch = Stretch.None};

Related

How to calculate the intersection area on BitmapImage composition in WPF?

I am trying to merge two BitmapImage's into one composite image. But some parts are overlaping each other .
var green = new BitmapImage(new Uri(#"C:\temp\green.jpg", UriKind.RelativeOrAbsolute));
var red = new BitmapImage(new Uri(#"C:\temp\red.jpg", UriKind.RelativeOrAbsolute));
var visual = new DrawingVisual();
DrawingImage drawingImageSource;
using (DrawingContext drawingContext = visual.RenderOpen())
{
DrawingGroup imageDrawings = new DrawingGroup();
imageDrawings.Children.Add(new ImageDrawing(red, new Rect(0, 0, red.PixelWidth, red.PixelHeight)));
imageDrawings.Children.Add(new ImageDrawing(green, new Rect(red.PixelWidth - 10, red.PixelHeight - 10, green.PixelWidth, green.PixelHeight)));
drawingImageSource = new DrawingImage(imageDrawings);
RenderTargetBitmap bmp = new RenderTargetBitmap(red.PixelWidth + green.PixelWidth - offsetX, red.PixelHeight + green.PixelHeight - offsetY, 96, 96, PixelFormats.Pbgra32);
bmp.Render(visual);
//no binding, just my image control to keep it simple
this.fImage.Source = drawingImageSource;
}
XAML:
<Grid>
<Image x:Name="fImage"/>
</Grid>
I want to render the intersection area in different ways, e.g. mix the colors or gradient based transition. Are there some instruments in .NET or do I need to handle with pixels?

How do I correctly transform an image in WPF?

I want to write program that functions something like PhotoShop.
1.upload image
2. Then I want to do skew transform, But when I do transform I have a problem, my picture goes beyond the edge of the workspace.
How do I transform without this problem(I think I should create a new Image every time I do a transform).
Then I crop, but crop makes the picture without transform. I think if I create a new image every time I do a transform, the problem will be fixed.
How do I do this correctly?
How do I correctly create this image in WPF? How to do transform and save an image? I am using(System.Drawing.Bitmap, System.Windows.Media.Imaging) Maybe, can someone show me experiences, code or useful material?
For the skew tranformation you may use MatrixTranform. Basic idea is described here
Below is the code that transforms an image located at "D:\input.png", attaches transformation result to the source of Image that defined in the .xaml file:
<Image Name="imgProcess" />
and writes result to the file "D:\skew.png"
double skewX = .0;
double skewY = Math.Tan(Math.PI / 18);
MatrixTransform transformation = new MatrixTransform(1, skewY, skewX, 1, 0, 0)
BitmapImage image = new BitmapImage(new Uri(#"D:\input.png"));
var boundingRect = new Rect(0, 0, image.Width + image.Height * skewX, image.Height + image.Width * skewY);
DrawingGroup dGroup = new DrawingGroup();
using (DrawingContext dc = dGroup.Open())
{
dc.PushTransform(transformation);
dc.DrawImage(image, boundingRect);
}
DrawingImage imageSource = new DrawingImage(dGroup);
imgProcess.Source = imageSource;
SaveDrawingToFile(ToBitmapSource(imageSource), #"D:\skew.png", (int)boundingRect.Width, (int)boundingRect.Height);
private BitmapSource ToBitmapSource(DrawingImage source)
{
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
drawingContext.DrawImage(source, new Rect(new Point(0, 0), new Size(source.Width, source.Height)));
drawingContext.Close();
RenderTargetBitmap bmp = new RenderTargetBitmap((int)source.Width, (int)source.Height, 96, 96, PixelFormats.Pbgra32);
bmp.Render(drawingVisual);
return bmp;
}
private void SaveDrawingToFile(BitmapSource image, string fileName, int width, int height)
{
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(image));
using (var stream = new FileStream(fileName, FileMode.Create))
{
encoder.Save(stream);
}
}
Results

Convert Canvas to ImageSource

im attempting to convert a canvas to a image source for use as an OpacityMask, I want to save it into memory rather than save it as a file, i'm having trouble though. Below is my code, I think i'm going about it wrong!
Really, I need to get the image information as a Base64String, so somewhere between that I need to convert the RenderTargetBitmap!
public BitmapSource ExportToPng(Uri path, Canvas surface)
{
BitmapEncoder encoder = new PngBitmapEncoder();
System.IO.MemoryStream myStream = new System.IO.MemoryStream();
// Save current canvas transform
Transform transform = surface.LayoutTransform;
// reset current transform (in case it is scaled or rotated)
surface.LayoutTransform = null;
// Get the size of canvas
System.Windows.Size size = new System.Windows.Size(surface.ActualWidth, surface.ActualHeight);
// Measure and arrange the surface
// VERY IMPORTANT
surface.Measure(size);
surface.Arrange(new Rect(size));
// Create a render bitmap and push the surface to it
RenderTargetBitmap renderBitmap =
new RenderTargetBitmap(
(int)size.Width,
(int)size.Height,
96d,
96d,
PixelFormats.Pbgra32);
renderBitmap.Render(surface);
// push the rendered bitmap to it
encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
// save the data to the stream
encoder.Save(myStream);
// Restore previously saved layout
surface.LayoutTransform = transform;
var sr = new System.IO.StreamReader(myStream);
var myStr = sr.ReadToEnd();
var bytes = Convert.FromBase64String(myStr);
// Save to memory
/*Bitmap pg = new Bitmap("525, 350");
Graphics gr = Graphics.FromImage(pg);
gr.FillRectangle(new SolidBrush(System.Drawing.Color.FromArgb(255, 255, 255, 255)), 0, 0, (float)size.Width, (float)size.Height);
gr.DrawImage(System.Drawing.Bitmap.FromStream(myStream), 0, 0);*/
return BitmapFromBase64(myStr);
}
public static BitmapSource BitmapFromBase64(string base64String)
{
var bytes = Convert.FromBase64String(base64String);
using (var stream = new System.IO.MemoryStream(bytes))
{
return BitmapFrame.Create(stream,
BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
}
Edit:
Just found another possible way, however this creates a DrawingVisual, I need to convert that to a ImageBrush
C#
// Create a DrawingVisual that contains a rectangle.
private DrawingVisual CreateDrawingVisualRectangle(List<Rectangle> rectangles)
{
DrawingVisual drawingVisual = new DrawingVisual();
// Retrieve the DrawingContext in order to create new drawing content.
DrawingContext drawingContext = drawingVisual.RenderOpen();
// Create a rectangle and draw it in the DrawingContext.
foreach(Rectangle x in rectangles)
{
Rect rect = new Rect(new System.Windows.Point(x.X, x.Y), new System.Windows.Size(x.Width, x.Height));
drawingContext.DrawRectangle(System.Windows.Media.Brushes.Black, (System.Windows.Media.Pen)null, rect);
}
// Persist the drawing content.
drawingContext.Close();
return drawingVisual;
}
A UIElement takes any Brush as OpacityMask. You can simply create a VisualBrush from you Canvas, since the base class of every UIElement is SWM.Visual.
Canvas c = new Canvas();
element.OpacityMask = new VisualBrush( c );
Regards, Snowball

Snaps to pixel in RenderTargetBitmap

I write this code to draw a text in a RenderTargetBitmap:
DrawingVisual drawingVisual = new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
drawingContext.DrawText(new FormattedText("yes", CultureInfo.GetCultureInfo("en-us"),
FlowDirection.LeftToRight, new Typeface("Times New Roman"),
30, Brushes.Red), new Point(10, 10));
}
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(200, 200, 96, 96, PixelFormats.Pbgra32);
renderTargetBitmap.Render(drawingVisual);
image1.Source = renderTargetBitmap;//image1 is an Image control
the result is:
How can I remove this blurry effect? this effect comes from RenderTargetBitmap not from Image control.
You could use DrawingImage instead of RenderTargetBitmap
var drawingGroup = new DrawingGroup();
using (var drawingContext = drawingGroup.Open())
{
drawingContext.DrawText(
new FormattedText("yes",
CultureInfo.GetCultureInfo("en-us"),
FlowDirection.LeftToRight,
new Typeface("Times New Roman"),
30,
Brushes.Red),
new Point(10, 10));
}
image1.Source = new DrawingImage(drawingGroup);
You'll need to create DrawingGroup and open DrawingContext from there

Resize bitmap image

I want to have smaller size at image saved.
How can I resize it?
I use this code for redering the image:
Size size = new Size(surface.Width, surface.Height);
surface.Measure(size);
surface.Arrange(new Rect(size));
// Create a render bitmap and push the surface to it
RenderTargetBitmap renderBitmap =
new RenderTargetBitmap(
(int)size.Width,
(int)size.Height, 96d, 96d,
PixelFormats.Default);
renderBitmap.Render(surface);
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
// push the rendered bitmap to it
encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
// save the data to the stream
encoder.Save(outStream);
public static Bitmap ResizeImage(Bitmap imgToResize, Size size)
{
try
{
Bitmap b = new Bitmap(size.Width, size.Height);
using (Graphics g = Graphics.FromImage((Image)b))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(imgToResize, 0, 0, size.Width, size.Height);
}
return b;
}
catch
{
Console.WriteLine("Bitmap could not be resized");
return imgToResize;
}
}
The shortest way to resize a Bitmap is to pass it to a Bitmap-constructor together with the desired size (or width and height):
bitmap = new Bitmap(bitmap, width, height);
Does your "surface" visual have scaling capability? You can wrap it in a Viewbox if not, then render the Viewbox at the size you want.
When you call Measure and Arrange on the surface, you should provide the size you want the bitmap to be.
To use the Viewbox, change your code to something like the following:
Viewbox viewbox = new Viewbox();
Size desiredSize = new Size(surface.Width / 2, surface.Height / 2);
viewbox.Child = surface;
viewbox.Measure(desiredSize);
viewbox.Arrange(new Rect(desiredSize));
RenderTargetBitmap renderBitmap =
new RenderTargetBitmap(
(int)desiredSize.Width,
(int)desiredSize.Height, 96d, 96d,
PixelFormats.Default);
renderBitmap.Render(viewbox);

Categories