Кодирование текста из textBox с помощью pictureBox на С#

530
30 декабря 2016, 09:44

Всем привет. Надеюсь, что здесь я найду ответ на интересующий меня вопрос. Так вот, мне нужно чтобы каждый символ из textBox обозначался своим собственным цветом в pictureBox (например буква "А" - красным цветом определенного пикселя). Для этого нужно создать БД, но вопрос заключается в следующем: как создать алгоритм за которым символы из textBox будут кодироватся в pictureBox в правильной последовательности (например первый символ из textBox в первый пиксель из picturePox, десятый в десятый и т.д.) ведь каждый раз размер изображения разный (в зависимости от количества символов в textBox; если 100 символов, то это изображение 10х10 и т.д.). И каким образом лучше организовать БД? Слово и код соответствующего цвета в RGB? Или как-то иначе? Спасибо за внимание. Надеюсь что вы поняли мою проблему.

Answer 1

Вот так. Суть в том, что массив битмапа 4 байтовый, а массив строчек 2 байтовый в этом вся некрасивость, но все работает, правда будет преимущественно темный цвет.

На форму pictureBox и textBox Ивенты: пиктур бокс клик; текстбокс текст чэндж.

using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        int sqrt=Convert.ToInt32(Math.Sqrt(textBox1.Text.Length))+1;
        Bitmap newB = new Bitmap(sqrt,sqrt);
        convertToBitmap(newB, sqrt);
        pictureBox1.Image = newB;
    }
    void convertToBitmap(Bitmap bmp, int sqrt)
    {
        Rectangle rect = new Rectangle(0, 0, sqrt, sqrt);
        BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);
        IntPtr ptr = bmpData.Scan0;
        int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
        byte[] rgbValues = new byte[bytes];
        Marshal.Copy(ptr, rgbValues, 0, bytes);
        byte[] arrText = GetBytes(textBox1.Text);//2 байта на букву взяли текст
        for (int counter = 0; counter < arrText.Length-1; counter += 2)
        {
            rgbValues[counter / 2 * 4] = arrText[counter];
            rgbValues[counter / 2 * 4+1] = arrText[counter + 1];
            rgbValues[counter / 2 * 4 + 3] = 255;
        }
        Marshal.Copy(rgbValues, 0, ptr, bytes);
        bmp.UnlockBits(bmpData);
    }
    void readFromBitmap(Bitmap bmp)
    {
        Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
        BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);
        IntPtr ptr = bmpData.Scan0;
        int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
        byte[] rgbValues = new byte[bytes];
        byte[] textValues = new byte[bytes / 2];
        Marshal.Copy(ptr, rgbValues, 0, bytes);
        for (int counter = 0; counter < rgbValues.Length; counter += 4)
        {
            textValues[counter / 2] = rgbValues[counter];
            textValues[counter / 2+1] = rgbValues[counter + 1];
        }
        MessageBox.Show(GetString(textValues));
        Marshal.Copy(rgbValues, 0, ptr, bytes);
        bmp.UnlockBits(bmpData);
    }
    static string GetString(byte[] bytes)
    {
        char[] chars = new char[bytes.Length / sizeof(char)];
        System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
        return new string(chars);
    }
    static byte[] GetBytes(string str)
    {
        byte[] bytes = new byte[str.Length * sizeof(char)];
        System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
        return bytes;
    }
    private void pictureBox1_Click(object sender, EventArgs e)
    {
        readFromBitmap((Bitmap)pictureBox1.Image);
    }
}

Давайте сделаем с базой :) База будет иметь вид txt файла, внутри буква:ARGB в формате hex(взять можно с любого сайта цвета или из пэйнта)

пример цветов для больших латинских букв A и B(красный и синий соотвественно)

A:FFFF0000
B:FF0000FF

