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

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

22.01.2017, 20:26. Показов 3287. Ответов 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
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,473
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
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,473
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
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,473
25.01.2017, 18:32
INA007, зачем так?
0
1 / 1 / 0
Регистрация: 11.07.2015
Сообщений: 40
25.01.2017, 18:38  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
зачем так?
Что именно?..)
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,473
25.01.2017, 18:44
INA007, в файл а потом из файла и файлом погоняем
0
1 / 1 / 0
Регистрация: 11.07.2015
Сообщений: 40
25.01.2017, 19:33  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
в файл а потом из файла и файлом погоняем
Ну... Хотел сразу файл записывать, чтоб можно было потом в оффлайне открывать.
Чтоб сырые данные были.
Записывать всё это в файл и отдельным потоком отображать.
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,473
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
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,473
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
Ответ Создать тему
Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru