Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
1 / 1 / 0
Регистрация: 11.07.2015
Сообщений: 40

Отображение изображения из потока

22.01.2017, 20:26. Показов 3213. Ответов 64
Метки нет (Все метки)

Приветствую всех!

Может быть кто сталкивался с таким моментом: извне идёт поток (по USB, к примеру), этот поток обрабатывается и выводится изображение на форму или Image, PaintBox...
Проблема вот в чём - изначально неизвестно какой длины будут данные и, естественно не известно какой "длины" будет изображение.
Как в этом случае сделать так, чтобы генерируемое изображение, уходя за нижнюю границу контейнера начинало смещаться вверх? Как бы прокручивалось до окончания приема данных...
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.01.2017, 20:26
Ответы с готовыми решениями:

Создание потока,отображение на прогресс баре
как создать поток,задать ему определенный приоритет и отобразить процесс выполнения в прогресс баре? Прошу,помогите

Передача изображения в виде потока
Подскажите пожалуйста. Моя страница обрабатывает изображение и полученное изображение должно передаватся ответом в виде потока и может...

Отображение RTSP потока видео на iOS устройствах
Доброго времени суток. Мне требуется отобразить на экране телефона видео, которое вещается из интернета по RTSP протоколу. Стандартными...

64
Модератор
 Аватар для vxg
3409 / 2181 / 354
Регистрация: 13.01.2012
Сообщений: 8,468
25.01.2017, 06:14
gumi250, где именно тут ошибка? Картинка монотонно растёт. Генератор как я понял делает несколько градиентов
0
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
25.01.2017, 07:09
vxg, конечно я не знаю, что дает генератор. Но меня смущает две вещи: 1-пилооборазный профиль вдоль оси х; 2 - пол картинки выглядят полосами, а вторая половина просто белая.
0
Модератор
 Аватар для vxg
3409 / 2181 / 354
Регистрация: 13.01.2012
Сообщений: 8,468
25.01.2017, 07:59
gumi250, ну я подумал что полосы - это генератор, а белые "уши" - это потому что поток как сказал автор пока идёт не весь (ширину наверное очень хотелось выставить в 1024, а генератор наверное столько данных не потянул). Алхимия)
0
1 / 1 / 0
Регистрация: 11.07.2015
Сообщений: 40
25.01.2017, 10:51  [ТС]
День добрый!
Я поясню, почему всё отображается сейчас так.
Для получения всего спектра оттенков серого нужно заполнить число от 0b00000000 до 0b00111111 с шагом 1.
Для теста мне это не нужно, поэтому генератор создаёт эту градацию с шагом 4. Вот поэтому на картинке при большом увеличении видно переходы.
И генератор не выдаёт сейчас всю ширину картинки - только часть, поэтому справа белое поле...)
0
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
25.01.2017, 12:02
Меня смущает не число цветов, а пила. INA007, вы уверены, что в ширине должно быть 10 периодов пилы, а скажем не 1 период? И разве вторая половина картинки не должна быть черной, а не белой?
Да и ваш алгоритм перевода данных в цвет мне кажется странным.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
      while(i < (BUFSIZE/2)-1){
          data10b = bufrd[i]<<8;
          i++;
          data10b += bufrd[i];
          i++;
            Form1->Image1->Canvas->Pen->Color = RGB(data10b%256, data10b%256, data10b%256);
            Form1->Image1->Canvas->MoveTo(x,y);
            Form1->Image1->Canvas->LineTo(x1,y1);
 
            x=x1;
            y=y1;
            x1++;
      }
0
1 / 1 / 0
Регистрация: 11.07.2015
Сообщений: 40
25.01.2017, 15:50  [ТС]
Это всё пока что только для теста...)

У меня тут на следующем этапе другая проблема вылезла: нужно писать данные с USB, который работает как виртуальный COM порт в бинарный файл и из файла тут же читать данные и преобразовывать в картинку.
Я создаю бинарный файл:
C++
1
2
3
4
ReadFile(COMport, bufrd, btr, &temp, &overlapped);
       binFile = fopen("test.hrp", "ab+");
       fwrite(&bufrd, sizeof(char), btr, binFile);
       Synchronize(Printing);
btr - это количество байт, которые пишутся в файл.
Этот код работает в отдельном потоке.
На этом этапе всё хорошо.
В функции "Printing":

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
while(i<1024){
          //fsetpos(binFile, &charcnt);
          charcnt = fread(&temp, sizeof(char), 1, binFile);
          data10b = temp<<8;
          charcnt = fread(&temp, sizeof(char), 1, binFile);
          data10b += temp;
          i++;
            Form1->Image1->Canvas->Pen->Color = RGB(data10b, data10b, data10b);
            Form1->Image1->Canvas->MoveTo(x,y);
            Form1->Image1->Canvas->LineTo(x1,y1);
 
            x=x1;
            y=y1;
            x1++;
      }
      fclose(binFile);
И всё...(
Выводится чёрное поле..
Причём, если сначала записать в файл, а потом читать, то картинка идёт правильно.
0
Модератор
 Аватар для vxg
3409 / 2181 / 354
Регистрация: 13.01.2012
Сообщений: 8,468
25.01.2017, 18:32
INA007, зачем так?
0
1 / 1 / 0
Регистрация: 11.07.2015
Сообщений: 40
25.01.2017, 18:38  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
зачем так?
Что именно?..)
0
Модератор
 Аватар для vxg
3409 / 2181 / 354
Регистрация: 13.01.2012
Сообщений: 8,468
25.01.2017, 18:44
INA007, в файл а потом из файла и файлом погоняем
0
1 / 1 / 0
Регистрация: 11.07.2015
Сообщений: 40
25.01.2017, 19:33  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
в файл а потом из файла и файлом погоняем
Ну... Хотел сразу файл записывать, чтоб можно было потом в оффлайне открывать.
Чтоб сырые данные были.
Записывать всё это в файл и отдельным потоком отображать.
0
Модератор
 Аватар для vxg
3409 / 2181 / 354
Регистрация: 13.01.2012
Сообщений: 8,468
25.01.2017, 21:00
INA007, записывать можно, но зачем из него брать в онлайне?
0
1 / 1 / 0
Регистрация: 11.07.2015
Сообщений: 40
25.01.2017, 21:49  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
записывать можно, но зачем из него брать в онлайне?
Ну, чтобы видеть картинку именно во время пролёта спутника... как бы в реальном времени.

Добавлено через 7 минут
Этот момент я уже решил.
Файл пишется и читается одновременно.
Вернее, последовательно - сначала пишется какая-то часть, потом начинает считываться.

Тут ещё, понимаете в чём дело...
Фреймы со спутника идут строками. В начале каждого фрейма идёт некая последовательность, типа синхронизации.
Вообще, всё это передаётся в манчестере. Аппаратная часть позаботится о синхронизации самого потока, а вот синхронизировать строки, я подумал, что будет проще, если после записи в бинарный файл находить эту синхропоследовательность и рисовать строку, начиная с неё.

Вот тут расписан формат этого потока: https://www.ncdc.noaa.gov/oa/p... sec4-1.htm

Добавлено через 2 минуты
Ведь спутник передаёт непрерывно картинку.
И в какой момент он появится в зоне видимости и в какой момент его передачи аппаратная часть засинхрится и начнётся запись в файл просто неизвестно.
0
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
25.01.2017, 23:53
Цитата Сообщение от INA007 Посмотреть сообщение
Этот момент я уже решил. Файл пишется и читается одновременно.
Да не нужно из файла ничего читать. Вы получили данные из USB в оперативную память, записали их на жесткий диск. Данные в оперативной памяти остались, зачем их жесткого снова в оперативку читать?

Я так понял проблема в том что данные могут начать поступать с середины строки. Просто начав получать данные ждите момент начала строки и начинайте писать.
1
1 / 1 / 0
Регистрация: 11.07.2015
Сообщений: 40
27.01.2017, 00:48  [ТС]
Цитата Сообщение от gumi250 Посмотреть сообщение
Просто начав получать данные ждите момент начала строки и начинайте писать.
Ну, там не так всё просто.
Спутник передаёт не только картинку - там куча служебной информации.
Поэтому я и пытаюсь разделить задачу между компом и микроконтроллером.
Вот тут полное описание протокола HRPT: https://www.ncdc.noaa.gov/oa/p... sec4-1.htm
0
1 / 1 / 0
Регистрация: 11.07.2015
Сообщений: 40
29.01.2017, 11:25  [ТС]
Добрый день!
В общем, всё было бы хорошо, ка бы не одна фича...)
Почему-то при прорисовке картинки приём данных и сама прорисовка может просто остановиться, если щёлкнуть по окну программы мышкой или попытаться сдвинуть окно...
Сам софт при этом не виснет...
0
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
29.01.2017, 11:39
на 99% это связано не с кодом прорисовки, а с кодом получения данных.
0
Модератор
 Аватар для vxg
3409 / 2181 / 354
Регистрация: 13.01.2012
Сообщений: 8,468
29.01.2017, 11:42
INA007, вариант - код получения данных скорее всего в потоке интерфейса, например в таймере, когда вы тащите форму его блокирует
0
1 / 1 / 0
Регистрация: 11.07.2015
Сообщений: 40
29.01.2017, 12:38  [ТС]
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
void __fastcall ReadThread::Execute()  //главная функция потока, реализует приём байтов из COM-порта
{
    //---- Place thread code here ----
    FreeOnTerminate = true; // освободить занятую потоком память по окончании его работы
 
    OVERLAPPED overlapped;
    COMSTAT comstat;        
    DWORD btr;
    DWORD temp, temp3, mask, signal;    
 
    memset(bufrd, 0, BUFSIZE);
 
    overlapped.hEvent = CreateEvent(NULL, true, true, NULL);
    SetCommMask(COMport, EV_RXCHAR);                       // установить маску на срабатывание по событию приёма байта в порт
 
 binFileWR = fopen("test.hrp", "ab+");
 
 while(!Terminated)                    //пока поток не будет прерван, выполняем цикл
   {
 
     overlapped.hEvent = CreateEvent(NULL, true, true, NULL);
     SetCommMask(COMport, EV_RXCHAR);
     WaitCommEvent(COMport, &mask, &overlapped);                // ожидать события приёма байта
                                                                // (это и есть перекрываемая операция)
     signal = WaitForSingleObject(overlapped.hEvent, INFINITE); //приостановить поток до прихода байта
    if(signal == WAIT_OBJECT_0)                     //если событие прихода байта произошло
        {
 
            if(GetOverlappedResult(COMport, &overlapped, &temp, true)) // проверяем, успешно ли завершилась
                {                                                           // перекрываемая операция WaitCommEvent
                     if((mask & EV_RXCHAR)!=0)                                  //если произошло именно событие прихода байта
                       {
                             ClearCommError(COMport, &temp, &comstat);              //нужно заполнить структуру COMSTAT
                             btr = comstat.cbInQue;                                 //и получить из неё количество принятых байтов
 
                           if(btr)                                              //если действительно есть байты для чтения
                             {
                                ReadFile(COMport, bufrd, btr, &temp, &overlapped);     //прочитать байты из порта в буфер программы
 
                                fwrite(bufrd, sizeof(char), btr, binFileWR);
                                fgetpos(binFileWR, &poswr);
                                counter += btr;
                                Form1->StatusBar1->Panels->Items[2]->Text = "Received " + IntToStr((int)counter/1024) + " kBytes!";
                     
                               Synchronize(Print); //вызываем функцию для вывода данных на экран 
                            }
                        }
                 }
        }
    }
 fclose(binFileWR);
 CloseHandle(overlapped.hEvent);        //перед выходом из потока закрыть объект-событие
}
Вот это код самого потока, который получает данные с виртуального COM порта.
Если закомментировать Synchronize(Print);, то данные идут и пишутся в файл отлично и без сбоев.

Получение данных - в отдельном потоке.
0
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
29.01.2017, 15:26
использовать vcl не в основном потоке нельзя, т.е. строки
C++
1
Form1->StatusBar1->Panels->Items[2]->Text = "Received " + IntToStr((int)counter/1024) + " kBytes!";
тут быть не должно.
Функция Print вызываемая в Synchronize делается в основном потоке, поэтому и приостанавливается.
0
1 / 1 / 0
Регистрация: 11.07.2015
Сообщений: 40
29.01.2017, 15:55  [ТС]
Цитата Сообщение от gumi250 Посмотреть сообщение
тут быть не должно.
Да. эту строку можно вообще убрать - она просто для индикации. )
Цитата Сообщение от gumi250 Посмотреть сообщение
Функция Print вызываемая в Synchronize делается в основном потоке, поэтому и приостанавливается.
А как её правильно сделать?
Функция Print принадлежит ReadThread - это, я так подумал, отдельный ведь поток?
Или я что-то напутал?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
29.01.2017, 15:55

Отображение изображения
Как отобразить Png рисунок средствами direct3d(не directDraw).

Отображение изображения
У меня есть изображение размерность 100 на 50 пикселей. В форме создаю label, в свойствах &quot;image&quot; выбираю свое изображение, задаю...

Отображение изображения
Почему изображение не становится по правому краю? &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;Maksimov&lt;/title&gt; &lt;meta...

Отображение изображения
Всем привет. Как добавить загруженное изображение в приложение? if (openFileDialog1.ShowDialog() ==...

Отображение изображения
Доброго времени суток. Есть форма с загрузкой изображения, как сделать что бы фото которое человек хочет загрузить сразу отображалось на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
23. что сделано за последнее время.
anaschu 17.06.2026
• Эталон: Клиника НИИ питания РАМН, Москва — централизованный пищеблок, 225 коек, 180 пациентов • Git: репозиторий med2, ветка абсентеизм. Рабочий файл: СРесурсами1_v4. alp • Смежный проект:. . .
22. Подключение слоя системной динамики (потоковые диффуры): экономические метрики модели
anaschu 17.06.2026
Апдейт модели: финансовый контур, разделение затрат Продолжаю развивать модель рабочего коллектива на AnyLogic. В этот раз работа шла над агентом Экономика — финансовым SD-слоем модели. Задача:. . .
[golang] Insert Delete GetRandom O(1) (Leetcode: 380)
alhaos 16.06.2026
Insert Delete GetRandom O(1) Сложность: Medium Источник: LeetCode 380 Задача Реализовать структуру данных RandomizedSet, которая поддерживает следующие операции за O(1) в среднем:
Свет в конце тоннеля
kumehtar 16.06.2026
Поймал себя на одной мысли. Раньше мне всегда казалось неправильным жить без чёткого понимания, куда всё идёт. Будто я иду по дороге судьбы, но не знаю, куда она ведёт. А раз не знаю — значит,. . .
[golang] Реализация стека с поддержкой получения минимального элемента за O(1)
alhaos 16.06.2026
Min Stack Сложность: Medium Источник: LeetCode 155 Задача: Реализовать стек который поддерживает push, pop, top и получение минимального элемента за O(1). Методы:
[golang] Конкурентный fetcher с ограничением максимального количества одновременных HTTP запросов.
alhaos 10.06.2026
Задача Реализовать конкурентный fetcher с ограничением максимального количества одновременных HTTP запросов. Сигнатура func Fetch(urls string, maxConcurrent int) Result Пример urls :=. . .
[golang] Состояние гонки (race condition)
alhaos 10.06.2026
Состояние гонки (race condition) Состояние гонки (Race Condition) — это ошибка, возникающая при одновременном доступе нескольких горутин к одним и тем же данным без должной синхронизации. При этом. . .
Взрослые отношения, и почему они не получаются
kumehtar 09.06.2026
Когда в детстве ребёнок не получает от родителей чего-то важного, он лишается не просто приятных переживаний, а основы для формирования определённых внутренних качеств и навыков. Если ребёнок не. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru