0

Okay, to start off. I'm trying to make dynamic editable, addable, and removeable text onto a picturebox. I got that working.

When saving an image from a picturebox, it doesn't save the labels. I now got it to draw the labels as a string using Graphics. Yet, it only draws the last modified/added/edited label to the pictureBox. I'm lost.

Here's my code for drawing the labels & saving them:

if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string ext = Path.GetExtension(sfd.FileName);
                switch (ext)
                {
                    case ".jpg":
                        format = ImageFormat.Jpeg;
                        break;
                    case ".bmp":
                        format = ImageFormat.Bmp;
                        break;
                }
                Bitmap bmp = new Bitmap(pictureBox1.Image);

                RectangleF rectf = new RectangleF(70, 90, 90, 50);

                Graphics g = Graphics.FromImage(bmp);

                g.SmoothingMode = SmoothingMode.AntiAlias;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;

                g.Flush();
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
                SolidBrush brush = new SolidBrush(label.ForeColor);

                for (int i = 0; i < n; i++)
                { 
                    g.DrawString(label.Text, label.Font, brush, label.Location);
                    label.SelectNextControl(label, false, false, true, false);
                }

                pictureBox1.Image = bmp;
                pictureBox1.Image.Save(sfd.FileName, format);
            }

Here's where the labels are defined and created:

label = new CustomLabel();
label.Name = "" + n;
label.Location = new Point(newTextbox.Location.X, newTextbox.Location.Y);
label.Text = newTextbox.Text;
label.Font = new Font("Verdana", fontSize);
label.BackColor = Color.Transparent; 

label.ForeColor = textColor;
label.AutoSize = true;
label.Visible = true;
newTextbox.Visible = false;
newTextbox.Dispose();

pictureBox1.Controls.Add(label);
TextSelected = false;
label.DoubleClick += new System.EventHandler(this.label_DoubleClick);
label.MouseDown += new MouseEventHandler(this.label_MouseDown);
label.MouseUp += new MouseEventHandler(this.MouseUp);
label.MouseMove += new MouseEventHandler(this.MouseMove);
n++;

And n is defined:

public int n = 1;

Where the stroke is added to the text:

public class CustomLabel : Label
    {
        public CustomLabel()
        {
            OutlineForeColor = Color.Black;
            OutlineWidth = 3;
        }
        public Color OutlineForeColor { get; set; }
        public float OutlineWidth { get; set; }
        protected override void OnPaint(PaintEventArgs e)
        {
            e.Graphics.FillRectangle(new SolidBrush(BackColor), ClientRectangle);
            using (GraphicsPath gp = new GraphicsPath())
            using (Pen outline = new Pen(OutlineForeColor, OutlineWidth)
            { LineJoin = LineJoin.Round })
            using (StringFormat sf = new StringFormat())
            using (Brush foreBrush = new SolidBrush(ForeColor))
            {
                gp.AddString(Text, Font.FontFamily, (int)Font.Style,
                    Font.Size, ClientRectangle, sf);
                e.Graphics.ScaleTransform(1.3f, 1.35f);
                e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
                e.Graphics.DrawPath(outline, gp);
                e.Graphics.FillPath(foreBrush, gp);
            }
        }
    }
Disloyal g
  • 20
  • 8
  • The previous one has 30+ views and no answer. I need to get this resolved. I've tried multiple "solutions" that failed. I deleted the old post. – Disloyal g Feb 06 '18 at 06:42

1 Answers1

1

The problem is in your for loop:

for (int i = 0; i < n; i++)
{ 
    g.DrawString(label.Text, label.Font, brush, label.Location);
    label.SelectNextControl(label, false, false, true, false);
}

Here label never changes, so you are just drawing the same label n times. And I don't know what SelectNextControl does.

I suggest looping over the controls in the picture box:

foreach (var customLabel in pictureBox1.Controls.OfType<CustomLabel>()) {
    g.DrawString(customLabel.Text, customLabel.Font, brush, customLabel.Location);
}
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • Awesome! That works! Now, one more question. How would I make it delete the label afterwards that way it's not overlapping? As in, it writes to the image but the label is still there so it's two layers of the same text. – Disloyal g Feb 06 '18 at 07:08
  • Do `pictureBox1.Controls.Clear()` after the foreach loop. @Disloyalg – Sweeper Feb 06 '18 at 07:14
  • Now it's removing all but the first added again and it's not adding the stroke. – Disloyal g Feb 06 '18 at 07:15
  • @Disloyalg Do you mean the output image does not have text on them? And that there is still a label on the picture box? – Sweeper Feb 06 '18 at 07:21
  • The output image has all the text it should have and the labels are still on the picturebox. – Disloyal g Feb 06 '18 at 07:24
  • Once I added pictureBox1.Controls.Clear() after the loop, it only added the first label onto the output image. – Disloyal g Feb 06 '18 at 07:25
  • UPDATE: Some reason I had the pictureBox1.Controls.Clear() inside of the foreach loop. Once I actually moved it out, it gets rid of all the labels and outputs the text onto the image properly but it doesn't add the stroke to it. – Disloyal g Feb 06 '18 at 07:26
  • @Disloyalg What stroke are you talking about? Where do you want to add it? – Sweeper Feb 06 '18 at 07:28
  • I want to add an outline around the text. I updated the main thread with where it currently adds the stroke to the text. If I don't add 'pictureBox1.Controls.Clear()' after the foreach loop, the stroke it drawn around the text but the label control doesn't leave either. – Disloyal g Feb 06 '18 at 07:30
  • @Disloyalg As a hack, I would set all the labels' `ForeColor` to transparent, but this is not really a long term solution. I suggest you figure out a way to draw the outline not in the `CustomLabel`'s graphics, but in the picture box's or the form's graphics. And this is kind of going out of the scope of this question. I suggest you ask a new one if you still struggle. – Sweeper Feb 06 '18 at 07:45
  • Figured it out. Thank you! :) – Disloyal g Feb 06 '18 at 08:47