Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.24;
Скачать: CL | DM;

Вниз

Сохранение Bitmap из буфера обмена(Clipboard) в файл   Найти похожие ветки 

 
Alexis ©   (2004-08-21 19:21) [0]

Делаю снимок экрана в Clipboard так :
ClipHandle : Cardinal;

keybd_event(VK_SNAPSHOT, 0, 0, 0);
ClipHandle := GetClipboardData(CF_BITMAP);

А что потом делать с полученным handle, чтобы сохранить изображение в bmp файл?
Заранее спасибо.


 
Dimaxx   (2004-08-21 23:18) [1]

А не проще ли сделать это через BitBlt и сразу кинуть в TBitmap?


 
Alexis ©   (2004-08-22 11:21) [2]

2 Dimaxx - может и проще, но я не подключаю к проекту Graphics по причине увеличения размера.
Может ли кто нибудь помочь по первоначальному вопросу?


 
Alexis ©   (2004-08-29 12:45) [3]

Ну вот, что я попытался написать, но все равно не работает :(

var
lpvObject : ^BITMAP;
hbm : HBITMAP;
FileH, ObjectSize : Integer;

begin
keybd_event(VK_SNAPSHOT, 0, 0, 0); //Capture all screen
if OpenClipboard(0) then
begin
 hbm := HBITMAP(GetClipboardData(CF_BITMAP));
 GetMem(lpvObject, sizeof(BITMAP));
 ObjectSize := GetObject(hbm, sizeof(BITMAP), lpvObject);
 showmessage(IntToStr(ObjectSize));
 FileH := FileCreate("ScreenShot.bmp");
 if FileH <> -1 then
 begin
  FileWrite(FileH, lpvObject^, ObjectSize);
  FileClose(FileH);
 end;

 CloseClipboard();
end;
end.

showmessage показывает полученный GetObject"ом размер 24 байта, хотя ясно, что bmp"шник в ClipBoard занимает гораздо больше.

Буду очень благодарен за помощь!


 
KSergey ©   (2004-08-29 14:04) [4]

Ты же сам сказал "буфер у меня на 24 байта"
Ф-ция честно вернула тебе 24 байта.
Это не имеет никакого отношения к размеру картинки.

> [2] Alexis ©   (22.08.04 11:21)
> 2 Dimaxx - может и проще, но я не подключаю к проекту Graphics
> по причине увеличения размера.

Заняться тебе просто нефигом... Ну и чатай сам книжки.. Там все написано...
Не, ну раз хочешь что-то познать - похвально, но тогда и прорывайся без подпорок!


 
Alexis ©   (2004-08-31 17:38) [5]


> Ты же сам сказал "буфер у меня на 24 байта"
> Ф-ция честно вернула тебе 24 байта.

Где ты такое увидел? Я по-моему такого не говорил.


 
Cobalt ©   (2004-08-31 22:13) [6]

2 Alexis ©   (31.08.04 17:38) [5]
ShowMessage(IntToStr(sizeof(BITMAP)));


 
enel ©   (2004-08-31 23:41) [7]

Можно проще:


procedure TMainForm.SaveScreenInFile;
var Dest: TRect;
   Desk: TCanvas;
   Bmp: TBitmap;
begin
 Dest:= Rect(0, 0, Screen.Width, Screen.Height);

 Bmp:= TBitmap.Create;
 Bmp.Width:= Screen.Width;
 Bmp.Height:= Screen.Height;

 Desk:= TCanvas.Create;
 Desk.Handle:= GetDC(HWND_DESKTOP);
 bmp.Canvas.CopyRect(Dest, Desk, Dest);
 bmp.SaveToFile(ExtractFilePath(Application.ExeName) + "FileName.bmp");

 ReleaseDC(Desk.Handle, HWND_DESKTOP);
 Bmp.Free;
 Desk.Free;
end;



 
enel ©   (2004-08-31 23:49) [8]

А тебе нужно сохранить в формате BMP?
А ты его знаешь? Если нет, то не выделывайся и подключай Graphic.


 
enel ©   (2004-09-01 02:38) [9]

Во-первых у тебя не освобождается память в твоем коде

>  GetMem(lpvObject, sizeof(BITMAP));

Во-вторых, объяви переменную Size в которую запиши
значение lpvObject.bmWidth*lpvObject.bmHeight*(lpvObject.bmBitsPixel div 8)+ SizeOf(Bitmap) это необходимый размер буффера;
Потом повторяй  ObjectSize := GetObject(hbm, Size, lpvObject);
после сохрани в файл, но не с расширением bmp, Size байт.
( т.к. он не будет правильным bmp-файлом, там нужно еще 30 байт информации)


 
Alexis ©   (2004-09-02 09:35) [10]


> Cobalt ©   (31.08.04 22:13) [6]
> ShowMessage(IntToStr(sizeof(BITMAP)));

Izvini, no pri cem zdes ShowMessage(IntToStr(sizeof(BITMAP)))??
U menia ved" showmessage(IntToStr(ObjectSize)) dlia proverki razmera buffera.


 
enel ©   (2004-09-08 01:12) [11]

Определение объеьа памяти, необходимого для хранения Bitmap:
> значение lpvObject.bmWidth*lpvObject.bmHeight*(lpvObject.bmBitsPixel
> div 8)+ SizeOf(Bitmap)
- эта запись не годится, есть корректнее:

var DIB: tagDIBSection;
   DataSize: Integer;
   HBM: HBitmap;
...

 GetObject(HBM, SizeOf(DIB), @DIB);
 DataSize:= GetBitmapBits(HBM, -1, DIB.dsBm.bmBits);


но вообще-то после GetObject в структуру DIB уже должна была быть занесена информация и в DIB.dsBmih.biSizeImage должен быть размер битмап, а в DIB.dsBm.bmBits - ссылка на данные этой битмап; я так и не понял почему, но у меня заполняется только поле dsBm структуры DIB, почему не знаю, полазь в OpenSourse Делфи (см. TBitmap.SaveToClipboardFormat или TBitmap.SaveToStream)


 
enel ©   (2004-09-18 01:34) [12]

Попробуй так:

//Три подпрограммы, необходимые для выявления ошибок GDI
//Нужно включить модуль Consts
procedure OutOfResources;
begin
 raise EOutOfResources.Create(SOutOfResources);
end;

procedure GDIError;
var
 ErrorCode: Integer;
 Buf: array [Byte] of Char;
begin
 ErrorCode := GetLastError;
 if (ErrorCode <> 0) and (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil,
   ErrorCode, LOCALE_USER_DEFAULT, Buf, sizeof(Buf), nil) <> 0) then
   raise EOutOfResources.Create(Buf)
 else
   OutOfResources;
end;

procedure Error;
var
 ErrorCode: Integer;
 Buf: array [Byte] of Char;
begin
 ErrorCode := GetLastError;
 if (ErrorCode <> 0) and (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil,
   ErrorCode, LOCALE_USER_DEFAULT, Buf, sizeof(Buf), nil) <> 0) then
   raise EOutOfResources.Create(Buf)
 else
   OutOfResources;
end;

function GDICheck(Value: Integer): Integer;
begin
 if Value = 0 then GDIError;
 Result := Value;
end;

// Сохранение
procedure SaveBitmap(ABitmap: HBitmap);
var Dib: TDibSection;
   Buf: Pointer;
   ISize: Integer;
   FileH: THandle;
begin
 if ABitmap = 0 then raise Exception.Create("Неправильный дискриптор");
 GdiCheck(GetObject(ABitmap, SizeOf(Dib), @Dib));
 if Dib.dsBm.bmBitsPixel < 24 then raise Exception.Create("Разрешение картинки менее чем 24 бит на пиксел");
 ISize:= GdiCheck(GetBitmapBits(ABitmap, -1, nil));
 GdiCheck(ISize);
 GetMem(Buf, ISize);
 try
   GdiCheck(GetBitmapBits(ABitmap, ISize, Buf));
   FileH:= FileCreate("ScreenShot.dat");
   try
     FileWrite(FileH, Dib.dsBm, SizeOf(Dib.dsBm));
     FileWrite(FileH, Buf^, ISize);
   finally
     FileClose(FileH);
   end;
 finally
   FreeMem(Buf);
 end;
end;

// Загрузка
// Вызывающая программа должна освободить ресурсы
procedure LoadBitmap(var ABitmap: HBitmap);
var Dib, Dib1: TDibSection;
   Buf: Pointer;
   ISize: Integer;
   FileH: THandle;
   ScreenDC: HDC;
begin
 FileH:= FileOpen("ScreenShot.dat", fmOpenRead);
 try
   ISize:= FileSeek(FileH, 0, soFromEnd)- SizeOf(Dib.dsBm);
   FileSeek(FileH, 0, soFromBeginning);
   FileRead(FileH, Dib.dsBm, SizeOf(Dib.dsBm));
   Dib.dsBm.bmBits:= nil;
   GetMem(Buf, ISize);
   try
     FileRead(FileH, Buf^, ISize);
     ScreenDC:= GdiCheck(GetDC(0));
     try
       with Dib.dsBm do
         ABitmap:= GdiCheck(CreateCompatibleBitmap(ScreenDC, bmWidth, bmHeight));
         try
           GdiCheck(SetBitmapBits(ABitmap, ISize, Buf));
         except
           DeleteObject(ABitmap);
         end;
     finally
       ReleaseDC(0, ScreenDC);
     end;
   finally
     FreeMem(Buf);
   end;
 finally
   FileClose(FileH);
 end;
end;

//                     Пример использования
// Нужно включить модуль Clipbrd

procedure TForm1.Button1Click(Sender: TObject);
var Bitmap: Cardinal;
begin
 Bitmap:= Clipboard.GetAsHandle(cf_Bitmap);
 SaveBitmap(Bitmap);
end;

procedure TForm1.Button2Click(Sender: TObject);
var Bitmap: HBitmap;
begin
 LoadBitmap(Bitmap);
 Clipboard.SetAsHandle(cf_Bitmap, Bitmap);
 DeleteObject(Bitmap); // Обязатльно нужно освободить ресурсы
end;



В Win NT работает, на других не знаю. На картинки менее чем 24 бита нужно еще и сохранение палитры.


 
Рыба ©   (2004-09-18 11:31) [13]

uses ClipBrd;

Bmp: TBitmap;
...
if ClipBoard.HasFormat(CF_BITMAP) then begin
 Bmp.Assign(ClipBoard);
 Bmp.SaxeToFile("gg.bmp");
end;


Сделай так и не парься.
Graphics не смертельно увеличивает размер.


 
Рыба ©   (2004-09-18 11:33) [14]

> Bmp.SaxeToFile("gg.bmp");

очепяточка %))))


 
Alexis ©   (2004-09-19 14:51) [15]

2 Рыба[13] - в моей проге, которая на данный момент весит 60 KB, использовать Graphics смертельно.



Страницы: 1 вся ветка

Текущий архив: 2004.10.24;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.622 c
1-1097356874
fmaker
2004-10-10 01:21
2004.10.24
Как сделать форму которая икогда бы не смогла бы быть активной,


14-1096746388
Guest
2004-10-02 23:46
2004.10.24
Как запускать ярлыки на музыкальные или видео файлы


3-1096009540
Леха
2004-09-24 11:05
2004.10.24
Как изменить значение всех строк с пом. sql


14-1096792176
gn
2004-10-03 12:29
2004.10.24
^-)


1-1097126943
П7
2004-10-07 09:29
2004.10.24
Эмуляция "незапуска" программы