喫茶XRAYトップページ

[スレッド全体
]

[13596] ChatGPTやべえ返信 削除
2023/3/14 (火) 14:16:15 miya
ChatGPTやべえ

まずは、Delphiでわからないことを検索するとこのサイトが挙がることが多くて重宝しており、感謝申し上げます
ところがChatGPTを試してみたところ衝撃でした
これもう質問のコツを掴んだらコーディング時間1/3以下になるぞ

■質問
Delphiで2つのTBitmapの内容が同じであればTrueを返す関数

■回答
以下は、2つのTBitmapの内容が同じであるかどうかを比較し、結果をTrueまたはFalseで返すDelphiの関数の例です。

function BitmapsEqual(const Bitmap1, Bitmap2: TBitmap): Boolean;
var
  Stream1, Stream2: TMemoryStream;
begin
  // ビットマップをストリームにコピーする
  Stream1 := TMemoryStream.Create;
  try
    Bitmap1.SaveToStream(Stream1);
    Stream1.Position := 0;
  except
    Stream1.Free;
    Exit(False);
  end;

  Stream2 := TMemoryStream.Create;
  try
    Bitmap2.SaveToStream(Stream2);
    Stream2.Position := 0;
  except
    Stream2.Free;
    Stream1.Free;
    Exit(False);
  end;

  // ストリームの内容を比較する
  if Stream1.Size <> Stream2.Size then
  begin
    Stream2.Free;
    Stream1.Free;
    Exit(False);
  end;

  Result := CompareMem(Stream1.Memory, Stream2.Memory, Stream1.Size);

  Stream2.Free;
  Stream1.Free;
end;
この関数では、まず、各ビットマップをTMemoryStreamにコピーします。次に、ストリームの内容を比較します。ストリームのサイズが異なる場合は、ビットマップが異なるため、Falseを返します。ストリームのサイズが同じ場合は、CompareMem関数を使用してストリームの内容を比較し、TrueまたはFalseを返します。

この関数を使用するには、2つのTBitmapを引数として渡すだけです。例えば、次のように使用します。

if BitmapsEqual(Bitmap1, Bitmap2) then
begin
  // Bitmap1とBitmap2の内容が同じです
end
else
begin
  // Bitmap1とBitmap2の内容が異なります
end;


■質問
Delphiで自アプリではない他のウインドウのクライアント領域のスクリーンショットを取得する関数

■回答
以下は、Delphiで自分自身でないWindowsアプリのクライアント領域のスクリーンショットを取得する方法の例です。

uses
  Winapi.Windows, Vcl.Graphics;

function CaptureWindow(const Handle: HWND): TBitmap;
var
  DC: HDC;
  Rect: TRect;
begin
  Result := TBitmap.Create;
  try
    DC := GetDC(Handle);
    try
      GetClientRect(Handle, Rect);
      Result.Width := Rect.Right - Rect.Left;
      Result.Height := Rect.Bottom - Rect.Top;
      BitBlt(Result.Canvas.Handle, 0, 0, Result.Width, Result.Height, DC, 0, 0, SRCCOPY);
    finally
      ReleaseDC(Handle, DC);
    end;
  except
    Result.Free;
    raise;
  end;
end;
この関数では、ウィンドウのハンドルを引数として受け取り、TBitmap型のスクリーンショットを返します。GetDC関数を使用してウィンドウのデバイスコンテキストを取得し、BitBlt関数を使用してウィンドウのクライアント領域をTBitmapにコピーします。最後に、DCを解放し、TBitmapを返します。

この関数を使用するには、次のようにします。

var
  Bitmap: TBitmap;
begin
  Bitmap := CaptureWindow(SomeHandle);
  try
    // Bitmapにクライアント領域のスクリーンショットが格納されています
  finally
    Bitmap.Free;
  end;
end;
この関数は、自分自身でないアプリケーションのウィンドウハンドルを指定する必要があります。ただし、取得できるウィンドウの種類には制限があります。例えば、ウィンドウがデスクトップやシステムダイアログなどの特殊な種類である場合、この関数ではスクリーンショットを取得できません。

[13597] Re:ChatGPTやべえ返信 削除
2023/3/15 (水) 11:56:17 Mr.XRAY
ChatGPT とどういう関係があるのか分かりませんが・・・


  if LBitmapA.Equals(LBitmapB) then begin
    // 略
  end;


//=============================================================================
//  ウィンドウのクライアント領域のキャプチャ
//  uses に Winapi.WinSpool; が必要
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LhWnd   : HWND;
  LRect   : TRect;
  LBitmap : TBitmap;
begin
  LhWnd := Handle;
  Winapi.Windows.GetClientRect(LhWnd, LRect);

  LBitmap := TBitmap.Create;
  try
    // 以下の場合,自分自身のキャプチャなのでこれと同じ
//    LBitmap := Form1.GetFormImage;
//    LBitmap.SaveToFile('111.bmp');

    LBitmap.SetSize(LRect.Width, LRect.Height);

    LBitmap.Canvas.Lock;
    PrintWindow(LhWnd, LBitmap.Canvas.Handle, 1);
    LBitmap.Canvas.Unlock;

    LBitmap.SaveToFile('000.bmp');
  finally
    FreeAndNil(LBitmap);
  end;
end;


いろいろなコーディングがあるということです.
Printwindow 関数は,隠れたウィンドウもキャプチャします.
キャプチャ例てす.



[13598] ウィンドウのクライアント領域のキャプチャ返信 削除
2023/3/15 (水) 18:18:46 Mr.XRAY
>   if LBitmapA.Equals(LBitmapB) then begin
>     // 略
>   end;


TBitmap.Equals 関数の内部の処理コードは,miya さんが提示されたコードと同じです.

>   Winapi.Windows.GetClientRect(LhWnd, LRect);

は,Winapi,Windows がないとコンパイルエラーになります.

> //    LBitmap := Form1.GetFormImage;

GetFromImage の内部処理は,miya さんが提示されたコードとほとんど同じです.
PrintWindow 関数もそうかも知れません.


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82