Форум программистов Контакты:
О проблемах с регистрацией, почтой и по другим вопросам пишите сюда - post@programmersforum.ru
По необходимости будем регистрировать вручную. И проверяйте папку спам!
Главная  |  Правила форума  |  Исходники Delphi  |  Основы Delphi  |  Блог программистов  |  Рассылка  |  Повторная активизация e-mail  | 

Вернуться   Форум программистов > Delphi программирование > Мультимедиа в Delphi

Ответ
 
Опции темы
Старый 16.09.2010, 19:02   #1
fen1ksss
Пользователь
 
Регистрация: 29.11.2009
Сообщений: 44
Репутация: 10
По умолчанию BMP в массив

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

Код:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

CONST
  PixelCountMax = 32768;

TYPE
  pRGBArray = ^TRGBArray;
  TRGBArray = ARRAY[0..PixelCountMax-1] OF TRGBTriple;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  OriginalBitmap:TBitmap;
  ProcessedBitmap:TBitmap;
  i,j:integer;
  RowOriginal:pRGBArray;
  RowProcessed:pRGBArray;

implementation

{$R *.dfm}

procedure CreateBMP;
begin
if OriginalBitmap.PixelFormat <> pf24bit then
  begin
    ShowMessage('Изображение должно быть 24-х битным');
    Exit;
  end;

for j:=OriginalBitmap.Height-1 downto 0 do
begin
  RowOriginal:=pRGBArray(OriginalBitmap.Scanline[j]);
  RowProcessed:=pRGBArray(ProcessedBitmap.Scanline[j]);

  for i:=OriginalBitmap.Width-1 downto 0 do
  begin
    RowProcessed[i].rgbtRed:=RowOriginal[i].rgbtRed;
    RowProcessed[i].rgbtGreen:=RowOriginal[i].rgbtGreen;
    RowProcessed[i].rgbtBlue:=RowOriginal[i].rgbtBlue;
  end;
end;
Form1.Canvas.Pixels[i,j]:=(RowProcessed[i].rgbtRed shl 16)+
(RowProcessed[i].rgbtGreen shl 8) +
RowProcessed[i].rgbtBlue;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  OriginalBitmap.LoadFromFile('0003.bmp');
  ProcessedBitmap.width:=800;
  ProcessedBitmap.height:=600;
  createbmp;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   OriginalBitmap:=TBitmap.Create;
   ProcessedBitmap:=TBitmap.Create;
end;

По нажатию на кнопку ничего не происходит и выдает
Process is not accessible
Thread Exit: Thread ID: 3852. Process Project1.exe (3536)

вот юнит с BMP - изображением
http://www.megaupload.com/?d=XX55QNQD
fen1ksss вне форума   Ответить с цитированием
Старый 16.09.2010, 19:21   #2
DomiNick
Студент, не
Профессионал
 
Аватар для DomiNick
 
Регистрация: 29.01.2009
Адрес: Россия-Матушка, ул.«Эльфов 80-го уровня», спросить "сáмого Эльфа"...
Сообщений: 2,067
Репутация: 440
По умолчанию

Ну есть же поиск по форуму..... Например воть: http://www.programmersforum.ru/showthread.php?t=110388

И "OriginalBitmap.Free; ProcessedBitmap.Free;" не забываем при Destroy формы... *

З.Ы. Никогда не понимал зачем все делают какое-то [0..PixelCountMax-1]...



P.S. Не проверял, но на вскидку - где например "ProcessedBitmap.PixelFormat:=pf24b it;" ?
__________________
I am the First of Cyber Evolution...
I am the First to Program your Future...

Последний раз редактировалось DomiNick; 16.09.2010 в 19:26. Причина: P.S.
DomiNick вне форума   Ответить с цитированием
Старый 16.09.2010, 20:31   #3
alexprey
Форумчанин
 
Регистрация: 25.05.2010
Сообщений: 169
Репутация: 6
По умолчанию

