+2.28
1 читатель, 46 топиков

Распознавание автомобильного номера с изображения на C# (.NET)

Распознавание номера .NETДовелось мне не так давно помогать с запуском одного проекта под .NET на WCF — под x64 систему, проект нормально работал на x86 но отказывался работать на x64. В целом как я и ожидал проблема решалась довольно просто, помимо основной проблемы всплыло ещё несколько, в процессе решения которых пришлось познакомиться с очень интересной библиотекой Emgu CV, которая позволяет делать множество замечательных вещей, среди которых распознавание номера на изображении.

Благодаря этой библиотеке можно очень легко и просто внедрить распознавание номера в свою программу. Вот я и решил поделиться новым знанием, вдруг кому-то захочется что-то эдакое реализовать. Например мне сразу пришла в голову идея автоматически открывающегося шлагбаума, без всяких брелков. :) Качество распознавания, скажем — так себе, хотя возможно я просто не достаточно разобрался в возможностях, и всё делал как по умолчанию в примерах, но тем не менее поиграться стоит — вещь интересная.

В принципе, в комплекте с библиотекой есть целый набор примеров, в том числе и пример с распознаванием автомобильного номера. Но в этой публикации я приведу свой пример.

Итак, приступим…

Читать дальше →

Пример POST запроса через WebRequest

Пример POST запроса к сервису с использованием WebRequest на C#:

using System;
using System.Net;
using System.IO;

namespace Tester
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("RUN Tests for Service:");

            //Выполняем тестовый POST запрос к службе.               
            SendTestPostRequest(@"URL - сервиса", "Текст запроса");

            Console.WriteLine("Press any key for exit...");
            Console.ReadKey();
        }

        //Метод выполяющий запрос по указанному адресу и получающий ответ.
        static void SendTestPostRequest(string url, string data)
        {
            try
            {
                WebRequest request = WebRequest.Create(url);
                request.Method = "POST";
                string postData = data;
                request.ContentType = "application/x-www-form-urlencoded";
                System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
                byte[] postByteArray = encoding.GetBytes(postData);
                request.ContentLength = postByteArray.Length;

                System.IO.Stream postStream = request.GetRequestStream();
                postStream.Write(postByteArray, 0, postByteArray.Length);
                postStream.Close();
                HttpWebResponse response = (HttpWebResponse) request.GetResponse();
                Console.WriteLine("Response Status Description: " + response.StatusDescription);
                Stream dataSteam = response.GetResponseStream();
                StreamReader reader = new StreamReader(dataSteam);
                string responseFromServer = reader.ReadToEnd();
                Console.WriteLine("Response: " + responseFromServer);
                reader.Close();
                dataSteam.Close();
                response.Close();
            }
            catch(Exception ex)
            {
                //Если что-то пошло не так, выводим ошибочку о том, что же пошло не так.
                Console.WriteLine("ERROR: "+ex.Message);
            }
        }

    }
}

Позднее связывание, на примере взаимодействия с терминалом сбора данных Cipher 8001L

В данной публикации я продемонстрирую взаимодействие с COM объектом на языке C#. В примере будет использована OLE-компонента для взаимодействия с ТСД Cipher 8001L компании CitySoft. Думаю, всё то что описано можно использовать и для других COM-Объектов.

Для начала поясню в чём суть позднего связывания, и зачем это надо. Позднее связывание необходимо нам тогда, когда тип объекта заранее не известен и мы не можем напрямую обращаться к параметрам, методам и свойствам используемого объекта — вот для этого и используется позднее связывание.

Для вызова метода надо знать его название и список формальных параметров, которые он принимает. Для вызова используем метод InvokeMember().

Читать дальше →

Немножко о PictureBox и памяти.

Наткнулся на одно явление, решил описать себе на память и для общественности, может кому-то окажется полезным.

Всем известно что память надо чистить, и чем методичнее это делаешь тем лучше. И вот на днях Эксепшн по памяти вылез там, откуда я его не ожидал.

Итак задача: делаем приложение в котором есть PictureBox и ImageList, приложение «мониторит» определённые параметры и в зависимости от того чего «намониторило» меняет изображение в PictureBox на одно из коллекции ImageList.

Казалось бы, чего проще…
pictureBox1.Image = imageList1.Images[номер_картинки];

Но не тут то было, оказывается если сделать так определённое количество раз (довольно большое количество, но думаю зависит от размера изображений), то спустя некоторое время получим Ошибку по памяти. Судя по всему при таком способе память от предыдущего изображения остаётся занятой, при этом добавляется блок памяти под новое. Вообщем помогает это исправить Dispose().

Чтобы всё было хорошо, сколько бы изображение не менялось, делать надо так:
pictureBox1.Image.Dispose();
pictureBox1.Image = imageList1.Images[номер_картинки];

При таком варианте ошибок не возникает.

Вот-так. Век живи — век учись.

