Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.11.21;
Скачать: CL | DM;

Вниз

Как создать картинку?   Найти похожие ветки 

 
DeadMeat ©   (2004-08-20 11:35) [0]

Здрассте... Наконец Media заработала и я могу свой вопрос сюда задать...
Вообщем проблемка у меня такая - надо создать bitmap, но так, чтобы он располагался в определенном месте памяти, который я укажу... В данном случае мне нужно создать его в MapFile-е. Создание его в "своем" месте, а потом копирование не подходит. Критично скорость всей операции...
Кто знает как это сделать?

P.S. Желательно без Graphics, т.е. на API...


 
[lamer]Barmaglot ©   (2004-08-20 13:59) [1]

В чем проблема? Место в памяти нужное тебе ты веделил, формат заголовка известен, формат хранения данных известен.

Пишешь заголовок в память, за ним данные, вот и получаешь свой BMP в памяти... Или я не понял твою проблему?


 
Sapersky   (2004-08-20 15:02) [2]

The CreateDIBSection function creates a device-independent bitmap (DIB) that applications can write to directly. The function gives you a pointer to the location of the bitmap"s bit values. You can supply a handle to a file mapping object that the function will use to create the bitmap, or you can let the operating system allocate the memory for the bitmap.

Вроде то?
Относительно скорости мне и самому интересно. Можешь потом сообщить?


 
DeadMeat ©   (2004-08-20 21:48) [3]


> [1] [lamer]Barmaglot ©   (20.08.04 13:59)

Это та конечно хорошо, но в моем случае мне надо сделать снимок окна... Попиксельно сканить каждое окно по скорости может даже будет выше, но это ещё не мой уровень... Не дорос...


> [2] Sapersky   (20.08.04 15:02)

Спасибо... Не обратил внимание.
Попробовал, но что-то не очень работает.
Делаем снимок куска экрана:

procedure ShotWindow;
var bitdc, DC: HDC;
   BitsMem: Pointer;
   BitmapInfo: TBitmapInfo;
   hold:hgdiobj;
   size:integer;
begin
with BitmapInfo do
with bmiHeader do
begin
 biSize:=sizeof(bmiHeader);
 biWidth:= 200;
 biHeight:=200;
 biPlanes:= 1;
 biBitCount:= 24;
 biCompression:=BI_RGB;
 size:=bytesperscanline (biwidth,bibitcount,sizeof (dword));
 biSizeImage:=size;
 biXPelsPerMeter:= 0;
 biYPelsPerMeter:= 0;
 biClrUsed:= 0;
 biClrImportant:= 0;
end;

DC:=GetDC(form1.handle);
bitdc:=CreateCompatibleDC(DC);

bitmap:=CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, hi (size), lo (size), bitname);
bitimage:=MapViewOfFile(bitmap, FILE_MAP_ALL_ACCESS, 0, 0, size);

rbufdat^.hbit:=CreateDIBSection(DC,BitmapInfo,DIB_RGB_COLORS,BitsMem,bitmap,0);

ReleaseDC(form1.handle, DC);

hold:=SelectObject(bitdc,rbufdat^.hbit);

bitblt (bitdc,0,0,200,200,getdc (0),0,0,srccopy); //за getdc (0) просьба не пинать... знаю что освобождать надо... просто щас не до этого...

SelectObject(bitdc, hold);
DeleteObject(bitdc);
end;


Выводим его на форму:

procedure TForm1.Button2Click(Sender: TObject);
var dc:hdc;
   hold:hgdiobj;
begin
dc:=createcompatibledc (form1.Canvas.Handle);
hold:=selectobject (dc,rBufDat^.hbit);
bitblt (canvas.Handle,0,200,200,200,dc,0,0,srccopy);
selectobject (dc,hold);
DeleteObject(dc);
end;

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

---
...Death Is Only The Begining...


 
DeadMeat ©   (2004-08-21 15:22) [4]

Что..., никто не знает?..
Мож задать вопрос в WinApi...

---
...Death Is Only The Begining...


 
DeadMeat ©   (2004-08-22 14:33) [5]

Вопрос снят.
Огромное спасибо MBo за помощь.

---
...Death Is Only The Begining...


 
Sapersky   (2004-08-22 18:43) [6]

Э... а можно поподробней, в чём проблема была? У меня та же задача, но в чистом GDI опыта нет :(
Совсем хорошо было бы помочь исходником... :)


 
DeadMeat ©   (2004-08-22 20:05) [7]

Вообщем прикол вот в чем:

biCompression:=BI_RGB;
size:=bytesperscanline (biwidth,bibitcount,sizeof (dword))*bitheight;
biSizeImage:=size;

Как я уже говорил, дело было в размере мэпфайла. Он неправильно задавался...
Ещё:
bitmap:=CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, size, bitname);
Хватит только в LOW, т.к. это 32-битные значения => в этом случае можно указать только одно, ведь картинка вряд ли будет превышать 4Gb...

Теперь, для "доставания" картинки нужно проделать все теже действия, что и для создания, но рисовать не в неё, а из неё... Т.е. передавать hBitmap не надо..., надо только передать размеры и глубину цвета....
Короче вот рабочий результат:

const MMFName="Window_Shooter";
     bitname="Shot_Image";

type
 PBufDat=^TBufDat;
 TBufDat=packed record
  bufrect:tpoint;
  bitdepth:integer;
 end;

var
 rBufDat:PBufDat=nil;
 hMapObject:THandle=0;

 bitmap:thandle=0;
 bitimage:pointer=nil;

procedure ShotWindow (wd,hg,dp:integer);
var bitdc, DC: HDC;
   BitsMem: Pointer;
   BitmapInfo: TBitmapInfo;
   hold:hgdiobj;
   size:integer;
   hbitm:hbitmap;
begin
//здесь создается (или открывается) мапфайл и делается снимок
with BitmapInfo do
with bmiHeader do
begin
 biSize:=sizeof(bmiHeader);
 biWidth:=wd;
 biHeight:=hg;
 biPlanes:= 1;
 biBitCount:= dp;
 biCompression:=BI_RGB;
 size:=bytesperscanline (biwidth,bibitcount,sizeof (dword))*biheight;
 biSizeImage:=size;
 biXPelsPerMeter:= 0;
 biYPelsPerMeter:= 0;
 biClrUsed:= 0;
 biClrImportant:= 0;
end;

bitmap:=CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, size, bitname); //мапфайл для картинки
bitimage:=MapViewOfFile(bitmap, FILE_MAP_ALL_ACCESS, 0, 0, size);

DC:=GetDC(form1.handle);
bitdc:=CreateCompatibleDC(DC);
hbitm:=CreateDIBSection(DC,BitmapInfo,DIB_RGB_COLORS,BitsMem,bitmap,0);
ReleaseDC(form1.handle, DC);
hold:=SelectObject(bitdc,hbitm);

bitblt (bitdc,0,0,wd,hg,getdc (0),0,0,srccopy); //меняете на то что надо...

SelectObject(bitdc, hold);
DeleteObject(bitdc);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
rbufdat^.bufrect.Y:=200;
rbufdat^.bufrect.X:=200;
rbufdat^.bitdepth:=24;
shotwindow (rbufdat^.bufrect.Y,rbufdat^.bufrect.Y,rbufdat^.bitdepth); //делаем снимок
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
hMapObject:=CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TBufDat), MMFName); //мапфайл для данных
rBufDat:=MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TBufDat));
end;

procedure TForm1.Button4Click(Sender: TObject);
var bitdc, DC: HDC;
   BitsMem: Pointer;
   BitmapInfo: TBitmapInfo;
   hold:hgdiobj;
   size:integer;
   hbitm:hbitmap;
begin
//а здесь мы выводим ее на экран
with BitmapInfo do
with bmiHeader do
begin
 biSize:=sizeof(bmiHeader);
 biWidth:=rbufdat^.bufrect.X;
 biHeight:=rbufdat^.bufrect.Y;
 biPlanes:= 1;
 biBitCount:= rbufdat^.bitdepth;
 biCompression:=BI_RGB;
 size:=bytesperscanline (biwidth,bibitcount,sizeof (dword))*biheight;
 biSizeImage:=size;
 biXPelsPerMeter:= 0;
 biYPelsPerMeter:= 0;
 biClrUsed:= 0;
 biClrImportant:= 0;
end;

bitmap:=CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, size, bitname);
bitimage:=MapViewOfFile(bitmap, FILE_MAP_ALL_ACCESS, 0, 0, size);

DC:=GetDC(form1.handle);
bitdc:=CreateCompatibleDC(DC);
hbitm:=CreateDIBSection(DC,BitmapInfo,DIB_RGB_COLORS,BitsMem,bitmap,0);
ReleaseDC(form1.handle, DC);
hold:=SelectObject(bitdc,hbitm);

bitblt (canvas.Handle,0,0,rbufdat^.bufrect.X,rbufdat^.bufrect.y,bitdc,0,0,srccopy); //заменить на нужное

SelectObject(bitdc, hold);
DeleteObject(bitdc);
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
unmapviewoffile (bitimage);
closehandle (bitmap);

unmapviewoffile (rbufdat);
closehandle (hmapobject);
end;

end.

Вот вообщем то и все...

---
...Death Is Only The Begining...


 
Sapersky   (2004-08-23 11:11) [8]

Спасибо.
Не совсем понятно правда, зачем повторять два раза пассы с GDI - CreateDIBSection и прочее... Может, проще всё-таки передать hBitmap - или в другом процессе он будет недействителен?



Страницы: 1 вся ветка

Текущий архив: 2004.11.21;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.051 c
14-1099641414
kein
2004-11-05 10:56
2004.11.21
Как поменять загрузчик


14-1099881443
Думкин
2004-11-08 05:37
2004.11.21
С днем рождения! 8 ноября


1-1100152104
Sidek
2004-11-11 08:48
2004.11.21
Навигация в ClientDataSet-е


6-1095228765
kastik
2004-09-15 10:12
2004.11.21
Погода в сети через Delphi


1-1099892230
qp
2004-11-08 08:37
2004.11.21
Нужно ли инициализировать динамический массив после выделения пам