using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace McBitFont { public partial class ImageImporter : Form { private int fw, fh, pixelization, threshold; private Color[] colorPool = [Color.Black, Color.White]; private Bitmap bmpOriginal, bmpProcessed; public Bitmap bmpScaled; public ImageImporter(int width, int height) { InitializeComponent(); fw = width; fh = height; } private void UpdateControls(byte level) { switch (level) { case 1: bmpProcessed = null; bmpScaled = null; pbProcessed.Image = null; pbScaled.Image = null; lblProcessedSize.Text = "0 x 0"; lblScaledSize.Text = "0 x 0"; btnResize.Enabled = false; btnOK.Enabled = false; btnConvert.Enabled = true; break; case 2: bmpScaled = null; pbScaled.Image = null; lblScaledSize.Text = "0 x 0"; btnOK.Enabled = false; btnResize.Enabled = true; break; case 3: btnOK.Enabled = true; break; } } private void btnOK_Click(object sender, EventArgs e) { DialogResult = DialogResult.OK; } private void btnCancel_Click(object sender, EventArgs e) { DialogResult = DialogResult.Cancel; } // Pick a color from color pool that is closest to an average of given colors private Color PickColor(Color[] colors) { int i; int r = 0; int g = 0; int b = 0; // Calculating average color amongst givet color set for (i = 0; i < colors.Length; i++) { r += colors[i].R; g += colors[i].G; b += colors[i].B; } r /= colors.Length; g /= colors.Length; b /= colors.Length; int near = 1000; int ind = 0; // Picking a closts color from color pool for (i = 0; i < colorPool.Length; i++) { int valR = colorPool[i].R - r + threshold; int valG = colorPool[i].R - g + threshold; int valB = colorPool[i].R - b + threshold; if (valR < 0) valR = -valR; if (valG < 0) valG = -valG; if (valB < 0) valB = -valB; threshold = tbThreshold.Value; int total = valR + valG + valB; if (total < near) { ind = i; near = total; } } return colorPool[ind]; } private static void DrawArrow(Graphics g, Point from, Point to, float thickness = 1, Color? color = null) { if (color == null) color = Color.Black; var pen = new Pen((Color)color, thickness) { CustomEndCap = new AdjustableArrowCap(4, 5) }; g.DrawLine(pen, from, to); } private void tbPixelization_ValueChanged(object sender, EventArgs e) { lblPixelization.Text = "Pixelization: " + tbPixelization.Value.ToString(); } private void tbThreshold_ValueChanged(object sender, EventArgs e) { lblThreshold.Text = "Threshold: " + tbThreshold.Value.ToString(); } private void btnLoadImage_Click(object sender, EventArgs e) { if (dlgLoadImage.ShowDialog() == DialogResult.OK) { bmpOriginal = new Bitmap(dlgLoadImage.FileName); pbOriginal.Image = Draw200x200(bmpOriginal); lblOrigSize.Text = bmpOriginal.Width.ToString() + " x " + bmpOriginal.Height.ToString() + " (" + pbOriginal.Image.Width.ToString() + " x " + pbOriginal.Image.Height.ToString() + ")"; // Clear other images UpdateControls(1); } } private void btnConvert_Click(object sender, EventArgs e) { pixelization = tbPixelization.Value; //Bitmap bmOrig = (Bitmap)pbOriginal.Image; bmpProcessed = new Bitmap(bmpOriginal.Width, bmpOriginal.Height); // Processing image using (Graphics g = Graphics.FromImage(bmpProcessed)) { List block; Rectangle rect = new Rectangle(); SolidBrush sb = new SolidBrush(Color.Black); Color final = Color.Black; Color pixel; // Going through original image with steps = pixelization for (int x = 0; x < bmpOriginal.Width; x += pixelization) { for (int y = 0; y < bmpOriginal.Height; y += pixelization) { block = []; // Going throug a block pixel by pixel to calculate its average color later for (int v = 0; v < pixelization; v++) { for (int c = 0; c < pixelization; c++) { if (x + v < bmpOriginal.Width && y + c < bmpOriginal.Height) { pixel = bmpOriginal.GetPixel(x + v, y + c); if (pixel.A <= tbTransparency.Value) pixel = Color.White; block.Add(pixel); } } } // Getting a color from the color pool and painting the block if (block.Count > 0) { final = PickColor(block.ToArray()); sb.Color = final; rect.X = x; rect.Y = y; rect.Width = pixelization; rect.Height = pixelization; g.FillRectangle(sb, rect); } } } } pbProcessed.Image = Draw200x200(bmpProcessed); lblProcessedSize.Text = bmpProcessed.Width.ToString() + " x " + bmpProcessed.Height.ToString() + " (" + pbProcessed.Image.Width.ToString() + " x " + pbProcessed.Image.Height.ToString() + ")"; UpdateControls(2); } private void btnResize_Click(object sender, EventArgs e) { bmpScaled = DrawScaled(bmpProcessed, fw, fh); pbScaled.Image = Draw200x200(bmpScaled); lblScaledSize.Text = bmpScaled.Width.ToString() + " x " + bmpScaled.Height.ToString() + " (" + pbScaled.Image.Width.ToString() + " x " + pbScaled.Image.Height.ToString() + ")"; UpdateControls(3); } // Draw 200x200 bitmap for picturebox private static Bitmap Draw200x200(Bitmap bmpRef) { return DrawScaled(bmpRef, 200, 200); } // Draw scaled bitmap keeping aspect ratio private static Bitmap DrawScaled(Bitmap bmpRef, int w, int h) { var scale = Math.Min(w / (double)bmpRef.Width, h / (double)bmpRef.Height); var bmpNew = new Bitmap((int)(bmpRef.Width * scale), (int)(bmpRef.Height * scale)); using (Graphics g = Graphics.FromImage(bmpNew)) { g.InterpolationMode = InterpolationMode.NearestNeighbor; g.PixelOffsetMode = PixelOffsetMode.Half; g.DrawImage(bmpRef, 0, 0, bmpNew.Width, bmpNew.Height); } return bmpNew; } private void tbThreshold_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.C) { tbThreshold.Value = 0; } } private void tbPixelization_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.C) { tbPixelization.Value = 1; } } private void tbTransparency_ValueChanged(object sender, EventArgs e) { lblTransparency.Text = "Transp. threshold: " + tbTransparency.Value.ToString(); } private void tbTransparency_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.C) { tbTransparency.Value = 32; } } private void ImageImporter_Paint(object sender, PaintEventArgs e) { DrawArrow(e.Graphics, new Point(175, 246), new Point(255, 246), 2, Color.SlateGray); DrawArrow(e.Graphics, new Point(380, 246), new Point(455, 246), 2, Color.SlateGray); } } }