Большой Воронежский Форум

Если это ваш первый визит, рекомендуем почитать справку по форуму. Для размещения своих сообщений необходимо зарегистрироваться. Для просмотра сообщений выберите раздел.
Вернуться   Большой Воронежский Форум » Компьютеры и все, что с ними связано » » Программирование
Философия, технологии, алгоритмы!

Ответ
 
Опции темы
Старый 14.04.2015, 22:15   #1   
Форумец
 
Сообщений: 6,692
Регистрация: 26.04.2006
Возраст: 44

Eвгений вне форума Не в сети
Как быстро скопировать из массива в Image->Canvas->Pixels ??

Есть двумерный массив unisigned char.
И есть Image1.
Зарисовать попиксельно - это понятно, но боюсь что скорость будет мала, к тому же я получаю картинку по USB, процесс непрерывный.

В свое время я заменил попиксельное копирование на CopyRect из соображений быстродействия, но это касалось копирования из одной области в другую.
А как мне максимально быстро скопировать из двумерного массива char в canvas ?

Ну что-то типа
unsigned char m[640][480];
memcpy(Image1->Canvas->Pixels,m,sizeof(m));


Быстродействие очень важно, хотелось бы на все (307 000 байт) тратить не более 0.3 сек.
  Ответить с цитированием
Старый 14.04.2015, 22:39   #2   
Форумец
 
Аватар для Spectator
 
Сообщений: 39,863
Регистрация: 27.05.2003
Возраст: 46

Spectator вне форума Не в сети
https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx
https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx
https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx

HDC = Canvas->Handle

SetDIBits => переведет из массива в Bitmap, Bitmap уже в канве отобразить не проблема.
  Ответить с цитированием
Старый 15.04.2015, 09:35   #3   
Форумец
 
Сообщений: 6,692
Регистрация: 26.04.2006
Возраст: 44

Eвгений вне форума Не в сети
Spectator, Сделал немножко не так, мне показалось, что StretchDIBits больше подходит.

Вот кусок кода - который принимает данные и выводит их попиксельно - это работает.
Цитата:
unsigned char DataIn[307200];
unsigned char* pDataIn; //буфер
BITMAPINFO bmp;
........................
pDataIn=DataIn;

void __fastcall TForm1::VaComm1RxBuf(TObject *Sender, PVaData Data, int Count)
{
unsigned int i;
HDC hDC;
VaBuffer1->Peek(DataIn+Total,Count);
VaBuffer1->Clear();
Total+=Count;

if (Total==307200) // когда получили весь кадр
{
Memo1->Lines->Add(IntToStr(Count) + ", " + IntToStr((__int64)Total));
Form1->Image1->Canvas->Brush->Color=clWhite;
Form1->Image1->Canvas->FillRect(Form1->Image1->ClientRect); // Очищаем канву
for (i=0; i < Total; i++) // заполняем попиксельно
{

if (CurrentX>=640)
{
CurrentX=0;
CurrentY++;
}

Image1->Canvas->Pixels[CurrentX++][CurrentY]=DataIn[i];
}


}

}
А если заменить попиксельный цикл на
Цитата:
hDC=Image1->Canvas->Handle;
StretchDIBits(hDC,1,1,640,480,0,0,640,480, DataIn, &bmp, DIB_RGB_COLORS, SRCCOPY);
картинка белая.

Что я делаю не так? Мне в частности непонятно, какую роль играет здесь BITMAPINFO bmp;
  Ответить с цитированием
Старый 15.04.2015, 10:45   #4   
Форумец
 
Аватар для Spectator
 
Сообщений: 39,863
Регистрация: 27.05.2003
Возраст: 46

Spectator вне форума Не в сети
Цитата:
Сообщение от Eвгений Посмотреть сообщение
Что я делаю не так? Мне в частности непонятно, какую роль играет здесь BITMAPINFO bmp;
скорее всего не заполняешь как раз BITMAPINFO, которую нужно заполнить для того чтобы функция знала, в каком формате хранятся данные изображения.

http://stackoverflow.com/questions/3...xels-using-x-y

при правильном заполнении ты получишь тот же результат, что и попиксельное чтение, но работать будет наверняка намного быстрее.
  Ответить с цитированием
Старый 15.04.2015, 11:39   #5   
Форумец
 
Сообщений: 6,692
Регистрация: 26.04.2006
Возраст: 44

Eвгений вне форума Не в сети
Spectator,
Я почитаю, но прежде хочу возмутиться - неужели нет функции, которая может заполнить BITMAPINFO взяв за основу существующую картинку?
Ну что-то типа
BITMAPINFO = GetBITMAPINFO_FROM_IMAGE(Image1->Canvas) ?
  Ответить с цитированием
Старый 15.04.2015, 11:55   #6   
Форумец
 
Аватар для Spectator
 
Сообщений: 39,863
Регистрация: 27.05.2003
Возраст: 46

Spectator вне форума Не в сети
Цитата:
Сообщение от Eвгений Посмотреть сообщение
Spectator,
Я почитаю, но прежде хочу возмутиться - неужели нет функции, которая может заполнить BITMAPINFO взяв за основу существующую картинку?
Ну что-то типа
BITMAPINFO = GetBITMAPINFO_FROM_IMAGE(Image1->Canvas) ?
почему, есть
GetObject
http://stackoverflow.com/questions/2...-load-a-bitmap
  Ответить с цитированием
Старый 15.04.2015, 18:13   #7   
Форумец
 
Сообщений: 6,692
Регистрация: 26.04.2006
Возраст: 44

Eвгений вне форума Не в сети
Почти получилось вот так
Цитата:
WLabel->Caption->Text="Кадр получен";

Memo1->Lines->Add(IntToStr(Count) + ", " + IntToStr((__int64)Total));

Form1->Image1->Canvas->Brush->Color=clWhite;
Form1->Image1->Canvas->FillRect(Form1->Image1->ClientRect);



Image1->Picture->Bitmap->PixelFormat=pf16bit; // подготавливаем Image1 к тому, что будет грузиться 8 битная информация.




memset(&bitmap_info, 0, sizeof(bitmap_info));
bitmap_info.bmiHeader.biSize = sizeof(bitmap_info.bmiHeader);
bitmap_info.bmiHeader.biWidth = 640;
bitmap_info.bmiHeader.biHeight = 480;
bitmap_info.bmiHeader.biPlanes = 1;
bitmap_info.bmiHeader.biBitCount = 16;//bits per pixel
bitmap_info.bmiHeader.biCompression = DIB_RGB_COLORS;

SetDIBits(Image1->Canvas->Handle,Form1->Image1->Picture->Bitmap->Handle,0,Image1->Height,&DataIn,&bitmap_info,DIB_RGB_COLORS);
Быстродействие - мгновенное появление картинки....Так что уж помогите добить этот код...
Но вот только какие-то проблемы с цветами..... Если скажем не заполнять картинку белым цветом перед перерисовкой - то цвета из буфера будут другими...
Ладно, прикручу камеру, получу нативную картинку, тогда буду копать..

Последний раз редактировалось Eвгений; 27.04.2015 в 19:16.
  Ответить с цитированием
Старый 27.04.2015, 19:15   #8   
Форумец
 
Сообщений: 6,692
Регистрация: 26.04.2006
Возраст: 44

Eвгений вне форума Не в сети
Все-таки что-то не так.
Картинка отображается так, как будто она имеет формат RGB555. А у меня RGB565
Как я это понял?
Вот сайт http://rawpixels.net/
Выкладываю бинарник (дамп памяти). Если в настройках на сайте выставить RGB565 (исходный формат) то получится нормальная картинка, черно белая. А если поставить RGB555 - то получится то, что у меня в программе.
В свойствах Image1 я не нашел ничего подходящего.
Как настроить правильный вывод картинки?
Вложения
Тип файла: rar 4.rar (36.2 Кб, 0 просмотров)
  Ответить с цитированием
Старый 27.04.2015, 19:25   #9   
Форумец
 
Сообщений: 6,692
Регистрация: 26.04.2006
Возраст: 44

Eвгений вне форума Не в сети
Да действительно...
Настроил источник в режим RGB555, получил в программе правильную картинку. То есть Image1 c дефольтными настройками, функция SetDIBits выводят картинку в формате RGB555.
Как это побороть?
  Ответить с цитированием
Поиск в теме: 



Быстрый переход:

  Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Support by DrIQ & Netwind