0

I am having an odd issue whereby when I then try to iterate over the pixels of the PictureBox or save the bmp it is just all black.

The intention of the tool is that you select a font, size, and style, and then it loops over the ASCII chars of that font and shows each character in the picture box, and converts the pixel data into a HEX array so I can use them on LCD displays.

The main part of the tool works whereby it is correctly looping through the ASCII chars and displaying them in the picture box but after each char is drawn to the picture box and I then try to iterate over the pixels of the PictureBox every pixel is returned as 0,0,0 RGB "black" and if I save the bmp which was drawn to the PictureBox that too is all black, but again I can see the bmp of that char correct drawn in the PictureBox yet the PictureBox data and bmp data does not match what I see in the PictureBox itself, I am truly lost as to why I am unable to correctly iterate or save the bmp or PictureBox.

I have tried not using async functions which is not ideal as I want the UI to be free, and I have tried various means to read the pixels and save the bmp but the result is the same. I hope to ask if anyone knows why I am getting this odd behavior and the solution to the issue.

Regards from Ed.

    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;

    namespace generateFonts
    {
        public partial class Form1 : Form
        {
            string font = "";
            float fontSize = 0;
            FontStyle fontStyle = FontStyle.Regular;

            public Form1()
            {
                InitializeComponent();
                comboBox1.SelectedIndex = 0;
                comboBox2.SelectedIndex = 0;
                comboBox3.SelectedIndex = 0;

                font = comboBox1.SelectedItem.ToString();
                fontSize = Convert.ToInt32(comboBox2.SelectedItem);
                fontStyle = FontStyle.Regular;
            }

            private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
            {
                font = comboBox1.SelectedItem.ToString();
            }

            private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
            {
                fontSize = Convert.ToInt32(comboBox2.SelectedItem);
            }

            private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
            {
                if (comboBox3.SelectedIndex == 0)
                    fontStyle = FontStyle.Regular;
                else if (comboBox3.SelectedIndex == 1)
                    fontStyle = FontStyle.Italic;
                else if(comboBox3.SelectedIndex == 2)
                    fontStyle = FontStyle.Bold;
            }

            private async void button1_Click(object sender, EventArgs e)
            {
                await Task.Run(() => StartProcess(1));
            }

            private void StartProcess(int runs)
            {
                // Font 
                Font myFont = new Font(font, fontSize, fontStyle);

                List<string> bytes = new List<string>();

                string[] bits = { "0", "0", "0", "0", "0", "0", "0", "0" };
                byte bitPos = 0;

                for (byte i = 32; i < 126; i++)
                {
                    //Create a Image-Object on which we can paint
                    Image bmp = new Bitmap(200, 200);

                    //Create the Graphics-Object to paint on the Bitmap
                    Graphics g = Graphics.FromImage(bmp);

                    string c = Convert.ToChar(i).ToString();

                    //Get the perfect Image-Size so that Image-Size = String-Size
                    SizeF size = g.MeasureString(c, myFont);

                    //Use this to become better Text-Quality on Bitmap.
                    g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    g.PixelOffsetMode = PixelOffsetMode.HighQuality;

                    //Here we draw the string on the Bitmap
                    g.DrawString(c, myFont, new SolidBrush(Color.Black), 0, 0);

                    if (!Directory.Exists("FontBmps"))
                        Directory.CreateDirectory("FontBmps");

                    this.Invoke((MethodInvoker)delegate ()
                    {
                        pictureBox2.Width = Convert.ToInt32(size.Width);
                        pictureBox2.Height = Convert.ToInt32(size.Height);
                        pictureBox2.Image = bmp; // <--- this is working and the picturebox shows the bmp correctly
                        bmp.Save("FontBmps/" + i + "_" + font + "_" + fontSize + "px_" + fontStyle + ".bmp", ImageFormat.Bmp); // <--- error here: this saves a black square instead of the bmp i see displayed in the picturebox GUI ??
                        // Even if i save the picturebox itself that too is just a black square instead of the correct image shown in the GUI ??

                        // now convert the bmp to a HEX array of pixels
                        for (int h = 0; h < pictureBox2.Height; h++)
                        {
                            for (int w = 0; w < pictureBox2.Width; w++)
                            {
                                Color colour = (pictureBox2.Image as Bitmap).GetPixel(w, h);

                                if (colour.R == 0 && colour.G == 0 && colour.B == 0)
                                {
                                    bits[bitPos] = "1";
                                }
                                else
                                {
                                    bits[bitPos] = "0"; // <-- never hits me, again for some reason the bmp or picturebox is all black pixels data but i see it correctly show in the picturebox GUI ??
                                }

                                if (bitPos < 7)
                                    bitPos++;
                                else
                                {
                                    //string bitStr = bits.ToString();
                                    //string hex = Convert.ToByte(bitStr, 2).ToString("x2");
                                    //bytes.Add(hex);
                                    bitPos = 0;
                                    for(byte n = 0; n < 8; n++)
                                    {
                                        bits[n] = "0";
                                    }
                                }

                            }
                        }

                        if (bitPos != 0)
                        {
                            // TO DO...
                        }

                    });
                    Thread.Sleep(500); // <--- i have this just to see it displaying the chars but i have removed it with no effect to the issue 
                }
                // now add List to a file in the correct format
                foreach (string str in bytes)
                {
                    Console.WriteLine(str);
                    // TO DO...
                }
            }


        }
    }

Tools GUI

Jackdaw
  • 7,626
  • 5
  • 15
  • 33
edwin
  • 181
  • 2
  • 10

1 Answers1

1

I believe the image is black, but some parts have transparency. That is, you would need to check Alpha (Color.A). What you see in the picture box, would be the background color of the picture box where it is transparent.

You won't see the transparency in the saved file, given that the ImageFormat.Bmp does not support transparency. Try Png instead, which supports transparency (and has lossless compression).

Alternatively, you can use Graphics.Clear to have the image be the color you want for background (white, I guess) before drawing to it.


Aside from that, I'll suggest to use bmp instead of (pictureBox2.Image as Bitmap), and use Bitmap.LockBits. That would improve performance.

This might be useful for reference: Converting a bitmap to monochrome. See also C# - Faster Alternatives to SetPixel and GetPixel for Bitmaps for Windows Forms App.

Theraot
  • 31,890
  • 5
  • 57
  • 86