Главная страница
    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.48 MB
Время: 0.034 c
1-1100093018
Pentium133
2004-11-10 16:23
2004.11.21
потомок TThread


14-1098880794
Aldor
2004-10-27 16:39
2004.11.21
Ура! Еду в Новосибирск!


8-1092992637
race1
2004-08-20 13:03
2004.11.21
directshow player


14-1099181911
SpyBack
2004-10-31 03:18
2004.11.21
Зацените


1-1100069141
YuriS
2004-11-10 09:45
2004.11.21
MDIForm





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский