WIL説明書(C++)  3.0.0
オーバレイ処理

オーバレイはベクタデータやラスタデータを画像データ等に重畳して表示する為の透明のレイヤーです。 1枚のレイヤーに複数のベクタ・ラスタデータを図形オブジェクトとして管理します。 図形オブジェクトは、それぞれ自身の描画位置を保有し、描画機能を実装しています。
オーバレイ処理は、下記の2通りの方法があります。

  1. オーバレイのインスタンスをユーザ側で管理する方法
  2. オーバレイのインスタンスを FVCL::GDI::CFvDisplay の内部で管理する方法


方法 (1):
ユーザ側で宣言したオーバレイを、このクラスの Overlays 配列に追加する方法です。 オーバレイのインスタンスはユーザ側で保持しておく必要があります。

CFvDisplay_overlay1.png

方法 (2):
このクラスの CreateOverlay メソッドでオーバレイを生成する方法です。 オーバレイのインスタンスは、このクラスの m_Overlays に保持されており、 オーバレイに対して操作するには、 GetOverlay メソッドでオーバレイのインスタンスを取得する必要があります。

CFvDisplay_overlay2.png

図形描画処理

画像にベクタデータやラスタデータを重畳して表示するには、オーバレイのインスタンスに対して 図形オブジェクト を追加する必要があります。
図形の描画処理は、下記の2通りの方法があります。

  1. 図形オブジェクトのインスタンスをユーザ側で管理する方法
  2. 図形オブジェクトのインスタンスを FVCL::GDI::CFvOverlay の内部で管理する方法


方法 (1):
図形オブジェクトのインスタンスをユーザ側で宣言して、オーバレイに配置する方法です。 図形オブジェクトのインスタンスをユーザ側で管理する必要はありますが、 ユーザが図形オブジェクトをマウスで操作するような動的なオーバレイを作成する場合は、この方法が適しています。

CFvOverlay_component1.png

方法 (2):
図形オブジェクトのインスタンスを FVCL::GDI::CFvOverlay の内部で管理する方法です。 図形を配置するには、 DrawFigure メソッドを使用します。 この時、メソッドに指定したインスタンスのコピーが m_Figures に保管されます。 図形オブジェクトを操作するには、前述の DrawFigure の戻り値を保持しておくか、 GetFigure で取得したインスタンスを介して行う必要があります。

CFvOverlay_component2.png

サンプルコード

下記は、ダイアログ上の任意の位置に画像とオーバレイ(文字列、線分)を描画する例です。
文字列はスケーリングせず表示領域の左上に描画しています。
線分はスケーリングして現在のコントロールポイントを中心に描画しています。

スクリーンショット:

CFvOverlay_SampleCodeDlg.png

ヘッダー:

#pragma once
#include "FVCLbasic.h"
#include "afxwin.h"
class CSampleCodeDlg : public CDialogEx
{
public:
CSampleCodeDlg(CWnd* pParent = NULL);
enum { IDD = IDD_SAMPLECODE_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
protected:
HICON m_hIcon;
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
protected:
FVCL::Data::CFvImage m_Image;
FVCL::GDI::CFvDisplay m_Display;
FVCL::GDI::CFvOverlay m_Overlay1;
FVCL::GDI::CFvOverlay m_Overlay2;
FVCL::GDI::CFvGdiString m_FigureText;
FVCL::GDI::CFvGdiLineSegment m_FigureLS1;
FVCL::GDI::CFvGdiLineSegment m_FigureLS2;
public:
CStatic m_View;
afx_msg void OnBnClickedButtonActual();
afx_msg void OnBnClickedButtonReduce();
afx_msg void OnBnClickedButtonExpand();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
};

実装: (初期化処理)

BOOL CSampleCodeDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);
// (1) 背景に表示する画像を読み込みます.
m_Image.Load(_T("TestFiles/floppy_RGB.jpg"));
// (2) ディスプレイを初期化します.
m_Display.Create();
// (-) オーバレイの初期化/設定の例:
{
m_Overlay1.SetScaling(false);
m_Display.Overlays.push_back( &m_Overlay1 );
m_Overlay2.SetScaling(true);
m_Overlay2.SetScalingMode(FVCL::GDI::ScalingMode::Center);
m_Display.Overlays.push_back( &m_Overlay2 );
}
// (-) 視点を中心に設定する例.
{
center.x = m_Image.GetHorzSize() / 2;
center.y = m_Image.GetVertSize() / 2;
m_Display.SetControlPoint(center);
}
return TRUE;
}


関連:


実装: (描画処理)

