Модераторы: Snowy, Alexeis, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Быстрая графика, Работа с графикой 
V
    Опции темы
костярик
Дата 20.7.2006, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Здравствуйте!
У меня вопрос. Я часто работаю с графикой, обычно использую класс TBitmap (ScanLine). Интересно, есть ли другой, более быстрый способ вывести изображение на экран, не используя АПИ-шки типа OpenGL или DirectX. 
PM MAIL   Вверх
Mechanic
Дата 20.7.2006, 22:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 5.5.2006
Где: Kharkov, Ukraine

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



Graphics32, например..  smile  
--------------------
Tell me the extensions of the files You backup and I'll tell You who You are..  ©Mch  
PM   Вверх
Alexeis
Дата 20.7.2006, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



Цитата(костярик @  20.7.2006,  17:12 Найти цитируемый пост)
Я часто работаю с графикой, обычно использую класс TBitmap (ScanLine)

Этот метод позволяет получить прямой доступ к памяти битовой карты изображения, что может быть быстрее этого? Другое дело отображение на экран! 


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

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

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
костярик
Дата 21.7.2006, 05:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата
Другое дело отображение на экран!


В том-то и дело. Как вывести массив цветов на экран, наиболее быстрым образом?  

Это сообщение отредактировал(а) костярик - 21.7.2006, 05:13
PM MAIL   Вверх
Kesh
Дата 21.7.2006, 09:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2488
Регистрация: 31.7.2002
Где: Германия, Saarbrü cken

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



BitBlt и FastBlt 


--------------------
user posted image
PM MAIL WWW ICQ Skype   Вверх
Alexeis
Дата 21.7.2006, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



PatBlt 


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

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

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alexeis
Дата 21.7.2006, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



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


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

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

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Kesh
Дата 21.7.2006, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2488
Регистрация: 31.7.2002
Где: Германия, Saarbrü cken

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



Пардон, ошибся... не FastBlt, а MaskBlt

Добавлено @ 15:15 
Хотя все-таки нет... Склероз пока еще не убил мой мозг...

Код

function BltFast(dwX: DWORD; 
  dwY: DWORD; 
  lpDDSrcSurface: IDirectDrawSurface4; 
  lpSrcRect: PRect; 
  dwTrans: DWORD): HResult;

Но работает он соответственно с DDSurface'ами... 


--------------------
user posted image
PM MAIL WWW ICQ Skype   Вверх
Alexeis
Дата 21.7.2006, 19:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



Цитата(Kesh @  21.7.2006,  15:11 Найти цитируемый пост)
Но работает он соответственно с DDSurface'ами...


костярик, просил 
Цитата(костярик @  20.7.2006,  17:12 Найти цитируемый пост)
 не используя АПИ-шки типа OpenGL или DirectX. 
 - это все таки  directDraw, я понял что он хотел выводить при помощи GDI
 


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

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

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
костярик
Дата 21.7.2006, 20:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

я понял что он хотел выводить при помощи GDI

Правильно, надо вывести массив цветов при помощи GDI. Тут вот BitBlt посоветовали, он копирует из одного контекста в другой. А как загнать цвета в контекст? 
PM MAIL   Вверх
Alexeis
Дата 21.7.2006, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



В него не нужно загонять просто
Код

var
bmp : tbitmap;
begin
...................
  BitBlt(bmp.canvas.handle,.....)

canvas.handle - это и есть контекст 


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

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

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
костярик
Дата 22.7.2006, 06:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

canvas.handle - это и есть контекст 

Да, но у меня есть только массив из троек байтов (R, G, B) для каждого цвета. У меня еще нет канвы. Как же мне имеющийся массив загнать в контекст. TBitmap я не использую, а то, понятно, можно было б через скан лайн. Есть ли такая возможность? 
PM MAIL   Вверх
Alexeis
Дата 22.7.2006, 16:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



CreateBitmapInderect - позволяет создать битмап в памяти, затем для него можно создать свой контекст. Он называется, что-то вроде контекста для памяти. Специальный контекст, не связанный ни с каким дескриптором окна. Это чистой воды Api операции. Я попробую поискать пример - когдато делал. 


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

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

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alexeis
Дата 22.7.2006, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



