Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Сохранить DC в *.bmp файл. Как реализировать?

282
31 декабря 2006 года
Bard
481 / / 26.02.2006
Кто нибудь сталкивался с подобной проблемой, когда скриншот екрана надо сохранить как графический файл? Мне главное сохранить в файл сам битмап, а с заголовком bmp формата я и сам разберусь. Помогите, если знаете.
334
31 декабря 2006 года
HexEdit
809 / / 27.07.2006
Тебе это в винде надо?

Если в винде, то надо юзать CreateCompatimbleBitmap, GetDIBits и т. д.
получаешь таким образом набор пикселей и массив RGBQUAD и далее - записываешь все это в файл соответствующим образом (по формату файла)...

Есть примеры в MSDN.
282
31 декабря 2006 года
Bard
481 / / 26.02.2006
А пример можна?
4.1K
01 января 2007 года
GRIENDERS
117 / / 06.06.2006
Цитата: Bard
А пример можна?


Я сам столкнулся однажды с этим, но так как на WinApi это было сложно, решил создать в C++ Buldere dll. С его классом TJPEG - это как 2 байта переслать. Вот код, который сохраняет файл в формате jpeg

Код:
extern "C" __declspec(dllexport) WINAPI void MakeScreen(char* filename, int Quality)
  {
char* temp = new char[150];
GetSystemDirectory(temp,100);
strcat(temp,"\\temp.bmp");
 Graphics::TBitmap* bm = new   Graphics::TBitmap();
TJPEGImage* JPEG =new TJPEGImage();
HDC dc=GetWindowDC(GetDesktopWindow());
 bm->Height = 768;
 bm->Width = 1024;
BitBlt(bm->Canvas->Handle,0,0,1024, 768, dc,0,0, SRCCOPY);
bm->SaveToFile(temp);
JPEG->Assign(bm);
JPEG->CompressionQuality = Quality;
JPEG->Compress();
JPEG->SaveToFile(filename);
DeleteFile(temp);
}
// Quality - это качество, чем оно выше, тем увесистее файл

Вот на делфях, сохраняет в файл bmp
Код:
var
b: tbitmap;
dc:hdc;
begin
 b:=tbitmap.Create;
 b.Width := screen.Width;
 b.Height:= screen.Height;
  dc:=getdc(0);
  bitblt(b.Canvas.Handle,0,0,screen.Width, screen.Height,dc,0,0, SRCCOPY);
  b.SaveToFile('c:\test.bmp');
  b.Destroy;
  releasedc(0,dc);
end;
282
01 января 2007 года
Bard
481 / / 26.02.2006
За код конечно спасибо, но я уже на каком-то сайте нашел код на дельфях и переделал его на фасм:

Код на дельфях:
Код:
program Project1;

uses
  Windows;

procedure ScreenShot(const Width, Height: LongInt; const Filename: string);
var
    Bih: TBitmapInfoHeader;
    Bfh: TBitmapFileHeader;
    CDC, DC: HDC;
    CBmp: HBitMap;
    Bmp: Pointer;
    BmpInfo: TBitMapInfo;
    F, Size, Written: LongWord;
begin
    DC := GetDC(0);
    CDC := CreateCompatibleDC(DC);
    Bih.biSize := SizeOf(TBitmapInfoHeader);
    Bih.biWidth := Width;
    Bih.biHeight := Height;
    Bih.biPlanes := 1;
    Bih.biBitCount := GetDeviceCaps(DC, BITSPIXEL) * GetDeviceCaps(DC, PLANES);
    if Bih.biBitCount = 32 then Bih.biBitCount := 24;
    Size := 3 * Width * Height;
    Bfh.bfType := $4D42;
    Bfh.bfOffBits := SizeOf(TBitmapFileHeader) + SizeOf(TBitmapInfoHeader);
    BmpInfo.bmiHeader := Bih;
    CBmp := CreateDIBSection(DC, BmpInfo, 0, Bmp, 0, 0);
    SelectObject(CDC, CBmp);
    StretchBlt(CDC, 0, 0, Width, Height, DC, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SRCCOPY);
    F := CreateFile(PChar(Filename), GENERIC_WRITE, 0, nil, CREATE_ALWAYS, 0, 0);
    WriteFile(F, Bfh, SizeOf(TBitmapFileHeader), Written, nil);
    WriteFile(F, Bih, SizeOf(TBitmapInfoHeader), Written, nil);
    WriteFile(F, Bmp^, Size, Written, nil);
    CloseHandle(F);
end;

begin

ScreenShot(1024,768,'file.bmp');

end.


Переделаный мною код для фасм:

Код:
proc ScreenShot, _Width, _Height, _FileName
      invoke CreateDC,"DISPLAY",0,0,0
      mov [DC],eax
      invoke CreateCompatibleDC,[DC]
      mov [CDC],eax
      mov [Bih.biSize],44
      mov eax,[_Width]
      mov [Bih.biWidth],eax
      mov eax,[_Height]
      mov [Bih.biHeight],eax
      mov [Bih.biPlanes],1
      mov [Bih.biBitCount],24
      mov [Size],3
      mov eax,[Size]
      imul eax,[_Width]
      imul eax,[_Height]
      mov [Size],eax
      mov [Bfh.bfType],4D42h
      mov [Bfh.bfOffBits],64
      mov [BmpInfo],Bih
      invoke CreateDIBSection,[DC],[BmpInfo],0,Bmp,0,0
      mov [CBmp],eax
      invoke SelectObject,[CDC],[CBmp]
      invoke GetSystemMetrics,SM_CXSCREEN
      mov [ResolutionX],eax
      invoke GetSystemMetrics,SM_CYSCREEN
      mov [ResolutionY],eax
      invoke   StretchBlt,[CDC],0,0,[_Width],[_Height],[DC],0,0,[ResolutionX],[ResolutionY],SRCCOPY
      invoke CreateFile,[_FileName],GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0
      mov [F],eax
      invoke WriteFile,[F],Bfh,20,Written,0
      invoke WriteFile,[F],Bih,44,Written,0
      invoke WriteFile,[F],[Bmp],[Size],Written,0
      invoke CloseHandle,[F]
      ret
      endp



Дело в том, что я в дельфях не шарю вообще так что если я допустил какую-то ошибку - подправьте.

Код на астме сохраняет битмап в фай но с кривым заголовком (т.е. не правильным). И даже когда вручную создать заголовок для битмапа и наконец увидеть сделанный скрин, то оказываеться и битмап не правильный: верхняя часть скрина (пол екрана) с зеленоватым оттенком, а нижняя абсолютно нормальная.
282
01 января 2007 года
Bard
481 / / 26.02.2006
Ура! Свершилось!!!!! Всем кому интересно - юзайте!

Код на FASM'е

Код:
include '..\..\INCLUDE\win32ax.inc'

.data

  Bih          BITMAPINFOHEADER
  Bfh          BITMAPFILEHEADER
  CDC          dd ?
  DC           dd ?
  CBmp         dd ?
  Bmp          dd ?
  BmpInfo      dd ?
  F            dd ?
  Size         dd ?
  Written      dd ?

  ResolutionX dd ?
  ResolutionY dd ?

.code

  start:

    stdcall ScreenShot,1280,1024,"C:\screenshot.bmp"
    invoke ExitProcess, 0

      proc ScreenShot, _Width, _Height, _FileName
      invoke CreateDC,"DISPLAY",0,0,0
      mov [DC],eax
      invoke CreateCompatibleDC,[DC]
      mov [CDC],eax
      mov [Bih.biSize],40
      mov eax,[_Width]
      mov [Bih.biWidth],eax
      mov eax,[_Height]
      mov [Bih.biHeight],eax
      mov [Bih.biPlanes],1
      mov [Bih.biBitCount],24
      mov [Size],3
      mov eax,[Size]
      imul eax,[_Width]
      imul eax,[_Height]
      mov [Size],eax
      mov [Bfh.bfType],4D42h
      mov [Bfh.bfOffBits],58
      mov [BmpInfo],Bih
      invoke CreateDIBSection,[DC],[BmpInfo],0,Bmp,0,0
      mov [CBmp],eax
      invoke SelectObject,[CDC],[CBmp]
      invoke GetSystemMetrics,SM_CXSCREEN
      mov [ResolutionX],eax
      invoke GetSystemMetrics,SM_CYSCREEN
      mov [ResolutionY],eax
      invoke StretchBlt,[CDC],0,0,[_Width],[_Height],[DC],0,0,[ResolutionX],[ResolutionY],SRCCOPY
      invoke CreateFile,[_FileName],GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0
      mov [F],eax
      invoke WriteFile,[F],Bfh,14,Written,0
      invoke WriteFile,[F],Bih,44,Written,0
      invoke WriteFile,[F],[Bmp],[Size],Written,0
      invoke CloseHandle,[F]
      ret
      endp

.end start


Ошибка была втом, что я не правильно задал размеры обеих структур. Оказываеться, что размеры меньше на шесть байт.
261
04 января 2007 года
ahilles
1.5K / / 03.11.2005
юзаем...
вот только когда пишешь на асме врядли когда может пригодиться сохранять скриншот в файл
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог