c# - Transparent form doesn't show text properly - c#

The idea of my project is to show solid text on a transparent form control.
I have used this technique to make the form transparent:
BackColor = Color.Lime;
TransparencyKey = Color.Lime;
The problem I'm having is coloured edges around the text. I've tried drawing anti-aliased text using graphics and displaying the text using labels but neither worked. I still have disgusting-looking, pixelated, lime edges around my text.
I looked around a little - posts are usually concerned with making the form transparent not dealing with this issue.

You can get reasonable output by using TextRenderingHint.AntiAliasGridFit.
private void TestForm_Paint(object sender, PaintEventArgs e) {
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
e.Graphics.DrawString("Header", this.Font, SystemBrushes.WindowText, new Point(1, 1));
}
But if you plan on using large fonts, it won't render too well since it can't really antialias properly.
The nature of fonts, in general, is to have a background to draw on. If you have black text on a transparent form, and the end user has a black background-- the end user isn't going to see anything.

Related

Draw/Render Text over a DirectX Video (PictureBox Control as Owner)

I have managed to implement a video playing capability to my WinForms Application Project using DirectX's Video Class (although old and deprecated). My goal was to use this video as a background for a specific form with minimal controls. I've tried using GIF files but the color quality is just not good enough, using APNG on the other hand leaves me with a hilariously large .apng file size.
As Dx's Video Class needs a control to play the video into - i've used a PictureBox Control to make do where a Panel Control can also substitute for this. My Next Goal is to draw/render a text over the PictureBox Control which acts as the host for the Video. This is due to that Label Controls are not transparent nor does it support transparency in 100% so i am trying to improvise by rendering a string using Graphics.DrawString() or TextRenderer.DrawText().
I've tried both but neither was able to display the text as i've expected it to be.
Below is my code snippet over the Paint Event for the PictureBox Control:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
var font = new Font("Helvetica Neue LT Std 65", 15);
var brush = new SolidBrush(Color.White);
var point = new Point(55, 150);
string welcomeText = "Welcome, User!";
// e.Graphics.DrawString(welcomeText, font, brush, point);
TextRenderer.DrawText(e.Graphics, welcomeText, font, point, Color.White);
pictureBox1.Refresh();
}
when running my source code, nothing happens actually, just like in this GIF: https://imgur.com/3uYdCF1
however, what i'm expecting is something like this:
Is it even possible to achieve this in the first place with WinForms? If so, i'd like some help to implement this. Thank you.

Translate Screen points to Picture Points

I am trying to draw text on image using System.Drawing.Graphics but I'm having a little difficulty in positioning the text correctly in the image. My program is supposed to allow the user to draw a textbox, edit it and then apply it's text permanently to an image in the PictureBox. But each time I try to draw the text to the image, it is either too small, or positioned in the wrong spot. Here's my code:
var bmp = new Bitmap(OriginalImage);
// Box is the already drawn textbox.
using (var graphics = Graphics.FromImage(bmp))
{
graphics.DrawString(Box.Text,new Font(Box.Font.FontFamily, Box.Font.Size, FontStyle.Regular), Brushes.Black, Box.Location);
}
Also, the PictureBox SizeMode is set to Zoom, though the textbox is always well positioned (made sure of that :)). Any ideas or suggestions would be cherished, thanks in advance.

C# NET - Draw opaque brush on form with opacity level set

