Looking at your form I can guess what you want and what you are missing at the moment..
Your code:
g.DrawString(someText, someFont, someBrush, 50,50);
will always print to a fixed location. (And it doesn't even show :-()
So the first thing to do is to create a class level variable to hold the location:
Point textLocation = new Point(-123, -321);
For cleaner code let's add one more:
readonly Point Invalid = new Point(-123, -321);
Later we want to test if the location is valid but a Point
is a structure and can't be null
and while there is a Point.Empty
this really is (0,0), which makes it a quite normal value.. So we use a magic number but only here and with a helpful name ;-)
Now we can apply the text using the new variable:
private void cb_ApplyText_Click(object sender, EventArgs e)
{
Graphics g = Graphics.FromImage(pictureBox1.Image);
g.DrawString(textBox1.Text,
new Font("Tahoma", Convert.ToInt32(numericUpDown1.Value)),
new SolidBrush(foreColor), textLocation);
textLocation = Invalid;
pictureBox1.Refresh();
}
Note that I get my font size from a NumericUpDown
.
More interesting: By calling Refresh
we nudge the PictureBox
to show the changes in the Image..
Also note how I set the testLocation
variable to Invalid
, so we do not draw it onto the surface after having drawn in into the image pixels..
Now for the real issue: How to make the location dynamic. For this you need to code the MouseMove
event:
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (!e.Button.HasFlag(MouseButtons.Left)) return;
textLocation = e.Location;
pictureBox1.Invalidate();
}
Note the Invalidate
call: This triggers the Paint
event, which we need to draw the text at the current mouse position:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (textLocation != Invalid)
e.Graphics.DrawString(textBox1.Text,
new Font("Tahoma", Convert.ToInt32(numericUpDown1.Value)),
new SolidBrush(foreColor), textLocation);
}
Nothing special here except the check for a valid text location.
Now while holding the mouse button down you can move the text and when its position is ok you apply it with the button.
Note one more potential problem: The two DrawString
calls use two different Graphics
objects and this will only work if both have the same resolution. e.Graphics
will have the resolution of the screen but an image you load can have any resolution or even none..
The simplest way to avoid problems here is to change the Image's resolution until saving it; then reset to the values you have to store after the load..
Update: Here is an example of a versatile save method that let's you pick various file formats:
private void cb_Save_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
// .. add more formats if you want here!
sfd.Filter = "Jpg|*.jpg|Jpeg|*.jpeg|PNG|*.png";
ImageFormat format = ImageFormat.Jpeg;
if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
if (sfd.FileName.ToLower().EndsWith(".png")) format = ImageFormat.Png;
// ..and here!
}
((Bitmap)pictureBox1.Image).SetResolution(ImgDpi.X, ImgDpi.Y);
pictureBox1.Image.Save(sfd.FileName, format);
}