Слушайте а не проще использовать
TBitmap.Canvas.Pixels ???
alexprey вне форума   Ответить с цитированием
Старый 16.09.2010, 20:48   #4
DomiNick
Студент, не
Профессионал
 
Аватар для DomiNick
 
Регистрация: 29.01.2009
Адрес: Россия-Матушка, ул.«Эльфов 80-го уровня», спросить "сáмого Эльфа"...
Сообщений: 2,067
Репутация: 440
По умолчанию

И ждать результата раз в сорок (если не в 140) дольше?
__________________
I am the First of Cyber Evolution...
I am the First to Program your Future...
DomiNick вне форума   Ответить с цитированием
Старый 16.09.2010, 21:10   #5
Alex Cones
Trust no one.
Профессионал
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Адрес: In the middle of nowhere.
Сообщений: 6,530
Репутация: 1426
По умолчанию

Продолжая мысь о простом хранении - не проще хранить в HBitMap, при необходимости подключаясь к нему и вытягивая инфу о пикселях? Лично у меня такой метод нисколько не тормозит даже на 800 * 600 картинках, при обновлении 40 раз\сек.

P.S. Если запросите, дам весь код своей системы.
__________________
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума   Ответить с цитированием
Старый 16.09.2010, 21:23   #6
fen1ksss
Пользователь
 
Регистрация: 29.11.2009
Сообщений: 44
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alex Cones Посмотреть сообщение
Продолжая мысь о простом хранении - не проще хранить в HBitMap, при необходимости подключаясь к нему и вытягивая инфу о пикселях? Лично у меня такой метод нисколько не тормозит даже на 800 * 600 картинках, при обновлении 40 раз\сек.

P.S. Если запросите, дам весь код своей системы.
Суть программы: есть последовательность кадров и нужно ее засунуть в один кадр, т.е. сделать панорамное изображение.

Есть функция сравнения 2 массивов - 2 кадров, нахожу наименьшее отличие одного от другого и накладываю и так далее.
Для этого как раз и нужен массив, а как загонять изображение в массив это все равно (конечно не canvas.pixels), вот пробовал вариант через scanline, но до конца не получилось, если есть варианты, выложите плиз.
fen1ksss вне форума   Ответить с цитированием
Старый 17.09.2010, 08:22   #7
Прик
Участник клуба
 
Регистрация: 08.09.2010
Сообщений: 863
Репутация: 266
По умолчанию

Цитата:
Сообщение от fen1ksss Посмотреть сообщение
По нажатию на кнопку ничего не происходит...
А ничего и не должно происходить визуально (дальше будет ясно почему).
Процедура банально копирует одно изображение в другое, причем самым "садистстким" методом - по каждому цвету, составляющему пиксел. Но это бы еще ничего, если бы не вывод копии на форму по-пиксельно. Тут и слов нет.
Естественно, по этим причинам появление изображение на форме происходит заметно медленно.
Вот такой код выводит изображение за заметное для глаза время:
Код:

for j := OriginalBitmap.Height-1 downto 0 do begin
  RowOriginal:=pRGBArray(OriginalBitmap.Scanline[j]);
  RowProcessed:=pRGBArray(ProcessedBitmap.Scanline[j]);
  for i:=OriginalBitmap.Width-1 downto 0 do begin
    //Доступ к RGB-цветам отдельных пикселей должен осуществляться следующим образом:
    RowProcessed[i].rgbtRed:=RowOriginal[i].rgbtRed;
    RowProcessed[i].rgbtGreen:=RowOriginal[i].rgbtGreen;
    RowProcessed[i].rgbtBlue:=RowOriginal[i].rgbtBlue;
    Form1.Canvas.Pixels[i,j]:=(RowProcessed[i].rgbtRed shl 16)+
                      (RowProcessed[i].rgbtGreen shl 8) +
           RowProcessed[i].rgbtBlue;
  end;