What I want to achieve is a semi-transparent background that covers the screen.
And then be able to draw non-transparent brushes on top of it.
What I have tried is to have a form with the size of the screen, then setting it's color and setting this.opacity = 0.5. However this affects all brushes in the form.
Ive also tried setting the background color to Color.Transparent, and then drawing an additional brush that covers the screen with opacity 0.5 before I then draw the opaque brushes... However the background becomes opaque as well.
Even though the style flag is set (ControlStyles.SupportsTransparentBackColor, true)
I know I can achieve this by having an additional form.
One form for the transparent background and one for the opaque foreground, but isn't that overkill?
Is there a better way?
Update 1:
Trying what is suggested in the comments.
Current state:
Form1: the main program, calls for the 'overlay' to show, which is:
Form2: Overlay background (semi-transparent black) and,
Form3: Overlay foreground, this is where the user draws.
Form 1 and 2 works as indended, however Form3 refuses to work with transparency.
If I set
this.BackColor = Color.Lime;
this.TransparencyKey = Color.Lime;
then the performance drops and the program lags heavily (although it does become transparent).
Ideally I would want to use this.BackColor = Color.Transparent; however that doesn't have any effect (solid background, no alpha).
Note that the form covers the screen and the background is usually the desktop. Maybe that's why it doesn't work?
You can override the OnPaintBackground of the form, without calling it's base.
This will enable you to specify whatever color you want for the background.
Try this:
protected override void OnPaintBackground(PaintEventArgs e)
{
using (var brush = new SolidBrush(Color.FromAgrb(50, 0, 0, 0))
{
e.Graphics.FillRectangle(brush, e.ClipRectangle);
}
}

Why Isn't ControlPaint.DrawGrid Function not Displaying Anything to a PictureBox

I want to make a graph paper grid and set the drawing to the image of a picture box. Now I might even be using the wrong thing for drawing a graph paper grid but I have asked around and some people said that the DrawGrid method would work. None of the code below is returning any errors, but when I run the button1_Click method, it doesn't display anything to the picturebox.
private void button1_Click(object sender, EventArgs e)
{
button2.Visible = true;
Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height);
Size yourGridspacing = new Size((int)numericUpDown1.Value, (int)numericUpDown2.Value);
using (Graphics G = Graphics.FromImage(bmp))
{
ControlPaint.DrawGrid(G, new Rectangle(Point.Empty, bmp.Size), yourGridspacing , Color.Black);
}
pictureBox1.Image = bmp;
}
Any idea what the problem might be?
Your PictureBox probably has a White Background.. If so, please tell the ControlPaint.DrawGrid method so..:
ControlPaint.DrawGrid(G, new Rectangle(Point.Empty, bmp.Size),
yourGridspacing , Color.White);
The param doesn't control the color of the dots; it is supposed to help find a Color that will contrast. So maybe the best way to write it will be:
ControlPaint.DrawGrid(G, new Rectangle(Point.Empty, bmp.Size),
yourGridspacing, pictureBox1.BackColor);
This will work for all colors except Color.Transparent.. (in which case the Color of the control below will decide if the dots are visible..)
You may wonder, why such a roundabout way is chosen? Well, the method DrawGrid is not really meant as a normal drawing method, like the ones in Graphics. It is one of several methods that are meant to construct a robust display of Windows controls like Button or CheckBox.. Now, the Background over which the Grid is drawn need not have only one Color; it could be an Image or a Gradient and it could change..
You are supposed to pick a typical color to represent that background. The system will then choose a Color with good contrast for the dots.
For a way to control the grid's color see the last option in my other answer!

Borderless Winform with a 1px border

This might sound like a weird question but I have C# Winform that I set the FormBorderStyle to None. So far everything is good but I was wondering if there was a way to add like a 1px border on around my form ? I know I could do it by creating my own image but I was wondering if there was a more natural way of doing it.
Thanks
I consider using an image, or creating unnecessary controls for something that is easily paintable using GDI+ a waste of resources.
I think the simplest solution is overriding the OnPaint method of your form and drawing the border yourself:
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.DrawRectangle(Pens.Black, this.Bounds);
}
Of course, you may also use your own Pen with your own color and width.
Use padding 1;1;1;1 to your form and set a background color to your form, and put a panel to your form. Set white or other normal background color to the panel. And set dock in parent controller. The background color of the form will act as a border.
How about just adding a Panel (and setting it's border) to the Form?
Thanks for the suggestions, I've decided to create 4 1px label and just toss on the edge on each side. That way:
1. They are minding their own business on the side rather than taking up the whole middle if you use use a groupbox or panel.
2. You are able to choose change your border color.
There is no more natural or non natural ways to do it. It depends on what you want.
If you put a background image on the form, you have to consider a fact that in order to be able to support resizable for you have to have resizable background images.
If you simply draw on the background with a Pen or Brush, you can support also resizable form, but you have to work more if you want to do something cool, instead with image it's easier.
You can embed some control inside the form and with color's of them make a feeling of the border. Like control, you can use Panel, as suggested in comment, can use GroupBox that creates thin broder arround, or something else.
I created this method, so you could easily set the borderposition, color and thickness.
private void customBackgroundPainter(PaintEventArgs e, int linethickness = 2, Color linecolor = new Color(), int offsetborder = 6)
{
Rectangle rect = new Rectangle(offsetborder, offsetborder, this.ClientSize.Width - (offsetborder * 2), this.ClientSize.Height - (offsetborder * 2));
Pen pen = new Pen(new Color());
pen.Width = linethickness;
if (linecolor != new Color())
{
pen.Color = linecolor;
}
else
{
pen.Color = Color.Black;
}
e.Graphics.DrawRectangle(pen, rect);
}
You could use it in the OnPaintBackground likes this:
protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaintBackground(e);
customBackgroundPainter(
e,
linethickness: 3,
linecolor: Color.DarkOrange,
offsetborder: 5
);
}

Categories

Resources