Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Скриншот на Winapi


Автор: nuclearpartizan 3.2.2007, 15:22
Делаю скриншот из своей программы таким образом:

Цитата
Код

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;


Все отлично работает. Но размер скрина получается ~1,5mb
Можно как-то уменьшить размер файла без использования модулей jpeg, graphics? Размер программы критичен


Автор: Sartorius 3.2.2007, 15:27
В инфохеадере biCompression установи,какая понравиться.

Автор: Alexeis 12.2.2007, 19:09
Цитата(Sartorius @  3.2.2007,  15:27 Найти цитируемый пост)
В инфохеадере biCompression установи,какая понравиться.


Это вообще к чему сказано? Там может быть только заначения 0 = BI_RGB или 3  = BI_BITFIELDS

nuclearpartizan, можно использовать ZLIB. Скрины обычно хорошо жмуться.

Автор: Sartorius 12.2.2007, 19:40
Цитата

Это вообще к чему сказано? Там может быть только заначения 0 = BI_RGB или 3  = BI_BITFIELDS

 Почему ты так решил? 

Цитата

biCompression 
Specifies the type of compression for a compressed bottom-up bitmap (top-down DIBs cannot be compressed). This member can be one of the following values. Value Description 
BI_RGB An uncompressed format. 
BI_RLE8 A run-length encoded (RLE) format for bitmaps with 8 bpp. The compression format is a 2-byte format consisting of a count byte followed by a byte containing a color index. For more information, see Bitmap Compression.  
BI_RLE4 An RLE format for bitmaps with 4 bpp. The compression format is a 2-byte format consisting of a count byte followed by two word-length color indexes. For more information, see Bitmap Compression. 
BI_BITFIELDS Specifies that the bitmap is not compressed and that the color table consists of three DWORD color masks that specify the red, green, and blue components, respectively, of each pixel. This is valid when used with 16- and 32-bpp bitmaps. 
BI_JPEG Windows 98/Me, Windows 2000/XP: Indicates that the image is a JPEG image. 
BI_PNG Windows 98/Me, Windows 2000/XP: Indicates that the image is a PNG image. 


 При рисовании в контексте памяти все должно сразу сжиматься. Или я чего-то не понимаю?

Автор: Alexeis 12.2.2007, 20:22
Цитата(Sartorius @  12.2.2007,  19:40 Найти цитируемый пост)
Почему ты так решил? 

  Потому что значения BI_RLE8, BI_RLE4 - возможны только для битмапов 256 цветов и 16 цветов соответственно,  а это случается только если "полетел" драйвер видюхи или комп является музейным экспонатом. Что касается BI_JPEG, BI_PNG так этих друзей поддерживают только некоторые принтеры, и те устройства, которые поддерживают способны лишь выводить на печать, поток сжатых данных, но ни в коем случае не сжимать их. Об это так прямо и написано, в соседних разделах справки. Винда может только извлечь поток и передать принтеру, но не больше. Потому остаются только BI_RGB и BI_BITFIELDS.

Автор: RinOSpro 28.8.2007, 10:27
И еще вопросик что эта процедура в цикле не работает?? Записывается только заголовок что не так. Я и sleep выставлял но не пашет

Автор: Addmin 30.8.2007, 10:28
nuclearpartizan, обратите внимание на KOL, раз уж размеры программ так критичны smile С Bmp или Jpg вы маленького размера не получите никогда - он совершенно не приспособлен под это. Рекомендую с KOL покопаться в сторону PNG или GIF

www.kolnmck.ru

Автор: Snowy 30.8.2007, 10:54
Addmin, ты тупишь.

Автор: try_to_get 1.9.2007, 19:43
Можно написать свой алгоритм сжатия.

Автор: ne0n 1.9.2007, 20:22
Цитата(try_to_get @  1.9.2007,  19:43 Найти цитируемый пост)
Можно написать свой алгоритм сжатия.

Имхо не разумно! а может еще придумать свой формат изображения?!(это риторический вопрос)

Автор: try_to_get 1.9.2007, 20:49
ne0n, я просто привел пример, а решать nuclearpartizan писать или нет. smile 

Автор: ne0n 1.9.2007, 21:18
Цитата(try_to_get @  1.9.2007,  20:49 Найти цитируемый пост)
ne0n, я просто привел пример, а решать nuclearpartizan писать или нет.  


врятли ему поможет твой совет smile ты бы посмотрел на дату его поста и количество сообщений...

Автор: try_to_get 1.9.2007, 21:27
ne0n, Он "умер" что ли?

Автор: ne0n 1.9.2007, 22:40
Цитата(ne0n @  1.9.2007,  21:18 Найти цитируемый пост)
врятли ему поможет твой совет  ты бы посмотрел на дату его поста и количество сообщений...


подумай!

Автор: Addmin 2.9.2007, 05:06
Snowy, мда, вероятно. Вопросик то устарел smile Но всё равно - формат BMP очень неэкономичен, тем более для сохранения такого изображения, как рабочий стол. Наилучшим соотношением качество\размер для подобных изображений является формат PNG. Кто не верит - может скачать FastStone Capture (www.faststone.org) и поэкспериментировать smile

Автор: Alexeis 2.9.2007, 12:06
Addmin, только в случае если на рабочем столе не картники. PNG 24 бита сильно уступает jpg 24.

Автор: RinOSpro 7.9.2007, 08:07
http://forum.vingrad.ru/forum/topic-171341.html - вот здесь примеры как конвертировать в jpg и png

Добавлено через 1 минуту и 35 секунд
Люди а почему в цикле скриншот не снимается там записывается только заголовок 54 байта хотя я и sleep на 2 секунды ставил

Автор: Alexeis 7.9.2007, 10:01
Все нашел. Там была ошибка в коде. Не указан метод компрессии.

Код

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);
  FillChar(Bih, SizeOf(Bih), 0);
  FillChar(Bfh, SizeOf(Bfh), 0);
  Bih.biSize   := SizeOf(TBitmapInfoHeader);
  Bih.biWidth  := Width;
  Bih.biHeight := Height;
  Bih.biCompression := BI_RGB;
  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;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)