I'm trying to display pixels on a monitor, in preparation for when I display on a set of LEDs. I'm doing this using a font to draw onto a bitmap, and then reading off the bitmap, whether the pixel is lighter or darker, and putting this into a 2 dimensional array of booleans. This array is then passed into my interface-specific display method, for displaying. As this set is only going to be 6 pixels high, I'm using a font made for a six pixel resolution from www.dafont.com/6px.font Currently this system doesn't display that well - some characters are not really readable.
Is this even the right way to be doing this? What should I be doing? Thanks!
Pixel map file:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Text;
using System.Linq;
using System.Text;
namespace Phidgets
{
public class StringDrawer
{
internal int height, width;
internal bool[][] mapData;
GraphicalInterface MyGraphicalInterface;
Bitmap canvas;
int MaxPixelLength;
Graphics canvasGraphics;
Brush brush = new SolidBrush(Color.Black);
Font font;
public StringDrawer(int width, int height, GraphicalInterface myInterface)
{
InitFont();
this.height = height;
this.width = width;
MaxPixelLength = 2048 + width;//2048 pixels, plus the amount of empty pixels at the end.
mapData = new bool[height][];
for (int i = 0; i < height; i++)
{
mapData[i] = new bool[width];
}
MyGraphicalInterface = myInterface;
canvas = new Bitmap(MaxPixelLength, height);
canvasGraphics = Graphics.FromImage(canvas);
}
void DrawPoint(int x, int y)
{
mapData[x][y] = true;
}
void Clear()
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
mapData[i][j] = false;
}
}
}
public void DrawString(String input)
{
input = input.ToUpper();
Clear();
PaintCanvas(input);
UpdateDataFromCanvas();
MyGraphicalInterface.Update(mapData);
}
public void UpdateDataFromCanvas()
{
for (int y = 0; y < mapData.Count(); y++)
{
for (int x = 0; x < mapData[0].Length; x++)
{
bool b = canvas.GetPixel(x, y).R < 128;//r g or b is equivalent here, half way between light and dark.
mapData[y][x] = b;
}
}
}
Bitmap GetCurrentFrame(int startX)
{
return null;
}
void PaintCanvas(String input)
{
canvasGraphics.Clear(Color.White);
canvasGraphics.DrawString(input, regFont, solidBrush, 0, 0);
}
SolidBrush solidBrush;
Font regFont;
void InitFont()
{
System.Drawing.Text.PrivateFontCollection privateFontCollection = new System.Drawing.Text.PrivateFontCollection();
privateFontCollection.AddFontFile("../../6px-Normal.ttf");
solidBrush = new SolidBrush(Color.Black);
FontFamily[] fontFamilies = privateFontCollection.Families;
string familyName = fontFamilies[0].Name;
regFont = new Font(familyName, 6,FontStyle.Regular, GraphicsUnit.Pixel);
}
}
public abstract class GraphicalInterface
{
public abstract void Update(bool[][] mapData);
}
public class ScreenInterface : GraphicalInterface
{
//int xStart = 350;
//int yStart = 23;
int xStart, yStart;
Graphics g;
Brush brush = new SolidBrush(Color.Black);
public ScreenInterface(int xStart, int yStart, Form1 f)
{
g = f.CreateGraphics();
this.xStart = xStart;
this.yStart = yStart;
}
public override void Update(bool[][] mapData)
{
const int scale = 4;
for (int y = 0; y < mapData.Count(); y++)
{
for (int x = 0; x < mapData[0].Length; x++)
{
if (mapData[y][x])
g.FillRectangle(brush, xStart + (x * scale), yStart + (y * scale), scale, scale);
}
}
}
}
public class LedInterface : GraphicalInterface
{
public override void Update(bool[][] mapData)
{
for (int y = 0; y < mapData.Count(); y++)
{
for (int x = 0; x < mapData[0].Length; x++)
{
//not implemented
}
}
}
}
}
Form1 file:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Phidgets
{
public partial class Form1 : Form
{
StringDrawer testDrawer, LedDrawer;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
const int width = 24;
const int height = 6;
ScreenInterface screen = new ScreenInterface(450, 23, this);
testDrawer = new StringDrawer(width, height, screen);
LedDrawer = new StringDrawer(width, height, new LedInterface());
}
private void closeButton_Click(object sender, EventArgs e)
{
this.Close();
}
private void GoButton_Click(object sender, EventArgs e)
{
testDrawer.DrawString("a b c");
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Thanks to defont.com/6px for the font used, and as always, much wow to stackoverflow.");
}
}
}
Any help is much appreciated - thanks!
Figured out the problem - the font wasn't even assigning!
When I called: regFont = new Font(familyName, 6,FontStyle.Regular, GraphicsUnit.Pixel);
It didn't change! Like, if you went through in the debugger, the value didn't change after the assignment. So weird. but when I changed the InitFont method to say:
void InitFont()
{
System.Drawing.Text.PrivateFontCollection privateFontCollection =
new System.Drawing.Text.PrivateFontCollection();
privateFontCollection.AddFontFile("../../6px-Normal.ttf");
solidBrush = new SolidBrush(Color.Black);
FontFamily[] fontFamilies = privateFontCollection.Families;
regFont = new Font(fontFamilies[0], 6);
}
the assignment worked. So a little anti-climactic, but thanks guys for your help.