Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2004.11.21;
Скачать: [xml.tar.bz2];

Вниз

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

 
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 вся ветка

Форум: "Media";
Текущий архив: 2004.11.21;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.039 c
14-1099916302
Piter
2004-11-08 15:18
2004.11.21
Устройство TApplication


4-1097596116
F1
2004-10-12 19:48
2004.11.21
Как рисовать прямо на экране?


14-1099462223
Sergey_Masloff
2004-11-03 09:10
2004.11.21
На Borland ALM 2005 идет кто?


4-1097249553
pirate
2004-10-08 19:32
2004.11.21
Необходимо получить список запущенных процессов.


14-1099610766
default
2004-11-05 02:26
2004.11.21
Забавная задачка





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский