How to draw a text in a shape? C# - c#

The question is simple, assuming you have a shape (lets say a rectangle) and a text ("hello" for example), so it'll write the text all accross the borders of the rectangle for as many times as it fits, for example:
hello hello hello hello
hello hello
hello hello
hello hello hello hello
In order to do it I assume you'd need to use a graphics variable, I just dont know how to do it.
A code for drawing a string in a bitmap object:
Bitmap tempp = new Bitmap(1, 1);
Graphics g = Graphics.FromImage(tempp);
SizeF w = g.MeasureString("22", new Font("Tahoma", 200));//in order to get the size of the string as a pixel measurement
Bitmap bmp = new Bitmap((int)w.Width+1, (int)w.Height+1);//the bitmap that will contain the text as a picture
RectangleF rectf = new RectangleF(0, 0, (int)w.Width+1, (int)w.Height+1);
g = Graphics.FromImage(bmp);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
StringFormat format = new StringFormat()
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
g.DrawString("22", new Font("Tahoma", 200), Brushes.Black, rectf, format);
g.Flush();
Thanks in advance.
For second comment:
hello hello hello
hel llo
hel llo
hello hello hello

I hope this is what you need. There isn't much to explain here. The logic is pretty straightforward.
public string MyString = "Hello"
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var g = e.Graphics;
var strFont = new Font("Tahoma", 10);
var strSizeF = g.MeasureString(MyString, strFont);
var canvas = new Rectangle
{
Height = 200,
Width = 200,
Location = new Point(10, 10),
};
g.DrawRectangle(new Pen(new SolidBrush(Color.Blue)), canvas);
var nx = (int)(canvas.Width / strSizeF.Width);
var ny = (int)(canvas.Height / strSizeF.Height);
var spacingX = (canvas.Width - nx * strSizeF.Width) / (nx-1);
var spacingY = (canvas.Height - ny * strSizeF.Height) / (ny-1);
//draw top row and bottom row
int i;
for (i = 0; i < nx; i++)
{
g.DrawString(
MyString,
strFont,
Brushes.Black,
new PointF(canvas.X + i*(strSizeF.Width + spacingX), canvas.Y)
);
g.DrawString(
MyString,
strFont,
Brushes.Black,
new PointF(canvas.X + i * (strSizeF.Width + spacingX), canvas.Y + canvas.Height - strSizeF.Height)
);
}
//divide the string into half
var isLengthOdd = MyString.Length % 2 != 0;
var substr1 = MyString.Substring(0, MyString.Length / 2 + (isLengthOdd ? 1 : 0));
var substr2 = MyString.Substring(MyString.Length / 2, MyString.Length - MyString.Length / 2);
var substr2SizeF = g.MeasureString(substr2, strFont);
//draw side rows
for (i = 1; i < ny - 1; i++)
{
g.DrawString(
substr1,
strFont,
Brushes.Black,
new PointF(canvas.X, canvas.Y + i * (strSizeF.Height + spacingY))
);
g.DrawString(
substr2,
strFont,
Brushes.Black,
new PointF(canvas.X + canvas.Width - substr2SizeF.Width, canvas.Y + i * (strSizeF.Height + spacingY))
);
}
}
Result:

Related

How to set fontweight?

I'm writing a simple application in c# .net core 6 and winform to "assemble" some pngs and write some text on it.
This is the Photoshop output. The Title "Baldur the invincible" is wrote in Diablo Light when i'm writing it with DrawString with Font("Diablo", 30, FontStyle.Regular)
and this is my output with the Font.
In photoshop i used Diablo Light font but in the list of system fonts, from C# code, i see just Diablo Regular.. and the result is different.
How i can set the fontweight ?
here some code:
// ---------------------------------------------------------------------------------------------- +
// All TEXT ------------------------------------------------------------------------------------- +
// ---------------------------------------------------------------------------------------------- +
{
//string familyName;
//string familyList = "";
//FontFamily[] fontFamilies;
//InstalledFontCollection installedFontCollection = new InstalledFontCollection();
//fontFamilies = installedFontCollection.Families;
Font title_font = new Font("Diablo", 30, FontStyle.Regular);
Font sub_font = new Font("Diablo", 25, FontStyle.Regular);
List<Font> list_fonts = new List<Font>();
list_fonts.Add(title_font);
list_fonts.Add(sub_font);
RectangleF tit_rect = new RectangleF(165, 70, w - (165 * 2), h);
//RectangleF sub_rect = new RectangleF(165, 82 + 30, w - (165 * 2), h);
var v = m_dict_titles["Title"];
string curr_string = tabbed_value[v].ToUpper();
float offsety = WriteTitleTextf2(map_back, 0, TL(curr_string, false), tit_rect, list_fonts, StringAlignment.Near, 5);
}
public void WriteOnBitmapf(Bitmap bmp, int col, Font font, String text, RectangleF rectf, StringAlignment st_align, float stringi = 0.0f)
{
float size = font.Size;
Graphics g = Graphics.FromImage(bmp);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
StringFormat format = new StringFormat()
{
Alignment = st_align,
LineAlignment = StringAlignment.Near
};
Brush br = col == 0 ? new SolidBrush(Color.FromArgb(0, 0, 0)) : new SolidBrush(Color.FromArgb(255, 255, 255));
g.DrawString(text, font, br, rectf, format);
g.Flush();
}

How to make painted structures clean in Graphics(C#)

I used some basic code to draw lines on an bitmap, but I cannot think of any reason
why the surroundings of these lines are not deep black. If there is any solution I would be really interested in it. Thank you!
This is my code:
Bitmap bm = new Bitmap(3200, 1600, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
double step = werte.Count / 3200;
Pen whitePen = new Pen(Color.White, 3);
var graphics = Graphics.FromImage(bm);
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
graphics.FillRectangle(new SolidBrush(Color.Black), 0, 0, 3200, 1600);
int lastangezeigtH = (int)(1600 - ((werte[(int)(0 * step)] - min) * 1600 / deltaMinMax));
for (int i = 1; i < 3200; i++)
{
double h = (werte[(int)(i * step)] - min) * 1600 / deltaMinMax;
int angezeigtH = (int)(1600 - h);
//bm.SetPixel(i, angezeigtH, Color.White);
graphics.DrawLine(whitePen,i - 1, lastangezeigtH, i, angezeigtH);
lastangezeigtH = angezeigtH;
}

How to apply more than one filter to the image using Aforge

I can filter red and blue color separately but i want to filter both at the same time.. so my code is like this
//FOR RED COLOR
ColorFiltering filter = new ColorFiltering();
filter.Red = new IntRange(100, 255);
filter.Green = new IntRange(0, 75);
filter.Blue = new IntRange(0, 75);
filter.ApplyInPlace(image1);
MyDraw(image1);
// FOR BLUE COLOR
EuclideanColorFiltering filter2 = new EuclideanColorFiltering();
filter2.CenterColor = new RGB(Color.FromArgb(9, 39, 101));
filter2.Radius = 50;
filter2.ApplyInPlace(image1);
MyDraw(image1);
public void MyDraw(Bitmap image)
{
BlobCounter blobCounter = new BlobCounter();
blobCounter.MinWidth = 2;
blobCounter.MinHeight = 2;
blobCounter.FilterBlobs = true;
blobCounter.ObjectsOrder = ObjectsOrder.Size;
Grayscale grayFilter = new Grayscale(0.2125, 0.7154, 0.0721);
Bitmap grayImage = grayFilter.Apply(image);
blobCounter.ProcessImage(grayImage);
Rectangle[] rects = blobCounter.GetObjectsRectangles();
foreach (Rectangle recs in rects)
{
if (rects.Length > 0)
{
Rectangle objectRect = rects[0];
//Graphics g = Graphics.FromImage(image);
Graphics g = pictureBox1.CreateGraphics();
reception = "Cam," + objectRect.X + "," + objectRect.Y;
Console.WriteLine("X: " + objectRect.X + " Y:" + objectRect.Y.ToString());
using (Pen pen = new Pen(Color.FromArgb(252, 3, 26), 2))
{
g.DrawRectangle(pen, objectRect);
}
int objectX = objectRect.X + (objectRect.Width / 2);
int objectY = objectRect.Y + (objectRect.Height / 2);
g.DrawString(objectX.ToString() + "X" + objectY.ToString(), new Font("Arial", 12), Brushes.Red, new System.Drawing.Point(250, 1));
g.Dispose();
}
}
}
So i want to recognize blue and red shapes on webcam and draw a rectangle around recognized shape. For now, I can do it as red or blue. But I want to recognize red and blue colors at the same time
how can i add multiple filters?

Can rectangle be split in rows and columns?

private void panel1_Paint(object sender, PaintEventArgs e)
{
Pen mypen = default(Pen);
mypen = new Pen(System.Drawing.Color.Red, 3);
mypen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
//For Dash Line in Rectangle
Pen mypen1 = default(Pen);
mypen1 = new Pen(System.Drawing.Color.Blue, 1);
mypen1.DashStyle![enter image description here][2] = System.Drawing.Drawing2D.DashStyle.Dash;
//Pen mypen2 =default(Pen);
//mypen2 = new Pen(System.Drawing.Color.Yellow, 3);
//mypen2.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
//Pen mypen3 = default(Pen);
//mypen3 = new Pen(System.Drawing.Color.Violet, 1);
//mypen3.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
L1 = Rect1LT.X + 5;
T1 = Rect1LT.Y + 5;
W1 = Rect1RB.X - Rect1LT.X;
H1 = Rect1RB.Y - Rect1LT.Y;
e.Graphics.DrawRectangle(mypen, new System.Drawing.Rectangle(L1, T1, W1, H1));
e.Graphics.DrawRectangle(mypen1, new System.Drawing.Rectangle(L1, T1, W1, H1));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1LT.X, Rect1LT.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1RT.X, Rect1RT.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1LB.X, Rect1LB.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1RB.X, Rect1RB.Y, 10, 10));
e.Graphics.FillRectangle(Brushes.Blue, Rect1LT);
e.Graphics.FillRectangle(Brushes.Blue, Rect1RT);
e.Graphics.FillRectangle(Brushes.Blue, Rect1LB);
e.Graphics.FillRectangle(Brushes.Blue, Rect1RB);
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1T.X, Rect1T.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1R.X, Rect1R.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1B.X, Rect1B.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1L.X, Rect1L.Y, 10, 10));
e.Graphics.FillRectangle(Brushes.Blue, Rect1T);
e.Graphics.FillRectangle(Brushes.Blue, Rect1R);
e.Graphics.FillRectangle(Brushes.Blue, Rect1B);
e.Graphics.FillRectangle(Brushes.Blue, Rect1L);
DataGridView dg1 = new DataGridView();
//while (!exit)
//{
// var time = GetTime();
// Update(time);
// Render(time);
//}
}
I want to Divide Rectangle in Rows and Columns and Size of Rows and Column can be changeable at runtime? and No of Rows and Columns also can be changeable? I don't want to split whole rectangle I just want to divide them in rectangle.
Here is a simplfied example:
int cols = 7; int rows = 11;
private void panel1_Paint(object sender, PaintEventArgs e)
{
Rectangle Rect = // your Rectangle!
Rectangle pRect = Rect; // panel2.ClientRectangle;
float width = 1f * pRect.Width / cols;
float height = 1f * pRect.Height / rows;
using (Pen pen = new Pen(System.Drawing.Color.Blue, 1))
{
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
for (int c = 0; c < cols; c++)
for (int r = 0; r < rows; r++)
{
RectangleF rect = new RectangleF(pRect.X + c * width, pRect.Y + r * height,
width, height);
e.Graphics.FillRectangle(Brushes.Coral, rect);
// e.Graphics.DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height);
}
for (int c = 0; c < cols; c++) e.Graphics.DrawLine(pen,
pRect.X + c * width, pRect.Y, pRect.X + c * width, pRect.Y + pRect.Height);
for (int r = 0; r < rows; r++) e.Graphics.DrawLine(pen,
pRect.X, pRect.Y + r * height, pRect.X + pRect.Width, pRect.Y + r * height);
e.Graphics.DrawRectangle(Pens.Red,
pRect.X, pRect.Y, pRect.Width - 1, pRect.Height - 1);
}
}
Note a few changes:
The border color and the fill color must not be the same.
The fill must come first or it will overwrite the border
I work with floats to fill the panel completely; if the cols and rows don't divide into the panel/rectangle size evenly, the recangles will not all have the same sizes ..
At first I have ignored your DashStyle. If you want to have a DashStyle you must completely change your plan! The reason is that if you draw Rectangles in a grid you..
..either have them overlapping and then the dashes will get in each others way. There is a DashOffset parameter but I don't think it can be twisted to make it work over any grid.
..or you need to draw the rectangles inside the grid cells but then they will be twice a thick and the patterns still will disturb each other.
Instead you simply draw only a few lines as shown!
Here is my example with Dashes:

DataGridView Merge Cells

I'm facing a problem with DataGridView component.
I know that DataGridView component cannot merge cells!
Is there any way to merge two cells from two rows as tha above example ?
**************************
* First Name | Last Name *
* ---------- |---------- *
* | David *
* Smith |---------- *
* | Anna *
*------------|---------- *
* Michael | Daniel *
**************************
etc.
Please try to do like this,
this.Paint += new PaintEventHandler(dataGridView1_Click); //Call event while loading
private void dataGridView1_Click(object sender, PaintEventArgs e)
{
Font fnt = new Font("Arial", 10, FontStyle.Bold, GraphicsUnit.Point);
Rectangle rct1 = new Rectangle((dataGridView1.GetColumnDisplayRectangle(0, true).X), (dataGridView1.GetColumnDisplayRectangle(0, true).Y + dataGridView1.Columns[0].HeaderCell.ContentBounds.Height + 8), dataGridView1.GetColumnDisplayRectangle(0, true).Width - 1, (dataGridView1.GetRowDisplayRectangle((dataGridView1.Rows.Count - 1), true).Top - dataGridView1.GetRowDisplayRectangle((dataGridView1.Rows.Count - 1), true).Height));
// Create string to draw.
String drawString = "Sample Text";
// Create font and brush.
Font drawFont = new Font("Arial", 16);
SolidBrush drawBrush = new SolidBrush(Color.Black);
// Create point for upper-left corner of drawing.
float x = 150.0F;
float y = 50.0F;
// Set format of string.
StringFormat drawFormat = new StringFormat();
drawFormat.FormatFlags = StringFormatFlags.DirectionVertical;
// Draw string to screen.
e.Graphics.FillRectangle(Brushes.White, rct1);
e.Graphics.DrawString(drawString, drawFont, drawBrush, x, y, drawFormat);
Rectangle rct =new Rectangle();
rct = dataGridView1.GetRowDisplayRectangle(3, true)
rct.Height -= 1;
SizeF s =new SizeF();
s= e.Graphics.MeasureString("HORINZONTAL TEXT", dataGridView1.Font);
float lefts = (rct.Width / 2) - (s.Width / 2);
float tops = rct.Top + ((rct.Height / 2) - (s.Height / 2));
e.Graphics.FillRectangle(Brushes.White, rct);
e.Graphics.DrawString("HORINZONTAL TEXT", fnt, Brushes.Black, 2, tops);
}

Categories