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!
Related
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.
I have been working on creating a program similar to MS Paint. I have several of the features it has down but the one which is currently giving me trouble is the rectangular selection tool. My program currently draws everything on the panel and saves it all in an ArrayList so each shape can be redrawn in Paint().
Like MS paint I would like the user to be able to select a section of the drawing on the panel and either copy it, move it, re-size it, or even delete it. I was thinking about having the user draw a rectangle & saving the information for it. Then taking that information for the rectangle, passing them to create a new Bitmap. I would then paint a new rectangle in the background color to give the appearance that the selected area was "removed" when the selected portion is moved. It sounded okay until I realized that I couldn't use the Graphics.FromImage() on the PaintEventArgs variable passed to Paint() which made my idea useless. Not sure if that makes sense so my apologies if it's a confusing mess.
I've been searching the internet for some assistance and I haven't found much to help so either this is very easy to do, very difficult, or "rectangle selection tool" is not the proper term. Any help or pointers would be greatly appreciated!!! Thank you for your time! :)
I understand that you actually have the Rectangle and now would like to copy an area from your painted Panel.
This is possible, assuming you have, as you should, placed all the painting in the Paint event of the Panel.
Then you can, use DrawToBitmap to ask the Panel to draw itself onto a new Bitmap; from there you can DrawImage the Rectangle onto your Panel.
Note: For this to integrate with your list of 'Paint-Actions' you will have to either now store that Bitmap or store the Rectangle and redo the whole operation.
using (Graphics G = panelCanvas.CreateGraphics() )
{
Rectangle R0 = new Rectangle(22,22,55,55); // your Rectangle!
using (Bitmap bmp = new
Bitmap(panelCanvas.ClientSize.Width, panelCanvas.ClientSize.Height))
{ panelCanvas.DrawToBitmap(bmp, panelCanvas.ClientRectangle);
G.DrawImage(bmp, 111f, 111f, R0, GraphicsUnit.Pixel);
}
}
Aside: Please do replace the ArrayList, which is depracated by the new List<T>, e.g. a List<PaintAction> or whatever name your class has!
If you simply want to extract a rectanglular area from the Panel Control you can use thsi function:
public Bitmap getAreaFrom(Control ctl, Rectangle area)
{
Bitmap bmp2 = new Bitmap(area.Width, area.Height);
using (Graphics G = ctl.CreateGraphics())
using (Bitmap bmp = new Bitmap(ctl.ClientSize.Width, ctl.ClientSize.Height))
{
ctl.DrawToBitmap(bmp, ctl.ClientRectangle);
using (Graphics G2 = Graphics.FromImage(bmp2))
G2.DrawImage(bmp, 0f, 0f, area, GraphicsUnit.Pixel);
}
return bmp2;
}
I would like to be able to fill any given area of an image with a given color, much like you can use paint to fill a rectangle, circle or any other shape delimited by a color.
To make this simpler I already have made the picture box source image to have the same size as the picture box itself, which should make things a bit easier.
How can I do this given that I have a picture box with an image and an already defined color and the user only has to click over the picture box to fill in any area with such color.
void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
// The color to be used
Color color = Color.Red;
// Image has same dimensions as picturebox to make things easier
Image img = pictureBox1.Image;
// Where it was clicked.
Point clickCoords = new Point(e.X, e.Y);
// Coloring that area clicked much like Paint does. How?
...
// After coloring show the result in the picture box again
pictureBox1.Image = img;
}
Thanks.
EDIT: Example of my desired behavior.
To make my goal obvious, let me add this small example.
You know MS Paint right?
You selected the pencil tool and start doing anything on the canvas, doesn't matter form or shape or even if the points your are doing with the pencil are connected or not.
Now you select the bucket tool and start clicking on the canvas. What will it do? Fill in the selected area according to the color you clicked over and how far she goes without changing with the color you have selected on the color pallet.
This is the behavior I want to emulate on my picture box mouse click event.
What you are looking for is a flood-fill algorithm. This should do the trick just fine.
The algorithm recursively searched for neighboring uncolored pixels, until it hits a wall.
You can use the code from here:
// Load the image (probably from your stream)
Image image = Image.FromFile( imagePath );
using (Graphics g = Graphics.FromImage(image))
{
Color customColor = Color.FromArgb(50, Color.Gray);
SolidBrush shadowBrush = new SolidBrush(customColor);
g.FillRectangles(shadowBrush, new RectangleF[] { rectFToFill });
}
image.Save( imageNewPath );
, but there is a one thing you missed - a rectFToFill, which you should define according your click event. There are a lot of strategies you can use, I suggest you to handle a Drag event or something like that, save the event start point and end point, after that define the rectangular you must fill:
You should examine the event points and after that create the Rectangle(F) structure using some of its constructors.
The Graphics class has a dozen methods you can use to draw some shapes or lines on your Image.
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.
I have an idea and maybe you guys can give me a good start or an idea in which path might be correct.
I have a picturebox right now loading a specific bmp file. What I want to do is load this bmp file into the picturebox and then load another picture on top of it. The kicker to this all is the 2nd picture must be drawn. The 2nd picture is just a fill in black box. This black box must also overlay on the first image exactly right, the black box has cordinates from paint on it (yes we have the # of the cordaints).
Still think the picturebox is the way to go, or is there a way to load paint into this, and then paint on top of the paint image?
1) Need to load an image
2) Need to read a specific file that has cords
3) Need to draw a black rectangle that matches those coords (Those cords were created in paint).
What do you think the best way to approach this is? A Picture box with code to draw in the cords of the redacted image
Here's a code sample that should do what you're after:
//Load in an image
pbTest.Image = Image.FromFile("c:\\Chrysanthemum.jpg");
//Create the graphics surface to draw on
using (Graphics g = Graphics.FromImage(pbTest.Image))
{
using (SolidBrush brush = new SolidBrush(Color.Black))
{
//Draw a black rectangle at some coordinates
g.FillRectangle(brush, new Rectangle(0, 0, 20, 10));
//Or alternatively, given some points
//I'm manually creating the array here to prove the point, you'll want to create your array from your datasource.
Point[] somePoints = new Point[] { new Point(1,1), new Point(20,25), new Point(35, 50), new Point(90, 100) };
g.FillPolygon(brush, somePoints);
}
}
The finished article:
This answer is written to apply to both web and non-web uses of C# (why I did not give specific examples.)
GDI and other graphics libs all have functions that will paint a filled rectangle on top of an image. This is the way to go. If you use two images there is a good chance for a standard user and a great chance for a hacker they will be able to view just the original image, exposing the information you are trying to hide.
If you only send an image with the areas redacted, you will never have to worry about them being seen.