Динамический вывод картинок в отчётах Crystal Report на C#.

В данной публикации я расскажу каким образом в отчёт Crystal Report можно вывести требуемое количество изображений (например из базы данных).

!!! Для того чтобы публикация была понятна, рекомендуется к обязательному прочтению предыдущая статья Используем Crystal Report в C#.

Собственно, перепробовав много методов (в основном описанных на зарубежных сайтах — в Ру-нете как то не особо изучен этот вопрос), нашёл действительно работоспособный и эффективный метод вывода изображений в отчёт Crystal Report, который заключается в передаче изображений в отчёт через источник данных.

Для того чтобы передать таким способом изображения мы просто создаём DataTable, в котором одному из столбцов (можно и нескольким) задаём тип данных массив байт — «System.Byte[]». Далее просто добавляем в ячейки этого поля изображения преобразовав их в массив Byte[].

Читать дальше →

Свой сервер и клиент к нему при помощи TcpListener и TcpClient

Не так давно, наткнулся на одну статейку на Хабре, по поводу TcpListener — там с его помощью делался Web-сервер. Поскольку есть некоторые задачи требующие создания подобного приложения, было решено изучить вопрос и попробовать воссоздать увиденное. Переписал что было в публикации в приложение (всегда так делаю прежде чем скачать исходник — лучше для понимания) запустил, не работает. Точнее работает но через раз — как то кривенько и для реально рабочего приложения не годится. Скачал исходники — тоже самое, работает но через раз. Здесь работает через раз — означает что клиент то цеплялся то не цеплялся к серверу. Решил изучить вопрос с ноля. Накопал некоторый материал в интернете, всё это переработал — получилось тестовое рабочее приложение.

Начну с того, что я хотел сделать: пример состоит из двух приложений — сервера и клиента. (Мне Web-сервер не особо интересен, хотя пример можно достаточно просто переделать в него.)

Сервер — принимает данные от клиента (текст), преобразует строку полученную от клиента к заглавным буквам и отправляет обратно клиенту.

Клиент — отправляет n-ное количество раз заданную строку клиенту (сделано чтобы поназапускав несколько клиентов, в том числе с разных машин, посмотреть как будет себя вести сервер) прибавляя порядковый номерок к посланному тексту и получает такое же количество раз ответ от сервера с текстом заглавными буквами.

Дополнительно — вначале пример был без использования ThreadPool, но потом решил добавить, так сервер должен работать стабильнее (по моему мнению) и обрабатывать большее количество одновременных запросов.

Поскольку код я прокомментировал довольно хорошо, то привожу как есть, без дополнительного описания.
Читать дальше →

Один contextMenuStrip для разных форм

Вариант размещения одного contextMenuStrip на разных формах для разных элементов.

В основном пространстве имен добавляем класс с contextMenuStrip:
namespace TestContextMenu
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }

    }
    static class Menushki
    {
        public static ContextMenuStrip menu1 = new ContextMenuStrip();
       
        
    }
}
В нашем случае это класс Menushki
Читать дальше →

Динамическое создание элементов отображения и вывод в них информации из базы данных

Здесь я приведу пример динамического создания текстовых полей TextBox, с выводом в эти поля значений из источника данных.

Сразу к делу:

1. Задаем некоторые переменные и пару массивов.
DataSet ds = new DataSet(); //Создаем источник данных.
TextBox[] tb = new TextBox[100];//Массив из 100 текстбоксов, можно и списком воспользоваться, но пусть будет так.
Label[] lb = new Label[100]; //Массив подписей к полям.
int row_num = 0; //Номер выбранной записи в таблице.


Читать дальше →

Многострочный ListView для .NET CF (описание, исходный код и пример работы).

Здесь я приведу описание основных свойств и методов компонента GraphListView.

Самое главное, как указать источник данных:
//1. Бросаем на форму GraphListView
//связываем компонент с данными и обновляем его.
graphListView1.GraphListDataSet = new DataSet();
string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + "\\dataset.xml";
//В данном случае источник данных загрузили из XML файла.
graphListView1.GraphListDataSet.ReadXml(path);

//Указываем наименование таблицы в источнике данных
graphListView1.DataTableName = "Table";
//Указываем наименование поля таблицы в котором передается значение
graphListView1.FieldValue = "ID_DOCHEAD";
//Указываем наименование поля таблицы в котором передается отображаемое наименование
graphListView1.FieldDisplay = "NAME";

//Количество строк в позиции, можно не указывать по умолчанию 2;
//Может принимать значение от 1 до 10;
graphListView1.RowCountByPos = 2;
//Цвет текста, можно не указывать по умолчанию Белый;
graphListView1.FontColor = Color.Red;

//Обязательная функция после применения всех обязательных параметров выше.
//Заполнит и отобразит Список.
graphListView1.RefreshList();

Читать дальше →