前回は、画像を表示しました。
ただ読み込んだ画像がそのまま表示されているので、大きかったりすると画面すべてを表示できません。
そこで今回は読み込んだ画像のサイズを調整して表示しようと思います。
やりたい事の整理
今回やろうと思う事は、標準のコントロールにある[PictrureBox]のプロパティ[SizeMode]と同じことをしてみたいと思います。下記5点です。
■Normal → そのまま表示 ■StretchImage → 画像をコントロールの大きさに合わせる。 ■AutoSize → コントロールを画像の大きさに合わせる。 ■CenterImage → 画像を中心に表示する ■Zoom → 画像の比率は変えずに、コントロールの大きさに合わせて、中央に表示
【Normal】の場合、PictureBoxにそのまま画像を表示させる。

【StretchImage】の場合は、PictureBoxのサイズに合わせて表示する為、余白はなくなるが、画像の比率が違う場合、画像が伸びた形になる。

【AutoSize】の場合は、画像に合わせてPictureBoxのサイズを変更する

【CenterImage】の場合は、PictureBoxの中心と画像の中心を合わせた状態で表示する。

【Zoom】の場合は、画像の比率は変化させずに、PictureBoxの中心にサイズいっぱいいっぱい画像を表示させる。

HALCONでの表示調整方法
前回の記事で、【hWindowControl」を使って、画像を表示させました。
今回も【hWindowControl】を使っていきます。
【C#】HALCON de 画像処理(画像表示) | 育児パパの人生備忘録 (t19488sns.com)
【hWindowControl】のプロパティにImagePartというのものがあります。
これは、コントロールのサイズ内の表示サイズを設定します。

要は、ImagePartで指定した四角の領域分で表示され、(0,0)の位置から画像は表示されます。
Normal
これは、画像読込して、表示した流れをそのまま実施します。

private void button1_Click(object sender, EventArgs e)
{
//表示を消す
HOperatorSet.ClearWindow(hWindowControl1.HalconWindow);
OpenFileDialog ofd = new OpenFileDialog();
ofd.FileName = "";
ofd.InitialDirectory = @"C:\";
ofd.Filter = "画像ファイル(*.png;*.jpg)|*.png;*.jpg";
ofd.Title = "開くファイルを選択してください";
if (ofd.ShowDialog() == DialogResult.OK)
{
HTuple hwin1 = hWindowControl1.HalconWindow;
HOperatorSet.ReadImage(out HObject img, ofd.FileName);
//デフォルトに戻す
double defW = 640.0, defH = 480.0;
hWindowControl1.Size = new Size() { Width = (int)(defW / 2), Height = (int)(defH / 2) };
HOperatorSet.SetPart(hwin1, 0.0, 0.0, defH, defW);
DspImg = img;
HOperatorSet.DispObj(img, hwin1);
}
}

今回の変更点は、
■読み込んが画像のデータ<img>は、Private変数[DspImg]に入れる事。
■hWindowControlのサイズを元のサイズに戻す事
■hWindowControlのImagePartを元に戻す事
■初期時にhWindowControlに表示している画像をクリアする事
StretchImage

private void button2_Click(object sender, EventArgs e)
{
//表示を消す
HOperatorSet.ClearWindow(hWindowControl1.HalconWindow);
//DispImgにデータが入っているか確認
if (DspImg == null || DspImg.CountObj() <= 0) return;
//デフォルトに戻す
double defW = 640.0, defH = 480.0;
hWindowControl1.Size = new Size() { Width = (int)(defW / 2), Height = (int)(defH / 2) };
HOperatorSet.SetPart(hWindowControl1.HalconWindow, 0.0, 0.0, defH, defW);
//画像サイズを取得
HOperatorSet.GetImageSize(DspImg, out HTuple w, out HTuple h);
//画像サイズに合わせる。(コントロール内の表示サイズを設定)
HOperatorSet.SetPart(hWindowControl1.HalconWindow, 0.0, 0.0, h, w);
//再表示
HOperatorSet.DispObj(DspImg, hWindowControl1.HalconWindow);
}

流れとしては、
■表示を消す
■Private変数[DspImg]に画像があるかチェック
■デフォルトのサイズ/ImagePartに戻す
■Private変数[DspImg]の画像サイズの取得
■SetPartの調整
■表示
画像サイズの取得は、【GetImageSize()】で取得。
画像サイズをそのままImagePartにセットすればOK!!
AutoSize

private void button3_Click(object sender, EventArgs e)
{
//表示を消す
HOperatorSet.ClearWindow(hWindowControl1.HalconWindow);
//DispImgにデータが入っているか確認
if (DspImg == null || DspImg.CountObj() <= 0) return;
//デフォルトに戻す
double defW = 640.0, defH = 480.0;
hWindowControl1.Size = new Size() { Width = (int)(defW / 2), Height = (int)(defH / 2) };
HOperatorSet.SetPart(hWindowControl1.HalconWindow, 0.0, 0.0, defH, defW);
//画像サイズを取得
HOperatorSet.GetImageSize(DspImg, out HTuple w, out HTuple h);
hWindowControl1.Size = new Size() { Width = w, Height = h };
hWindowControl1.HalconWindow.SetPart(0, 0, h.I, w.I);
HOperatorSet.DispObj(DspImg, hWindowControl1.HalconWindow);
}

流れとしては、
■表示を消す
■Private変数[DspImg]に画像があるかチェック
■デフォルトのサイズ/ImagePartに戻す
■Private変数[DspImg]の画像サイズの取得
■Sizeの調整
■表示
CenterImage

private void button4_Click(object sender, EventArgs e)
{
//表示を消す
HOperatorSet.ClearWindow(hWindowControl1.HalconWindow);
//DispImgにデータが入っているか確認
if (DspImg == null || DspImg.CountObj() <= 0) return;
//デフォルトに戻す
double defW = 640.0, defH = 480.0;
hWindowControl1.Size = new Size() { Width = (int)(defW / 2), Height =(int)(defH / 2) };
HOperatorSet.SetPart(hWindowControl1.HalconWindow, 0.0, 0.0, defH, defW);
//画像サイズを取得
HOperatorSet.GetImageSize(DspImg, out HTuple w, out HTuple h);
double c1 = -(defW - w) / 2;
double c2 = c1 + defW;
double r1 = -(defH - h) / 2;
double r2 = r1 + defH;
HOperatorSet.SetPart(hWindowControl1.HalconWindow, r1, c1, r2, c2);
HOperatorSet.DispObj(DspImg, hWindowControl1.HalconWindow);
}

流れとしては、
■表示を消す
■Private変数[DspImg]に画像があるかチェック
■デフォルトのサイズ/ImagePartに戻す
■Private変数[DspImg]の画像サイズの取得
■SetPartの算出/調整
■表示
ここで肝になってくるのは、SetPartの算出方法です。
ざっくりこんな感じにあります。

DspImgはImagePartの(0,0)の位置から表示されます。
この絵のイメージから算出する数式は下記の通りになります。
X0 = – (Xprt – Ximg) / 2
X1 = Xprt + X0
Y0 = – (Yprt – Yimg) / 2
Y1 = Yprt + Y0
Zoom

private void button5_Click(object sender, EventArgs e)
{
//表示を消す
HOperatorSet.ClearWindow(hWindowControl1.HalconWindow);
//DispImgにデータが入っているか確認
if (DspImg == null || DspImg.CountObj() <= 0) return;
//デフォルトに戻す
double defW = 640.0, defH = 480.0;
hWindowControl1.Size = new Size() { Width = (int)(defW / 2), Height = (int)(defH / 2) };
HOperatorSet.SetPart(hWindowControl1.HalconWindow, 0.0, 0.0, defH, defW);
//画像サイズを取得
HOperatorSet.GetImageSize(DspImg, out HTuple w, out HTuple h);
//比率を求める
double rateR = defH / h, rateC = defW / w;
double rate = (rateR < rateC) ? rateR : rateC;
double c1 = -(defW / rate - w) / 2;
double c2 = c1 + defW / rate;
double r1 = -(defH / rate - h) / 2;
double r2 = r1 + defH / rate;
HOperatorSet.SetPart(hWindowControl1.HalconWindow, r1, c1, r2, c2);
HOperatorSet.DispObj(DspImg, hWindowControl1.HalconWindow);
}

流れとしては、
■表示を消す
■Private変数[DspImg]に画像があるかチェック
■デフォルトのサイズ/ImagePartに戻す
■Private変数[DspImg]の画像サイズの取得
■SetPartの算出/調整
■表示
ここでも算出が肝になります。
今回は、StretchImageとは違い、画像の比率を変えずに表示します。
読み込んだ画像サイズ(DspImg)から、何倍すれば、ImagePartのサイズ(w=640,h=480)になるかを各辺に対して行い、一番小さい倍率を選択し、その倍率から算出していきます。

X0 = – (Xprt / rate – Ximg) / 2
X1 = Xprt / rate + X0
Y0 = (Yprt / rate – Yimg) / 2
Y1 = Yprt / rate + Y0
まとめ
今回はHALCONを使って、表示する画像調整や表示する配置調整を行いました。
正直全然慣れていなくて、計算式がなかなか出てきませんでしたw
今回のでPictureBoxで選択できるSizeModeの5種類をすることが出来ましたね!
[Normal / StratchImage / AutoSize / CenterImage / Zoom]
ImagePartの使い方は、これでバッチリなような気がします!!

業務でプログラミング(C#/VB/Python)を作っている。
挫折を何回も繰り返し、幾度の壁を乗り越えてきた。
乗り越えてきた事を忘れないように記録に残す。
同じ思いをしている人への情報提供になれたらと思う。
基本は初心者に向けたプログラムの情報を提供する。
コメント