Форум: "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