end;

А вот такой "мгновенно":
Код:

  for j:=OriginalBitmap.Height-1 downto 0 do begin
    RowOriginal:=pRGBArray(OriginalBitmap.Scanline[j]);
    RowProcessed:=pRGBArray(ProcessedBitmap.Scanline[j]);
    for i:=OriginalBitmap.Width-1 downto 0 do
      RowProcessed[i] := RowOriginal[i];
  end;
  Form1.Canvas.Draw(0, 0, ProcessedBitmap);

А "ничего не происходит" от обычной невнимательности - вывод на форму пикселей вынесен за пределы циклов.
Автору темы желательно попрактиковаться в работе с графикой, прежде чем браться за не самую простую, обозначенную им, задачу.

Вопрос.
А упомянутая функция "сравнения 2 массивов - 2 кадров" что принимает в качестве параметров (какой тип/какие типы и сколько) и что возвращает как результат сравнения?

Последний раз редактировалось Прик; 17.09.2010 в 08:54. Причина: Вопрос
Прик вне форума   Ответить с цитированием
Старый 17.09.2010, 10:06   #8
Alex Cones
Trust no one.
Профессионал
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Адрес: In the middle of nowhere.
Сообщений: 6,530
Репутация: 1426
По умолчанию

Для общего развития все таки покажу свой код:

1) Качаем сорсы от FVFL
2) Пишем у себя код:
Код:

 Type
  TTexture = Record
   Bitmap : HBitMap;
   Width  : LongInt;
   Height : LongInt;
  End;

  TBuffer = Record
   DC   : HDC;
   Tex  : TTexture;
  End;

  TWarehouse = Record
   Buffer   : TBuffer;
   <Кадры> : TTexture; <Или лучше array>
  End;

Код:

 Var
  Warehouse : TWarehouse;

Код:

Procedure LoadFromFile(Var T : TTexture; FileName : PChar);
 Var
  F : File;
  Data : Array of Integer;
  CurrentTool : Byte;
 Begin
  SetLength(Data, 5);
  ZeroMemory(@Data[0], Length(Data) * SizeOf(Integer));
  ZeroMemory(@CurrentTool, 1);
  AssignFile(F, FileName);
  Reset(F, 1);
  BlockRead(F, Data[0], SizeOf(Integer));
  BlockRead(F, T.Width, SizeOf(T.Width));
  BlockRead(F, T.Height, SizeOf(T.Height));
  T.Bitmap := CreateCompatibleBitmap(Application.FRMMain.IMGMain.DC, T.Width, T.Height);
  While Not(Eof(F)) Do
   Begin
    BlockRead(F, CurrentTool, 1);
    Case CurrentTool Of
     1 : Begin
         BlockRead(F, Data[0], SizeOf(Integer));
         UNTEffects.AddBlue(T, Data[0]);
        End;
    2 : Begin
         BlockRead(F, Data[0], SizeOf(Integer));
         UNTEffects.AddGreen(T, Data[0]);
        End;
    3 : Begin
         BlockRead(F, Data[0], SizeOf(Integer));
         UNTEffects.AddRed(T, Data[0]);
        End;
    4 : Begin
         UNTEffects.ConvertToBW(T);
        End;
    5 : Begin
         BlockRead(F, Data[0], SizeOf(Integer));
         UNTEffects.Brigthness(T, Data[0]);
        End;
   ... // Остальные эффекты
   End;
   End;
  CloseFile(F);
 End;
