Drawing rectangles and saving the resulting image to a file

Code

public class Shape
{
    public int X { get; set; }

    public int Y { get; set; }

    public int Width { get; set; }

    public int Height { get; set; }

}

public class ShapeRender
{
    public void Render()
    {
        var shapes = new List<Shape>
        {
            new Shape
            {
                X = 2530,
                Y = 2041,
                Width = 1890,
                Height = 621
            },
            new Shape
            {
                X = 6516,
                Y = 1944,
                Width = 1890,
                Height = 816
            }
        };

        // Code to draw shapes and save into image file.
        //...
    }
}

Task

In the code described above, the ShapeRender() method creates objects Shape that need to be drawn on such a plane:

enter a description of the image here

And save the resulting image to a jpg, png, or bmp file.


Additional description

Units to set for properties X, Y, Width, Height conditional.


Question

What is from the toolkit .NET to use? I'm not I did a little digging in the System.Drawing namespace, but I couldn't get my bearings.

Author: Adam Shakhabov, 2018-09-07

2 answers

I believe that you can draw a list of rectangles from this.

using System.Drawing;
using System.Drawing.Imaging;

...

private static Image CreateImageWithRectangle()
{
  Image img = new Bitmap(1000, 500);

  using (Graphics gr = Graphics.FromImage(img))
  {
    gr.DrawRectangle(new Pen(Color.Red, 2), 100, 100, 800, 300);
  }

  return img;
}

...

Image img = CreateImageWithRectangle();
img.Save(@"C:\temp\image.png", ImageFormat.Png);
 3
Author: Igor, 2018-09-07 17:33:38

If you need a mapping, then here you are on WPF.

We put this {[4] in the window]}:

<ItemsControl ItemsSource="{Binding}" Background="White" x:Name="Host">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style>
            <Setter Property="Canvas.Left" Value="{Binding X}"/>
            <Setter Property="Canvas.Top" Value="{Binding Y}"/>
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Rectangle Width="{Binding Width}" Height="{Binding Height}"
                       Stroke="DarkGray" StrokeThickness="1"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Adding rectangles:

var shapes = new List<Shape>
{
    new Shape
    {
        X = 500, Y = 200,
        Width = 600, Height = 450
    },
    new Shape
    {
        X = 100, Y = 500,
        Width = 200, Height = 600
    }
};
DataContext = shapes;

Voila, we have a mapping.

To save to a file, use this:

var rtb = new RenderTargetBitmap(
    (int)Host.ActualWidth, (int)Host.ActualHeight, 96, 96, PixelFormats.Pbgra32);
rtb.Render(Host);

var jpg = new JpegBitmapEncoder() { Frames = { BitmapFrame.Create(rtb) } };
using (var f = File.Create(@"d:\testrender.jpg"))
    jpg.Save(f);

If you need rendering on the server, you can do without visual elements:

var shapes = new List<Shape>
{
    new Shape
    {
        X = 500, Y = 200,
        Width = 600, Height = 450
    },
    new Shape
    {
        X = 100, Y = 500,
        Width = 200, Height = 600
    }
};

var totalW = shapes.Max(s => s.X + s.Width) + 10;
var totalH = shapes.Max(s => s.Y + s.Height) + 10;

var rtb = new RenderTargetBitmap(totalW, totalH, 96, 96, PixelFormats.Pbgra32);
var visual = new DrawingVisual();

var pen = new Pen(Brushes.DarkGray, 1);
using (var r = visual.RenderOpen())
{
    r.DrawRectangle(Brushes.White, null, new Rect(0, 0, totalW, totalH));
    foreach (var shape in shapes)
        r.DrawRectangle(null, pen, new Rect(shape.X, shape.Y, shape.Width, shape.Height));
}

rtb.Render(visual);

var jpg = new JpegBitmapEncoder() { Frames = { BitmapFrame.Create(rtb) } };
using (var f = File.Create(@"d:\testrender.jpg"))
    jpg.Save(f);
 2
Author: VladD, 2018-09-07 21:07:46