Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как быстро скопировать из двумерного массива char, в канву Image? 
:(
    Опции темы
=Женек=
Дата 14.4.2015, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: 1
Всего: 1



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

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

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


Быстродействие очень важно, хотелось бы на все (307 000 байт) тратить не более 0.3 сек. 

Это сообщение отредактировал(а) =Женек= - 14.4.2015, 22:20
PM MAIL   Вверх
SVN74
Дата 14.4.2015, 23:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 5.5.2008
Где: Комсомольск на Дн епре

Репутация: 11
Всего: 18



Код

char* DataIn; - буфер
BITMAPINFO bmp; -  информация о картинке
StretchDIBits(hDC,1,1,rect.right - 2 ,rect.bottom - 1 ,0,0,drawBmp.biWidth,
                    drawBmp.biHeight, DataIn, &bmp, DIB_RGB_COLORS, SRCCOPY);


Это сообщение отредактировал(а) SVN74 - 14.4.2015, 23:19
PM MAIL WWW   Вверх
=Женек=
Дата 15.4.2015, 07:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: 1
Всего: 1



Смотрите, вот так, попиксельно работает
Код

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.4.2015, 09:30
PM MAIL   Вверх
=Женек=
Дата 15.4.2015, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: 1
Всего: 1



Я попробовал ручками заполнить (Image->Canvas у меня меняться никогда не будет) - все равно белый экран.
Вот что в итоге

Цитата
void __fastcall TForm1::VaComm1RxBuf(TObject *Sender, PVaData Data, int Count)
{
  unsigned int i;

  VaBuffer1->Peek(DataIn+Total,Count);
  VaBuffer1->Clear();
  Total+=Count;

  
  if (Total==307200) // Получен полный пакет данных кадра
  {
    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];
   }
  */

// ДАЛЕЕ КОД СТЫРЕННЫЙ НА ПРОСТОРАХ ИНТЕРНЕТА

HBITMAP hBmp=Image1->Picture->Bitmap->Handle;
  BITMAPINFO bmi;


  bmi.bmiHeader.biSize=sizeof(bmi.bmiHeader);
  bmi.bmiHeader.biBitCount=0;

  //этим вызовом заполняем поля bmi
  int ret=GetDIBits(Image1->Canvas->Handle,hBmp,0,Image1->Height,NULL,&bmi,DIB_PAL_COLORS);


  HBITMAP hIm=Image1->Picture->Bitmap->Handle;
  int j = SetDIBits(Image1->Canvas->Handle,hIm,0,Image1->Height,DataIn,&bmi,DIB_PAL_COLORS);
  }

}


ret=GetDIBits - вроде как должно возвратить число сканированных строк. У меня возвращает 1. Где собака порылась?

P.S. Проблема еще вот в чем - картинка поступает 8-битная, то есть 1 байт в буфере - один пиксель...
PM MAIL   Вверх
=Женек=
Дата 15.4.2015, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: 1
Всего: 1



Почти получилось вот так
Цитата

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

  HBITMAP hBmp=Image1->Picture->Bitmap->Handle;
  BITMAPINFO bmi;


  bmi.bmiHeader.biSize=sizeof(bmi.bmiHeader);
  bmi.bmiHeader.biBitCount=0;

  //этим вызовом заполняем поля bmi
  int ret=GetDIBits(Image1->Canvas->Handle,hBmp,0,Image1->Height,NULL,&bmi,DIB_RGB_COLORS);




  HBITMAP hIm=Image1->Picture->Bitmap->Handle;
  int j = SetDIBits(Image1->Canvas->Handle,hIm,0,Image1->Height,&DataIn,&bmi,DIB_RGB_COLORS);


Но есть странность - получается только при первом вызове функции, как буд-то что-то не обнуляется (хотя все переменные локальные).
Вторая странность - я просто вывожу прямоугольник в левой части экрана. Так вот цвет его всегда разный..
Где собака порылась?

P.S. А быстродействие - мгновенное появление картинки....Так что уж помогите добить этот код...
PM MAIL   Вверх
Alexeis
Дата 15.4.2015, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



Если говорить про самую быструю функцию, то среди GDI функций это будет
SetDIBitsToDevice
lpvBits - как раз массив растра. По ней примеров хватает и на форме и в гугле.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0456 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.