Alignment property of Pens tool in WinForms graphics - c#

When I want to draw a rectangle in c# using pen tools If the rectangle width and height is less then the pens width then program draw nothing in from if pens alignment property Inset.But when I set alignment center then It print a rectangle. which is not size of my rectangle. Actually what happened at that time?
example:
Pen p = new Pen(Color.Black, 300);
p.Alignment = PenAlignment.Center;
g.DrawRectangle(p, 100, 100,10, 10);
p.Dispose();
The output figure is:
But how it is possible to draw a rectangle of 1o pixel width,hight with a pen of 300 pixel width?

So, basically, when the rectangle width or height smaller then 300px, you want to draw a black filled rectangle?
void DrawRectangle(Graphics g, Color pencolor, int penwidth, Rectangle x)
{
if(x.Width < penwidth || x.Height < penHeight)
{
Pen p = new Pen(pencolor);
p.Alignment = PenAlignment.Inset;
g.FillRectangle(p, x);
p.Dispose();
}
else
{
Pen p = new Pen(pencolor, penwidth);
p.Alignment = PenAlignment.Inset;
g.DrawRectangle(p, x);
p.Dispose();
}
}
Hope that helps.

Related

Draw rectangle box for letters

My code. Output:
Bitmap bitmap = new Bitmap(600, 300, PixelFormat.Format32bppArgb);
Graphics g = Graphics.FromImage(bitmap);
GraphicsPath path = new GraphicsPath();
StringFormat format = new StringFormat();
Rectangle rect = new Rectangle(0, 0, 600, 300);
SolidBrush Brush = new SolidBrush(Color.White);
g.FillRectangle(Brush, rect);
g.SmoothingMode = SmoothingMode.AntiAlias;
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
path.AddString(textBox1.Text, FontFamily.GenericSansSerif, (int)FontStyle.Bold, 128, rect, format);
Brush = new SolidBrush(Color.Blue);
g.FillPath(Brush, path);
float x = path.GetBounds().X;
float y = path.GetBounds().Y;
float w = path.GetBounds().Width / textBox1.Text.Length;
float h = path.GetBounds().Height;
Pen redPen = new Pen(Color.Red, 2);
for (int i = 0; i < textBox1.Text.Length+1; i++)
{
rect = new Rectangle((int)x, (int)y, (int)w*i, (int)h);
g.DrawRectangle(redPen, rect);
}
pictureBox1.Image = bitmap;
I am getting the wrong result in the output because I cannot get the corners of the letters and am using the wrong way.
But i need get correct pixels of letter corners, draw rectangle and fill it.
Like this:
This line made me find one error in your code:
for (int i = 0; i < textBox1.Text.Length+1; i++)
It should be:
for (int i = 0; i < textBox1.Text.Length; i++)
But then indeed only 3 red boxes seem to appear.
The reason for that is the first rectangle (with your code) is very small, because the width is (int)w*i. That should be (int)w*(i+1).
Now back to the place where you are drawing rectangles.
If you take the text 'WWWW', you will see that your solution seems pretty OK.
But if you test with 'IIII', ten you should note that the left-most 'I' is left aligned in the red box, and the right-most 'I' is right aligned in the red box.
You are drawing 4 equal boxes round 4 letters with different with.
A solution could be to draw the letters with a monospaced font.
or, if you do not want a monospaced font, look at How to measure width of character precisely?

DrawEllipse: Ellipse goes outside of the Bitmap size

I want to draw a circle with DrawEllipse on a specified Bitmap, with the same size of the Bitmap, but the result is that the circle appears clipped at the edges.
Why this problem?
Bitmap layer = new Bitmap(80, 80);
using (Graphics g = Graphics.FromImage(layer))
{
using (Pen p = new Pen(Color.Black, 4))
{
g.DrawEllipse(p, new Rectangle(0, 0, layer.Width, layer.Height));
}
}
pictureBox3.Size = new Size(100, 100);
pictureBox3.Image = layer;
By default a Pen has a PenAlignment.Center.
This means that half of its widh will draw outside the bounding rectangle.
You can simply avoid the issue by changing it to PenAlignment.Inset:
using (Pen p = new Pen(Color.Black, 4) { Alignment = PenAlignment.Inset})
{
g.DrawEllipse(p, new Rectangle(0, 0, layer.Width, layer.Height));
}
Update: If you want to turn on smoothing for the Graphics object you will need 1 or 2 extra pixels on both sides of the pen stroke for the anti-aliasing pixels. Using a smaller bounding rectanlge can't be avoided now. But..:
Rectangle rect = new Rectangle(Point.Empty, layer.Size);
rect.Inflate(-1, -1); // or -2
..should do..

DrawEllipse: Antialiasing broken with PenAlignment.Inset

As suggested by #TaW on this previous question, I setted PenAlignment.Inset to draw the circle inside the Bitmap, but this caused another problem.
I want to draw a circle on a specified Bitmap with antialiasing.
SmoothingMode.AntiAlias
The problem is that, when I use PenAlignment.Inset, the antialiasing doesn't work correctly!
Instead, with PenAlignment.Center, it works correctly...
Any suggestion to resolve this problem?
Bitmap layer = new Bitmap(80, 80);
using (Graphics g = Graphics.FromImage(layer))
{
using (Pen p = new Pen(Color.Black, 4))
{
p.Alignment = PenAlignment.Inset;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.DrawEllipse(p, new Rectangle(0, 0, layer.Width, layer.Height));
}
}
pictureBox3.Size = new Size(100, 100);
pictureBox3.Image = layer;
(Note the bugs on the left image)
Deflating the bounding rectangle by 1/2 of the pen's stroke width should solve this problem. By "deflate", I mean pull in all 4 sides towards the rectangle's center by 1/2 pen width:
float halfPenWidth = p.Width*0.5f;
g.DrawEllipse(p, new RectangleF(halfPenWidth, halfPenWidth, layer.Width - p.Width, layer.Height - p.Width));
or plugging in a hardcoded pen width of 4:
g.DrawEllipse(p, new Rectangle(2, 2, layer.Width - 4, layer.Height - 4));
Note that the full pen width must be subtracted from the rectangle's width and height in order to pull the right and bottom sides in by 1/2 pen width while keeping the rectangle centered on the same point.
Using this code with pen alignment centered, 1/2 of the stroke width will be drawn outside of the rectangle at the points where the ellipse touches the rectangle, but it will still be drawn inside the bitmap.

How do I remove the margin when drawing a rectangle inside a panel in a Windows Form?

Firstly, for context, I'm a beginner in C# and I'm playing around with forms.
I have attempted to draw a rectangle to a panel ("myPanel") on a form ("Form1") but there is a margin or some sort of padding which I cannot remove.
I have set the "padding" and "margin" properties of "myPanel" to 0 with no success.
The code is:
namespace Forms___Playing_with_Graphics
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void myPanel_Paint(object sender, PaintEventArgs e)
{
// rectangle, slightly smaller than size of panel
int topLeftx = myPanel.Location.X;
int topLefty = myPanel.Location.Y;
int width = myPanel.Size.Width - 5;
int height = myPanel.Size.Height - 5;
Graphics g = e.Graphics;
Rectangle r = new Rectangle(topLeftx, topLefty, width, height);
Pen p = new Pen(Color.Black, 5F);
g.DrawRectangle(p, r);
}
}
}
A screenshot of the result:
How do I remove this padding between the rectangle and the inside left and top edges? My naive expectation was for the rectangle to start in the very top-left corner.
Any help would be greatly appreciated.
Top left corner has coordinates x = 0, y = 0. But you should also keep in mind width of rectangle border. If you want rectangle border to fit exactly to the panel which contains it, then you should step inside half of border width:
private void myPanel_Paint(object sender, PaintEventArgs e)
{
float borderWidth = 5f;
float topLeftx = borderWidth / 2;
float topLefty = borderWidth / 2;
float width = panel2.ClientSize.Width - borderWidth;
float height = panel2.ClientSize.Height - borderWidth;
Graphics g = e.Graphics;
Pen pen = new Pen(Color.Black, borderWidth);
g.DrawRectangle(pen, topLeftx, topLefty, width, height);
}
Result:

Drawing Colors in a picturebox?

In C# i have a picturebox. i would like to draw 4 colors. The default will be white, red, green, blue. How do i draw these 4 colors stritched in this picbox? or should i have 4 picbox? in that case how do i set the rgb color?
You need to specify what it is you would specifically like to draw. You can't draw a red - that makes no sense. You can, however, draw a red rectangle at location (0,0) which is 100 pixels tall and 100 wide. I will answer what I can, however.
If you want to set the outline of a shape to a specific color, you would create a Pen object. If you want to fill a shape with a color, however, then you would use a Brush object. Here's an example of how you would draw a rectangle filled with red, and a rectangle outlined in green:
private void pictureBox_Paint(object sender, PaintEventArgs e)
{
Graphics graphics = e.Graphics;
Brush brush = new SolidBrush(Color.Red);
graphics.FillRectangle(brush, new Rectangle(10, 10, 100, 100));
Pen pen = new Pen(Color.Green);
graphics.DrawRectangle(pen, new Rectangle(5, 5, 100, 100));
}
Add a PictureBox to the form, create an event handler for the paint event, and make it look like this:
private void PictureBox_Paint(object sender, PaintEventArgs e)
{
int width = myPictureBox.ClientSize.Width / 2;
int height = myPictureBox.ClientSize.Height / 2;
Rectangle rect = new Rectangle(0, 0, width, height);
e.Graphics.FillRectangle(Brushes.White, rect);
rect = new Rectangle(width, 0, width, height);
e.Graphics.FillRectangle(Brushes.Red, rect);
rect = new Rectangle(0, height, width, height);
e.Graphics.FillRectangle(Brushes.Green, rect);
rect = new Rectangle(width, height, width, height);
e.Graphics.FillRectangle(Brushes.Blue, rect);
}
This will divide the surface into 4 rectangles and paint each of them in the colors White, Red, Green and Blue.
If you want to use non-predefined colors, then you need to get a Color object from the static method Color.FromArgb().
int r = 100;
int g = 200;
int b = 50;
Color c = Color.FromArgb(r, g, b);
Brush brush = new SolidBrush(c);
//...
Best RegardsOliver Hanappi

Categories

Resources