Теперь код, добавился парсер базы(после загрузки формы используем loadBase()), изменен код. Парсить сможет, только если такая буква есть в базе цветов, ну и соответственно рисовать тоже. Потом подправим под ваши нужды, спрашивайте что не ясно.

    int[] colorsChar = new int[65535];
    void loadBase()
    {
        try
        {
            string[] ms = System.IO.File.ReadAllLines("colorBD.txt");
            foreach (string s in ms)
            {
                byte[] ch= GetBytes(s.Split(':')[0]);
                int charC=0;
                for (int counter = 0; counter < ch.Length-1; counter += 2)
                    charC = ch[counter] + ch[counter + 1] * 256;
                colorsChar[charC] = int.Parse(s.Split(':')[1], System.Globalization.NumberStyles.HexNumber);
            }
        }
        catch (System.IO.IOException e) { MessageBox.Show("Ошибка загрузки базы:"+e.Message); }
    }
    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        int sqrt=Convert.ToInt32(Math.Sqrt(textBox1.Text.Length))+1;
        Bitmap newB = new Bitmap(sqrt,sqrt);
        convertToBitmap(newB, sqrt);
        pictureBox1.Image = newB;
    }
    void convertToBitmap(Bitmap bmp, int sqrt)
    {
        Rectangle rect = new Rectangle(0, 0, sqrt, sqrt);
        BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);
        IntPtr ptr = bmpData.Scan0;
        int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
        byte[] rgbValues = new byte[bytes];
        Marshal.Copy(ptr, rgbValues, 0, bytes);
        byte[] arrText = GetBytes(textBox1.Text);//2 байта на букву взяли текст
        for (int counter = 0; counter < arrText.Length-1; counter += 2)
        {
            int z = arrText[counter] + arrText[counter + 1] * 256;
            byte[] ColorBytes = BitConverter.GetBytes(colorsChar[z]);
            rgbValues[counter / 2 * 4] = ColorBytes[0];
            rgbValues[counter / 2 * 4 + 1] = ColorBytes[1];
            rgbValues[counter / 2 * 4 + 2] = ColorBytes[2];
            rgbValues[counter / 2 * 4 + 3] = ColorBytes[3];
        }
        Marshal.Copy(rgbValues, 0, ptr, bytes);
        bmp.UnlockBits(bmpData);
    }
    void readFromBitmap(Bitmap bmp)
    {
        Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
        BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);
        IntPtr ptr = bmpData.Scan0;
        int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
        byte[] rgbValues = new byte[bytes];
        String text = "";
        Marshal.Copy(ptr, rgbValues, 0, bytes);
        for (int counter = 0; counter < rgbValues.Length; counter += 4)
        {
            int ColorBase = rgbValues[counter] + rgbValues[counter + 1] * 256 + rgbValues[counter + 2] * 65536 + rgbValues[counter + 3] * 16777216;
            string hexValue = ColorBase.ToString("X");
            string[] ms = System.IO.File.ReadAllLines("colorBD.txt");
            foreach (string s in ms)
                if (s.Split(':')[1].Equals(hexValue))
                    text += s.Split(':')[0];
        }
        MessageBox.Show(text);
        Marshal.Copy(rgbValues, 0, ptr, bytes);
        bmp.UnlockBits(bmpData);
    }

    static byte[] GetBytes(string str)
    {
        byte[] bytes = new byte[str.Length * sizeof(char)];
        System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
        return bytes;
    }
    private void pictureBox1_Click(object sender, EventArgs e)
    {
        readFromBitmap((Bitmap)pictureBox1.Image);
    }

Иллюстрация кода 1

Иллюстрация кода 2 с базой

READ ALSO
Знаки сравнения из string

Знаки сравнения из string

Всем приветИнтересна такая вещь,можно ли получить знаки сравнения (> < = >= <=) из string и потом использовать их?

508
Как узнать, является ли список или массив пустым

Как узнать, является ли список или массив пустым

Каким образом можно узнать, что в списке или массиве не содержится ни одного элемента?

384
Вызвать свойства окна [требует правки]

Вызвать свойства окна [требует правки]

Нужно вызвать свойства из своего приложения (путем нажатия кнопки) окна cmd с использованием c# или winapi по примеру скриншота, вся информации...

351
Как правильно реализовать работу окон?

Как правильно реализовать работу окон?

Первое окно запускается

376