void CSampleCodeDlg::OnPaint()
{
if (IsIconic())
{
// (省略)
}
else
{
CPaintDC dcPaint(this);
{
// (3) 描画先のデバイスコンテキストを取得します.
CPaintDC dc(&m_View);
// (4) 画像の表示範囲を指定します.
CRect client;
m_View.GetClientRect( &client );
m_Display.SetDisplayRect( RECT(client) );
// (5) 描画対象画像を設定します.
m_Display.SetImage(&m_Image);
// (-) オーバレイ文字列の描画例:
{
text.Format(_T("Magnification: %6.2f"), m_Display.GetMagnification());
m_FigureText.SetPosition( FVCL::Data::CFvPoint( 4, 4 ) );
m_FigureText.SetText(text);
m_FigureText.SetColor( RGB(0xFF, 0x00, 0x00) );
m_Overlay1.Figures.clear();
m_Overlay1.Figures.push_back( &m_FigureText );
}
// (-) オーバレイ図形の描画例:
{
FVCL::Data::CFvPoint cp = m_Display.GetControlPoint();
FVCL::Data::CFvPoint st = m_Display.DPtoIP(0, 0);
FVCL::Data::CFvPoint ed = m_Display.DPtoIP(client.Width(), client.Height());
m_FigureLS1.GetPen().SetColor( RGB(0xFF, 0xFF, 0x00) );
m_FigureLS2.GetPen().SetColor( RGB(0xFF, 0xFF, 0x00) );
m_FigureLS1.st.x = cp.x;
m_FigureLS1.st.y = st.y;
m_FigureLS1.ed.x = cp.x;
m_FigureLS1.ed.y = ed.y;
m_FigureLS2.st.x = st.x;
m_FigureLS2.st.y = cp.y;
m_FigureLS2.ed.x = ed.x;
m_FigureLS2.ed.y = cp.y;
m_Overlay2.Figures.clear();
m_Overlay2.Figures.push_back( &m_FigureLS1 );
m_Overlay2.Figures.push_back( &m_FigureLS2 );
}
// (6) デバイスコンテキストへ画像データを書き出します.
m_Display.Draw(dc.GetSafeHdc());
}
CDialogEx::OnPaint();
}
}


関連:


実装: (その他、MFC ダイアログの初期化部分)

#include "stdafx.h"
#include "SampleCode.h"
#include "SampleCodeDlg.h"
#include "CAboutDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CSampleCodeDlg::CSampleCodeDlg(CWnd* pParent)
: CDialogEx(CSampleCodeDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CSampleCodeDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_STATIC_VIEW, m_View);
}
BEGIN_MESSAGE_MAP(CSampleCodeDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_ACTUAL, &CSampleCodeDlg::OnBnClickedButtonActual)
ON_BN_CLICKED(IDC_BUTTON_REDUCE, &CSampleCodeDlg::OnBnClickedButtonReduce)
ON_BN_CLICKED(IDC_BUTTON_EXPAND, &CSampleCodeDlg::OnBnClickedButtonExpand)
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
void CSampleCodeDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
HCURSOR CSampleCodeDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}

実装: (コントロールポイントの変更)

下記は、ダイアログ上をクリックされると画像座標に変換してコントロールポイントを設定する例です。

void CSampleCodeDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rect;
m_View.GetWindowRect( &rect );
CWnd::ScreenToClient(&rect);
CPoint dp;
dp.x = point.x - rect.left;
dp.y = point.y - rect.top;
FVCL::Data::CFvPoint ip = m_Display.DPtoIP(dp.x, dp.y);
m_Display.SetControlPoint( ip );
CWnd::SetRedraw( TRUE );
CWnd::Invalidate( TRUE );
CWnd::UpdateWindow();
CDialogEx::OnLButtonDown(nFlags, point);
}


関連:



CFvOverlay_SampleCodeDlg_3.png

実装: (表示倍率変更)

下記は、表示倍率を設定する例です。

void CSampleCodeDlg::OnBnClickedButtonActual()
{
m_Display.SetMagnification(1.0);
CWnd::SetRedraw( TRUE );
CWnd::Invalidate( TRUE );
CWnd::UpdateWindow();
}
void CSampleCodeDlg::OnBnClickedButtonReduce()
{
double mag = m_Display.GetMagnification() / 2;
if (mag < 0.1)
mag = 0.1;
m_Display.SetMagnification(mag);
CWnd::SetRedraw( TRUE );
CWnd::Invalidate( TRUE );
CWnd::UpdateWindow();
}
void CSampleCodeDlg::OnBnClickedButtonExpand()
{
double mag = m_Display.GetMagnification() * 2;
if (mag > 50.0)
mag = 50.0;
m_Display.SetMagnification(mag);
CWnd::SetRedraw( TRUE );
CWnd::Invalidate( TRUE );
CWnd::UpdateWindow();
}


関連:



拡大(x2.0) 拡大(x4.0)
CFvOverlay_SampleCodeDlg_4_E1.png
CFvOverlay_SampleCodeDlg_4_E2.png


縮小(x0.5) 縮小(x0.25)
CFvOverlay_SampleCodeDlg_4_R1.png
CFvOverlay_SampleCodeDlg_4_R2.png

Documentation copyright © 2007 FAST Corporation. [B-001864]
Generated on 2023年11月02日(木) 10時12分56秒 for WIL説明書(C++) by doxygen 1.8.11