А вот и пример нашел
Код

var
  Form1: TForm1;
  bmp  : hBitMap;
  hBDC : HDC;
  bSize: TSize;
  r : integer;
  BInfo : ^BITMAP;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  bmp  := LoadImage(0, '049035.bmp', IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
  getMem(BInfo, sizeOf(BITMAP));
  GetObject(bmp, sizeOf(BITMAP), BInfo);
  hBDC := CreateCompatibleDC(form1.Canvas.Handle);
  SelectObject(hBDC, bmp);
  BitBlt(form1.Canvas.Handle, 0, 0, BInfo.bmWidth, BInfo.bmHeight, hBDC, 0, 0, SRCCOPY);
end;


LoadImage - Загружает картинку с диска
getMem(BInfo, sizeOf(BITMAP)); - выделение памяти под структуру, которая будет использоваться для функции  получения информации о битмапе - GetObject(bmp,sizeOf(BITMAP), BInfo);

  hBDC := CreateCompatibleDC(form1.Canvas.Handle); - создает новый контекст для структур в памяти (memory device context) т.е. для битовой маски совместимый с графическим адаптером. ипользуя в качестве образца контекст формы (подойдет любое окно).

SelectObject(hBDC, bmp); - связывает дескриптор битмапа с полученным контекстом

 BitBlt(form1.Canvas.Handle, 0, 0, BInfo.bmWidth, BInfo.bmHeight, hBDC, 0, 0, SRCCOPY); - рисуем все что есть в контексте битмапа на контекст формы. 
 


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

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

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alexeis
Дата 22.7.2006, 17:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



А теперь рассмотрим как можно создать битмап в памяти не загружая его с диска
В начале заполняем информационную структуру bmiInfo: BITMAPINFO;

Код

  bmiInfo.bmiHeader.biWidth:=W;            // ширина
  bmiInfo.bmiHeader.biHeight:=H;           // высота    
  bmiInfo.bmiHeader.biPlanes:=1;           // всегда 1    
  bmiInfo.bmiHeader.biBitCount:=24;        // три байта на пиксель    
  bmiInfo.bmiHeader.biCompression:=BI_RGB; // без компрессии    
  bmiInfo.bmiHeader.biSizeImage:=0;        // размер не знаем, ставим в ноль    
  bmiInfo.bmiHeader.biXPelsPerMeter:=2834; // пикселей на метр, гор.    
  bmiInfo.bmiHeader.biYPelsPerMeter:=2834; // пикселей на метр, верт.    
  bmiInfo.bmiHeader.biClrUsed:=0;          // палитры нет, все в ноль    
  bmiInfo.bmiHeader.biClrImportant:=0;     // то же    
  bmiInfo.bmiHeader.biSize:=SizeOf(bmiInfo.bmiHeader); // размер структруы    


Затем создаем собственно сам битмап
Код

  bmDIB := CreateDIBSection(DC, bmiInfo, DIB_RGB_COLORS,
                            Pointer(lpBits), 0, 0);

На этом этапе нам уже нужен контекст DC (как его получить писал выше)
(lpBits : PRGBTriple;) - указатель на карту.

Однако полученный битмап является DDB - Device Dependent Bitmap (не смотря на то что функция называется CreateDIBSection), что не позволяет нам н напрямую обращатся к битам карты. Поэтому мы должны его сконвертировать в DIB. Для этого заново готовим структуру  bmiInfo
Код

  bmiInfo.bmiHeader.biWidth:=W;            // ширина    
  bmiInfo.bmiHeader.biHeight:=H;           // высота    
  bmiInfo.bmiHeader.biPlanes:=1;           // всегда 1    
  bmiInfo.bmiHeader.biBitCount:=24;        // три байта на пиксель    
  bmiInfo.bmiHeader.biCompression:=BI_RGB; // без компресси
  bmiInfo.bmiHeader.biSize:=SizeOf(bmiInfo.bmiHeader); // размер структуры


И получаем битмап в нужном нам формате DIB_RGB_COLORS
Код
 
GetDIBits(DC, Bitmap, 0, H - 1, lpBits, bmiInfo, DIB_RGB_COLORS);


В параметре  lpBits получаем - адрес первого байта заветной битовой карты куда можно записывать битовый масив с учетом выравнивания каждой строки битмапа на границу 4-х байт (как в файле bmp) 

И чтоб в этом убедится
можно протестировать пикселы выводя вручную их из памяти на форму (это медленный вариант - только для тестирования smile )
Код

  p := Pointer(lpBits); //это мой вариант с выводом на форму

  For i := 1 to 200
  do
    for j := 1 to 250
    do
     form1.Canvas.Pixels[i, 250 - j] := RGB(p^[j,i].r, p^[j,i].g, p^[j,i].b);
 


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

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

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
костярик
Дата 24.7.2006, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Большое спасибо вам за инфу -- как раз то, что надо. Только у меня так и не получилось обратиться к массиву битов. Ваша конструкция p^[j,i].r работать, понятно, не будет: p -- это ж у нас указатель, к тому же нетипизированный, а не массив. Тут надо хитрее поступать. Я пытался работать с массивом цветов двумя способами: как с массивом байтов и как с массивом элементов, типа TRGBTriple. Для этого пришлось объявить новый тип:

  TRGBTripleArray = array [1..10000] of TRGBTriple;
  PRGBTripleArray = ^TRGBTripleArray;

Но это все равно не помогло. На экране ничего не рисуется, даже черный квадрат. Хотя bitblt возвращает true. Вот полностью весь код:
Код

  bmiInfo.bmiHeader.biWidth:=W;
  bmiInfo.bmiHeader.biHeight:=H;
  bmiInfo.bmiHeader.biPlanes:=1;
  bmiInfo.bmiHeader.biBitCount:=24;
  bmiInfo.bmiHeader.biCompression:=BI_RGB;
  bmiInfo.bmiHeader.biSizeImage:=0;
  bmiInfo.bmiHeader.biXPelsPerMeter:=2834;
  bmiInfo.bmiHeader.biYPelsPerMeter:=2834;
  bmiInfo.bmiHeader.biClrUsed:=0;
  bmiInfo.bmiHeader.biClrImportant:=0;
  bmiInfo.bmiHeader.biSize:=SizeOf(bmiInfo.bmiHeader);
  DC := CreateCompatibleDC(form1.Canvas.Handle);
  bmDIB := CreateDIBSection(DC, bmiInfo, DIB_RGB_COLORS,
                            Pointer(lpBits), 0, 0);
  bmiInfo.bmiHeader.biWidth:=W;
  bmiInfo.bmiHeader.biHeight:=H;
  bmiInfo.bmiHeader.biPlanes:=1;
  bmiInfo.bmiHeader.biBitCount:=24;
  bmiInfo.bmiHeader.biCompression:=BI_RGB;
  bmiInfo.bmiHeader.biSize:=SizeOf(bmiInfo.bmiHeader);
  GetDIBits(DC, bmDIB, 0, H - 1, lpBits, bmiInfo, DIB_RGB_COLORS);
  ellipse(dc, 1, 1, 5, 7); // рисуем эллипс
  bitblt(Canvas.Handle, 0, 0, w, h, dc, 0, 0, SRCCOPY); // пытаемся его отобразить
                                                        // на форме-- не работает!                
  For i := 1 to w do
    for j := 1 to h do
    begin
       // пытаемся обратиться к битам
      PByteArray(lpBits)[(j*w+i)*3+1] := i; // 1.способ
      PRGBTripleArray(lpbits)[j*w+i].rgbtRed :=   random(256); // 2 способ
      PRGBTripleArray(lpbits)[j*w+i].rgbtGreen := random(256); //
      PRGBTripleArray(lpbits)[j*w+i].rgbtBlue :=  random(256); //
    end;
  bitblt(Canvas.Handle, 10, 10, w, h, dc, 0, 0, SRCCOPY);  //  отображаем изменения -- не работает
 
PM MAIL   Вверх
Alexeis
Дата 24.7.2006, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



Цитата(костярик @  24.7.2006,  10:40 Найти цитируемый пост)
Только у меня так и не получилось обратиться к массиву битов. Ваша конструкция p^[j,i].r работать, понятно, не будет: p -- это ж у нас указатель

Эта констукция не может не работать, я ее проверял, на конкретном примере, не работает что-то другое!

Добавлено @ 11:25 
Вот рабочий пример!  

Это сообщение отредактировал(а) alexeis1 - 24.7.2006, 11:30

Присоединённый файл ( Кол-во скачиваний: 35 )
Присоединённый файл  load_image_Api.7z 103,20 Kb


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

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

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alexeis
Дата 24.7.2006, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



А вот вариант почти как вам надо!
Код

unit Unit1;

interface

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

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


var
  Form1: TForm1;
  b    : TBitmap;


implementation

{$R *.dfm}
          {$O-}
type
  Trgb = packed record
                 b,g,r : byte
                 end;

  arr = array[1..250,1..200] of Trgb;

procedure TForm1.btn1Click(Sender: TObject);
var
 DC : hDC;
 Bitmap : HBITMAP;
 p : ^arr;        //можно удалить
 i, j : integer;  //можно удалить
 bmInfo: TDIBSection;           // структура BITMAP WinAPI
 W, H : Integer;                 // высота и ширина растра
 bmDIB: hBitmap;                // дискрептор независимого растра
 bmiInfo: BITMAPINFO;           // структура BITMAPINFO WinAPI
 lpBits: PRGBTriple;            // указатели на структуры RGBTRIPLE WinAPI

begin
  Bitmap := LoadImage(0,
      'IMG.bmp',
      IMAGE_BITMAP,
      0,
      0,
      LR_DEFAULTSIZE or
      LR_LOADFROMFILE);

  GetObject(Bitmap, SizeOf(bmInfo), @bmInfo);

  DC := CreateCompatibleDC(form1.Canvas.Handle);
  SelectObject(DC, Bitmap);

  W := bmInfo.dsBm.bmWidth;
  H := bmInfo.dsBm.bmHeight;

  bmiInfo.bmiHeader.biWidth:=W;            // ширина
  bmiInfo.bmiHeader.biHeight:=H;           // высота    
  bmiInfo.bmiHeader.biPlanes:=1;           // всегда 1
  bmiInfo.bmiHeader.biBitCount:=24;        // три байта на пиксель    
  bmiInfo.bmiHeader.biCompression:=BI_RGB; // без компрессии
  bmiInfo.bmiHeader.biSizeImage:=0;        // размер не знаем, ставим в ноль    
  bmiInfo.bmiHeader.biXPelsPerMeter:=2834; // пикселей на метр, гор.
  bmiInfo.bmiHeader.biYPelsPerMeter:=2834; // пикселей на метр, верт.    
  bmiInfo.bmiHeader.biClrUsed:=0;          // палитры нет, все в ноль
  bmiInfo.bmiHeader.biClrImportant:=0;     // то же    
  bmiInfo.bmiHeader.biSize:=SizeOf(bmiInfo.bmiHeader); // размер структруы
  bmDIB := CreateDIBSection(DC, bmiInfo, DIB_RGB_COLORS,
  Pointer(lpBits), 0, 0);
  //создаем независимый растр WxHx24, без палитры, в указателе lpBits получаем    
  //адрес первого байта этого растра. bmDIB - дискрептор растра
  //заполняем первые шесть членов BITMAPINFO для передачи в GetDIBits    
  bmiInfo.bmiHeader.biWidth:=W;            // ширина
  bmiInfo.bmiHeader.biHeight:=H;           // высота    
  bmiInfo.bmiHeader.biPlanes:=1;           // всегда 1
  bmiInfo.bmiHeader.biBitCount:=24;        // три байта на пиксель    
  bmiInfo.bmiHeader.biCompression:=BI_RGB; // без компресси
  bmiInfo.bmiHeader.biSize:=SizeOf(bmiInfo.bmiHeader); // размер структуры    
  GetDIBits(DC, Bitmap, 0, H - 1, lpBits, bmiInfo, DIB_RGB_COLORS);

  p := Pointer(lpBits); //это мой вариант с выводом на форму

  ellipse(dc, 1, 1, 50, 17);
  BitBlt(Canvas.Handle, 0, 0, w, h, DC, 0, 0, SRCCOPY);
end;


Добавлено @ 11:53 
Вот тут вообще без загрузки изображения
+ Вывод при помощи bitblt
+ Вывод попиксельно из памяти указанной в p из того же битмапа
Код

unit Unit1;

interface

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

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


var
  Form1: TForm1;
  b    : TBitmap;


implementation

{$R *.dfm}
          {$O-}
type
  Trgb = packed record
                 b,g,r : byte
                 end;

  arr = array[1..250,1..200] of Trgb;

procedure TForm1.btn1Click(Sender: TObject);
var
 DC : hDC;
 Bitmap : HBITMAP;
 p : ^arr;        //можно удалить
 i, j : integer;  //можно удалить
 bmInfo: TDIBSection;           // структура BITMAP WinAPI
 W, H : Integer;                 // высота и ширина растра
 bmDIB: hBitmap;                // дискрептор независимого растра
 bmiInfo: BITMAPINFO;           // структура BITMAPINFO WinAPI
 lpBits: PRGBTriple;            // указатели на структуры RGBTRIPLE WinAPI

begin
  DC := CreateCompatibleDC(form1.Canvas.Handle);

  W := 200;
  H := 250;

  bmiInfo.bmiHeader.biWidth:=W;            // ширина
  bmiInfo.bmiHeader.biHeight:=H;           // высота
  bmiInfo.bmiHeader.biPlanes:=1;           // всегда 1
  bmiInfo.bmiHeader.biBitCount:=24;        // три байта на пиксель
  bmiInfo.bmiHeader.biCompression:=BI_RGB; // без компрессии
  bmiInfo.bmiHeader.biSizeImage:=0;        // размер не знаем, ставим в ноль
  bmiInfo.bmiHeader.biXPelsPerMeter:=2834; // пикселей на метр, гор.
  bmiInfo.bmiHeader.biYPelsPerMeter:=2834; // пикселей на метр, верт.
  bmiInfo.bmiHeader.biClrUsed:=0;          // палитры нет, все в ноль
  bmiInfo.bmiHeader.biClrImportant:=0;     // то же
  bmiInfo.bmiHeader.biSize:=SizeOf(bmiInfo.bmiHeader); // размер структруы
  bmDIB := CreateDIBSection(DC, bmiInfo, DIB_RGB_COLORS,
  Pointer(lpBits), 0, 0);

  SelectObject(DC, bmDIB);

  //создаем независимый растр WxHx24, без палитры, в указателе lpBits получаем
  //адрес первого байта этого растра. bmDIB - дискрептор растра
  //заполняем первые шесть членов BITMAPINFO для передачи в GetDIBits
  bmiInfo.bmiHeader.biWidth:=W;            // ширина
  bmiInfo.bmiHeader.biHeight:=H;           // высота
  bmiInfo.bmiHeader.biPlanes:=1;           // всегда 1
  bmiInfo.bmiHeader.biBitCount:=24;        // три байта на пиксель
  bmiInfo.bmiHeader.biCompression:=BI_RGB; // без компресси
  bmiInfo.bmiHeader.biSize:=SizeOf(bmiInfo.bmiHeader); // размер структуры
  GetDIBits(DC, Bitmap, 0, H - 1, lpBits, bmiInfo, DIB_RGB_COLORS);

  p := Pointer(lpBits); //это мой вариант с выводом на форму

  ellipse(dc, 1, 1, 140, 170);
  BitBlt(Canvas.Handle, 220, 0, w, h, DC, 0, 0, SRCCOPY);

  For i := 1 to 200 do
  for j := 1 to 250 do
   form1.Canvas.Pixels[i, 250 - j] := RGB(p^[j,i].r, p^[j,i].g, p^[j,i].b);
end;



end.

 


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

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

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
welt
Дата 14.6.2009, 01:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Alexeis
Ну я немного поправлю. Все-таки нехорошо, когда для разных картинок надо 
каждый раз вручную задавать границы массива
Код

 arr = array[1..250,1..200] of Trgb;


Я доработал код таким образом:

Код


type
  Trgb = packed record
   b,g,r : byte
   end;
const
  MaxPixelCountA = MaxInt div Sizeof(TRGB);
type
  arr = array [0..MaxPixelCountA - 1] of TRGB;

procedure TForm1.btn1Click(Sender: TObject);
var
 DC : hDC;
 Bitmap : HBITMAP;
 p : ^arr;        //можно удалить
 i, j : integer;  //можно удалить
 bmInfo: TDIBSection;           // структура BITMAP WinAPI
 W, H : Integer;                 // высота и ширина растра
 bmDIB: hBitmap;                // дискрептор независимого растра
 bmiInfo: BITMAPINFO;           // структура BITMAPINFO WinAPI
 lpBits: PRGBTriple;            // указатели на структуры RGBTRIPLE WinAPI

var
hBDC : HDC;

begin
  DC := Form1.Canvas.Handle; {DC := GetDC(Handle)
                              Handle - окна вывода(или любого)}
  Bitmap := LoadImage(0,
      'img.bmp',
      IMAGE_BITMAP,
      0,
      0,
      LR_DEFAULTSIZE or
      LR_LOADFROMFILE);

  GetObject(Bitmap, SizeOf(bmInfo), @bmInfo);
  W := bmInfo.dsBm.bmWidth;
  H := bmInfo.dsBm.bmHeight;
  hBDC := CreateCompatibleDC(dc);
  SelectObject(hBDC, Bitmap);
  BitBlt(dc, 0, 0, w, h, hBDC, 0, 0, SRCCOPY);

  bmiInfo.bmiHeader.biWidth:=W;            // ширина
  bmiInfo.bmiHeader.biHeight:=H;           // высота
  bmiInfo.bmiHeader.biPlanes:=1;           // всегда 1
  bmiInfo.bmiHeader.biBitCount:=24;        // три байта на пиксель
  bmiInfo.bmiHeader.biCompression:=BI_RGB; // без компрессии
  bmiInfo.bmiHeader.biSizeImage:=0;        // размер не знаем, ставим в ноль
  bmiInfo.bmiHeader.biXPelsPerMeter:=2834; // пикселей на метр, гор.
  bmiInfo.bmiHeader.biYPelsPerMeter:=2834; // пикселей на метр, верт.
  bmiInfo.bmiHeader.biClrUsed:=0;          // палитры нет, все в ноль
  bmiInfo.bmiHeader.biClrImportant:=0;     // то же
  bmiInfo.bmiHeader.biSize:=SizeOf(bmiInfo.bmiHeader); // размер структруы
  bmDIB := CreateDIBSection(DC, bmiInfo, DIB_RGB_COLORS,
  Pointer(lpBits), 0, 0);

  GetMem(p, w*h*sizeof(Trgb));
  GetDIBits(DC, Bitmap, 0, H - 1, lpBits, bmiInfo, DIB_RGB_COLORS);
  p := Pointer(lpBits); //

 {
  For i := 1 to W do  //Вывод на форму
   for j := 1 to H do  //Можно удалить
    form1.Canvas.Pixels[i, H - j] := RGB(p^[i + w * j].r, p^[i + w * j].g, p^[i + w * j].b);
 }
end;


PM MAIL   Вверх
Alexeis
Дата 14.6.2009, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



Цитата(welt @  14.6.2009,  00:42 Найти цитируемый пост)
Ну я немного поправлю. Все-таки нехорошо, когда для разных картинок надо 
каждый раз вручную задавать границы массива

  Главное, что ясна суть, так нагляднее видно что это матрица, а под свою задачу каждый пусть переделывает сам  smile 


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

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

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
AntonN
Дата 14.6.2009, 21:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



поправил спустя почти 3 года  smile 


--------------------
user posted image
PM MAIL WWW   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Звук, графика и видео"
Girder
Snowy
Alexeis

Запрещено:

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

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

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

FAQ раздела лежит здесь!


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

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Звук, графика и видео | Следующая тема »


 




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


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

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