Re: GetDesktopScreenGraphMemImageの使い方 ( No.1 ) |
- 名前:管理人 日時:2020/06/28 01:02
GetDesktopScreenGraphMemImage はポインタについて熟知していないと扱うのは難しいです
引数や戻り値の解説は以下の通りです
// デスクトップ画面から指定領域の画像のメモリイメージの先頭アドレスとイメージの幅・高さ・ストライドを取得する
// ( イメージのフォーマットは ColorBitDepth = 32( バイト順で B8G8R8X8 の 32bitカラー ) ColorBitDepth = 24( バイト順で B8G8R8 の 24bitカラー ) )
//
// <引数>
// x1, y1 : イメージを取得したいデスクトップ上の領域の左上座標
// x2, y2 : イメージを取得したいデスクトップ上の領域の右下座標
// Width : 取り込んだ領域の幅を格納するint型変数のアドレス
// Height : 取り込んだ領域の高さを格納するint型変数のアドレス
// Stride : 取り込んだ画像の1ライン辺りのバイト数を格納するint型変数のアドレス
// ColorBitDepth : 32( バイト順で B8G8R8X8 の 32bitカラー ) 24( バイト順で B8G8R8 の 24bitカラー )
//
// <戻り値>
// 取り込んだ画像のイメージが格納されているメモリ領域の先頭アドレス
void *GetDesktopScreenGraphMemImage( int x1, int y1, int x2, int y2, int *Width, int *Height, int *Stride, int ColorBitDepth ) ;
載せていただいたコードを拝見する限りではケーキさんはポインタについて、この関数が使用できるほどには理解をされていないとお見受けします
とりあえずデスクトップ画面の左上の 640x480 の領域の『1フレーム前と色の変化が発生した部分のみ赤色に、それ以外は水色に表示される』プログラムを
組んでみましたので、よろしければご覧ください
#include "DxLib.h"
#include <memory.h>
#define CAPTURE_W 640
#define CAPTURE_H 480
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
void *Image ;
int Width ;
int Height ;
int Stride ;
int TempSoftImage ;
void *TempSoftImageAddr ;
int BackupSoftImage ;
void *BackupSoftImageAddr ;
int i, j ;
// ウインドウモードで起動
ChangeWindowMode( TRUE ) ;
// キャプチャするサイズと同じ画面のサイズに設定
SetGraphMode( CAPTURE_W, CAPTURE_H, 32 ) ;
// ウィンドウが非アクティブな状態でも動作するようにする
SetAlwaysRunFlag( TRUE ) ;
// DXライブラリの初期化
if( DxLib_Init() < 0 ) return -1 ;
// 描画先を裏画面にする
SetDrawScreen( DX_SCREEN_BACK ) ;
// 描画用ソフトイメージを作成
TempSoftImage = MakeXRGB8ColorSoftImage( CAPTURE_W, CAPTURE_H ) ;
// 描画用ソフトイメージの実イメージが格納されているメモリアドレスを取得
TempSoftImageAddr = GetImageAddressSoftImage( TempSoftImage ) ;
// 1フレーム前の画像保存用ソフトイメージを作成
BackupSoftImage = MakeXRGB8ColorSoftImage( CAPTURE_W, CAPTURE_H ) ;
// 1フレーム前の画像保存用ソフトイメージの実イメージが格納されているメモリアドレスを取得
BackupSoftImageAddr = GetImageAddressSoftImage( BackupSoftImage ) ;
// 1フレーム前の画像保存用ソフトイメージをクリア
memset( BackupSoftImageAddr, 0, CAPTURE_W * 4 * CAPTURE_H ) ;
// メインループ
while( ProcessMessage() == 0 )
{
// 画面のクリア
ClearDrawScreen() ;
// デスクトップ画面左上のイメージを取得
Image = GetDesktopScreenGraphMemImage( 0, 0, CAPTURE_W, CAPTURE_H, &Width, &Height, &Stride, 32 ) ;
// 描画用ソフトイメージに1フレーム前の画像保存用ソフトイメージと色の違う所のみを赤色を格納、それ以外は水色
for( i = 0; i < CAPTURE_H ; i++ )
{
for( j = 0; j < CAPTURE_W; j++ )
{
if( *( ( DWORD * )( ( BYTE * )Image + j * 4 + i * Stride ) ) != *( ( DWORD * )( ( BYTE * )BackupSoftImageAddr + j * 4 + i * CAPTURE_W * 4 ) ) )
{
*( ( DWORD * )( ( BYTE * )TempSoftImageAddr + j * 4 + i * CAPTURE_W * 4 ) ) = 0x00ff0000 ;
}
else
{
*( ( DWORD * )( ( BYTE * )TempSoftImageAddr + j * 4 + i * CAPTURE_W * 4 ) ) = 0x0000ffff ;
}
}
}
// 1フレーム前の画像保存用ソフトイメージに現在のフレームのイメージを保存
for( i = 0; i < CAPTURE_H ; i++ )
{
for( j = 0; j < CAPTURE_W; j++ )
{
*( ( DWORD * )( ( BYTE * )BackupSoftImageAddr + j * 4 + i * CAPTURE_W * 4 ) ) = *( ( DWORD * )( ( BYTE * )Image + j * 4 + i * Stride ) ) ;
}
}
// 現在のフレームと1フレーム前の画像の差異の結果を画面に描画する
DrawSoftImage( 0, 0, TempSoftImage ) ;
// 裏画面の内容を表画面に反映
ScreenFlip() ;
}
// DXライブラリの後始末
DxLib_End() ;
// ソフトの終了
return 0 ;
}
|
Re: GetDesktopScreenGraphMemImageの使い方 ( No.2 ) |
- 名前:ケーキ (解決) 日時:2020/07/01 14:22
ご回答ありがとうございました
サンプルコードで関数の使い方がわかりました
とりあえずスクリーン全体の変化地点だけを赤くして、それ以外を縮小表示するウィンドウを作れました
座標も保存することができたので、想像通りのものが作れそうです
動作しないコードで申し訳ないのですが、変更後のコードを貼っておきます
const vec2 SCREEN_SIZE(1920, 1080);
const vec2 WINDOW_SIZE(SCREEN_SIZE.x / 2, SCREEN_SIZE.y / 2);
// デスクトップ画面から指定領域の画像のメモリイメージの先頭アドレスとイメージの幅・高さ・ストライドを取得する
// ( イメージのフォーマットは ColorBitDepth = 32( バイト順で B8G8R8X8 の 32bitカラー ) ColorBitDepth = 24( バイト順で B8G8R8 の 24bitカラー ) )
//
// <引数>
// x1, y1 : イメージを取得したいデスクトップ上の領域の左上座標
// x2, y2 : イメージを取得したいデスクトップ上の領域の右下座標
// Width : 取り込んだ領域の幅を格納するint型変数のアドレス
// Height : 取り込んだ領域の高さを格納するint型変数のアドレス
// Stride : 取り込んだ画像の1ライン辺りのバイト数を格納するint型変数のアドレス
// ColorBitDepth : 32( バイト順で B8G8R8X8 の 32bitカラー ) 24( バイト順で B8G8R8 の 24bitカラー )
//
// <戻り値>
// 取り込んだ画像のイメージが格納されているメモリ領域の先頭アドレス
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
void* Image;
int Width;
int Height;
int Stride;
int TempSoftImage;
void* TempSoftImageAddr;
int BackupSoftImage;
void* BackupSoftImageAddr;
int i, j;
// ウインドウモードで起動
ChangeWindowMode(TRUE);
// キャプチャするサイズと同じ画面のサイズに設定
SetGraphMode(WINDOW_SIZE.x, WINDOW_SIZE.y, 32);
// ウィンドウが非アクティブな状態でも動作するようにする
SetAlwaysRunFlag(TRUE);
// DXライブラリの初期化
if (DxLib_Init() < 0) return -1;
// 描画先を裏画面にする
SetDrawScreen(DX_SCREEN_BACK);
// 描画用ソフトイメージを作成
TempSoftImage = MakeXRGB8ColorSoftImage(CAPTURE_W, CAPTURE_H);
// 描画用ソフトイメージの実イメージが格納されているメモリアドレスを取得
TempSoftImageAddr = GetImageAddressSoftImage(TempSoftImage);
// 1フレーム前の画像保存用ソフトイメージを作成
BackupSoftImage = MakeXRGB8ColorSoftImage(CAPTURE_W, CAPTURE_H);
// 1フレーム前の画像保存用ソフトイメージの実イメージが格納されているメモリアドレスを取得
BackupSoftImageAddr = GetImageAddressSoftImage(BackupSoftImage);
// 1フレーム前の画像保存用ソフトイメージをクリア
memset(BackupSoftImageAddr, 0, CAPTURE_W * 4 * CAPTURE_H);
// メインループ
while (ProcessMessage() == 0)
{
// 画面のクリア
ClearDrawScreen();
std::vector<vec2> pos;
// デスクトップ画面左上のイメージを取得
Image = GetDesktopScreenGraphMemImage(0, 0, CAPTURE_W, CAPTURE_H, &Width, &Height, &Stride, 32);
// 描画用ソフトイメージに1フレーム前の画像保存用ソフトイメージと色の違う所のみを赤色を格納、それ以外は水色
for (i = 0; i < CAPTURE_H; i++)
{
for (j = 0; j < CAPTURE_W; j++)
{
if (*((DWORD*)((BYTE*)Image + j * 4 + i * Stride)) != *((DWORD*)((BYTE*)BackupSoftImageAddr + j * 4 + i * CAPTURE_W * 4)))
{
*((DWORD*)((BYTE*)TempSoftImageAddr + j * 4 + i * CAPTURE_W * 4)) = 0x00ff0000;
pos.push_back(vec2(i, j));
}
else
{
*((DWORD*)((BYTE*)TempSoftImageAddr + j * 4 + i * CAPTURE_W * 4)) = *((DWORD*)((BYTE*)Image + j * 4 + i * Stride));
}
}
}
// 1フレーム前の画像保存用ソフトイメージに現在のフレームのイメージを保存
for (i = 0; i < CAPTURE_H; i++)
{
for (j = 0; j < CAPTURE_W; j++)
{
*((DWORD*)((BYTE*)BackupSoftImageAddr + j * 4 + i * CAPTURE_W * 4)) = *((DWORD*)((BYTE*)Image + j * 4 + i * Stride));
}
}
int screen_handle = MakeScreen(CAPTURE_W, CAPTURE_H);
SetDrawScreen(screen_handle);
// 現在のフレームと1フレーム前の画像の差異の結果を画面に描画する
DrawSoftImage(0, 0, TempSoftImage);
SetDrawScreen(DX_SCREEN_BACK);
DrawExtendGraph(0, 0, WINDOW_SIZE.x, WINDOW_SIZE.y, screen_handle, TRUE);
// 裏画面の内容を表画面に反映
ScreenFlip();
}
// DXライブラリの後始末
DxLib_End();
// ソフトの終了
return 0;
}
|
|