// Этот код используйте, если хотите использовать эффекты из FVFL, иначе делайте загрузку из файла:
 Procedure LoadHB(FileName : PChar; Var Tex : TTexture);
 Begin
  Tex.Bitmap := LoadImage(GetModuleHandle(Nil), FileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
  VirtualDraw(Tex);
 End;

Код:

 Procedure CreateDCnHB;
  Begin
   Application.FRMMain.IMGMain.DC := GetDC(Application.FRMMain.IMGMain.Handle);
   Warehouse.Buffer.DC := CreateCompatibleDC(Application.FRMMain.IMGMain.DC);
   Warehouse.Buffer.Tex.Bitmap := CreateCompatibleBitmap(Application.FRMMain.IMGMain.DC, 800, 600);
   VirtualDraw(Warehouse.Buffer.Tex);
   SelectObject(Warehouse.Buffer.DC, Warehouse.Buffer.Tex.Bitmap);
  End;

Здесь у меня Application - не тот application, это следующая запись:
Код:

   TIMG = Record
    Handle     : HWND;
    DC         : HDC;
   End;

   TFRM  =  Record
    Handle      : HWND;
    IMGMain     : TIMG;
   End;

   TApplication = Record
    WinClass               : TWndClass;
    ApplicationHandle      : HWND;          // hInst
    OldHeight              : Integer;
    OldWidth               : Integer;
    (* Message *)  Msg     : TMSG;
    (* Forms   *)  FRMMain : TFRM;
   End;

- Изменяем как хотим, оставляем только переменную DC в любом месте.
Код:

  Procedure VirtualDraw(Var Source : TTexture);
  Var
   Bit     : BitMap;
  Begin
   GetObject(Source.Bitmap, SizeOf(Bit), @Bit);
   Source.Height := Bit.bmHeight;
   Source.Width := Bit.bmWidth;
  End;  // Процедура заполнения ширины\высоты

Код:

 Procedure Draw(Var T : TTexture; X,Y : Integer);
  Var
   Loc     : HDC;
  Begin
   Loc := CreateCompatibleDC(Warehouse.Buffer.DC);
   SelectObject(Loc, T.Bitmap);
   BitBlt(Warehouse.Buffer.DC, X, Y, T.Width, T.Height, Loc, 0, 0, SRCCOPY);
   DeleteDC(Loc);
  End;// Рисование на буфере.
 Procedure DrawT(Var T : TTexture; X,Y : Integer);
  Var
   Loc     : HDC;
  Begin
   Loc := CreateCompatibleDC(Warehouse.Buffer.DC);
   SelectObject(Loc, T.Bitmap);
   TransparentBlt(Warehouse.Buffer.DC, X, Y, T.Width, T.Height, Loc, 0, 0, T.Width, T.Height, $FF00FF);
   DeleteDC(Loc);
  End;  // То же с прозрачностью

Код:

 Procedure DrawB;
  Begin
   BitBlt(Application.FRMMain.IMGMain.DC,
          0, 0, 800, 600, Warehouse.Buffer.DC, 0, 0, SRCCOPY);
  End; // Вывод на экран. Размеры указывайте по форме.

Прикладываю проект, полностью построеннный на этом коде:
(Там только меню)
Вложения
Тип файла: rar Finder.rar (83.5 Кб, 27 просмотров)
__________________
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума   Ответить с цитированием
Старый 17.09.2010, 18:23   #9
fen1ksss
Пользователь
 
Регистрация: 29.11.2009
Сообщений: 44
Репутация: 10
По умолчанию

Цитата:
Сообщение от Прик Посмотреть сообщение
Вот такой код выводит изображение за заметное для глаза время:
Код:

for j := OriginalBitmap.Height-1 downto 0 do begin
  RowOriginal:=pRGBArray(OriginalBitmap.Scanline[j]);
  RowProcessed:=pRGBArray(ProcessedBitmap.Scanline[j]);
  for i:=OriginalBitmap.Width-1 downto 0 do begin
    //Доступ к RGB-цветам отдельных пикселей должен осуществляться следующим образом:
    RowProcessed[i].rgbtRed:=RowOriginal[i].rgbtRed;
    RowProcessed[i].rgbtGreen:=RowOriginal[i].rgbtGreen;
    RowProcessed[i].rgbtBlue:=RowOriginal[i].rgbtBlue;
    Form1.Canvas.Pixels[i,j]:=(RowProcessed[i].rgbtRed shl 16)+
                      (RowProcessed[i].rgbtGreen shl 8) +
           RowProcessed[i].rgbtBlue;
  end;
end;

А вот такой "мгновенно":
Код:

  for j:=OriginalBitmap.Height-1 downto 0 do begin
    RowOriginal:=pRGBArray(OriginalBitmap.Scanline[j]);
    RowProcessed:=pRGBArray(ProcessedBitmap.Scanline[j]);
    for i:=OriginalBitmap.Width-1 downto 0 do
      RowProcessed[i] := RowOriginal[i];
  end;
  Form1.Canvas.Draw(0, 0, ProcessedBitmap);

что то при замене 1 на второе ничего не выводится на форму... хотя вроде все точно копирую

Цитата:
Сообщение от Прик Посмотреть сообщение
Автору темы желательно попрактиковаться в работе с графикой, прежде чем браться за не самую простую, обозначенную им, задачу.
несомненно, просто это курсовая работа, так что пришлось браться с того, что задали

Цитата:
Сообщение от Прик Посмотреть сообщение
Вопрос.
А упомянутая функция "сравнения 2 массивов - 2 кадров" что принимает в качестве параметров (какой тип/какие типы и сколько) и что возвращает как результат сравнения?
на самом деле
Код:

Form1.Canvas.Pixels[i,j]:=(RowProcessed[i].rgbtRed shl 16)+
                      (RowProcessed[i].rgbtGreen shl 8) +
           RowProcessed[i].rgbtBlue;

это просто проверка того, что изображение находится в массиве, на самом деле мне нужен массив, допустим s1[i,j] = (RowProcessed[i].rgbtRed shl 16)+(RowProcessed[i].rgbtGreen shl 8) + RowProcessed[i].rgbtBlue;

Далее беру часть 2 изображения, так же засовываю в массив, допустим s2[i,j]

"Пробегаю s2 по всему s1" ища наименьшую разностную функцию, там где эта функция наименьшая, там теоретически и совпадают 2 кадра и просто накладываю 2 на 1.

Остается вопрос, каким типом описать s1 и s2? подскажите
fen1ksss вне форума   Ответить с цитированием
Старый 17.09.2010, 19:05   #10
Прик
Участник клуба
 
Регистрация: 08.09.2010
Сообщений: 863
Репутация: 266
По умолчанию

Оба фрагмента копирования и вывода я проверял - работают, т.е. изображение ProcessedBitmap выводятся на форму и в первом и во втором случае.

Вам не нужны какие-то особенные массивы (s, s2), так как TBitmap при загруженном изображении можно рассматривать как двухмерный массив элементов типа Integer, которые интерпретируются как TColor.
После загрузки картинок в один и второй объекты класса TBitmap уже можно спокойно применять к ним "разностную функцию".

Небольшое замечание: создавая объекты TBitmap нужно озаботится освобождением памяти от этих объектов когда они уже не нужны.
Прик вне форума   Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

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

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
timage в bmp varelik Мультимедиа в Delphi 8 21.12.2009 09:55
Программа BMP PradoSV Общие вопросы C/C++ 0 23.11.2009 23:25
bmp картинки B@R@B@$HK@ Общие вопросы C/C++ 0 09.06.2009 22:08
Как загрузить BMP в массив и обратно в С++ Ilja Общие вопросы C/C++ 8 07.03.2009 23:48
Декодирование BMP Rezet Мультимедиа в Delphi 6 24.01.2009 22:33




14:57.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.

Forex с Admiral Markets — это надежно


Работа на Forex с 2000 года. Очное и дистанционное обучение. Выгодные условия.
магазин горящих туров


более 1000 горящих предложений ежедневно
Бэбиблог - соц сеть для будущих мам


RusProfile.ru


Справочник российских юридических лиц и организаций.