画像処理ソリューション
これを見れば画像処理の入門から基礎~応用まで全てがわかるのを目指して!
   
翻訳(Translate)

プロフィール

ニックネーム:Akira
東京都の町田事業所に勤務
画像処理ソフトの開発を行っています。リンクフリーです!
詳細プロフィールは こちら
お問い合わせは、こちら↓

【補助HP】
画像処理ソリューションWeb版 【Newブログ】
イメージングソリューション

スポンサーリンク


カテゴリ

最近のコメント

カレンダー

12 | 2017/01 | 02
S M T W T F S
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 - - - -

趣味のブログ

iPhone萬歳!
iPhoneの情報いろいろ。
ブログ学習帳
ブログ、SEO、アフィリエイト情報など(まだまだこれから)
俺流クラフト日記
ハンドメイド作品の記録(現在、放置中)

スポンサーリンク 最近の記事
(09/18)  計測測定展に光切断のデモを出展しました
(08/17)  ディジタル画像技術事典200に記事が載りました
(06/09)  光切断を画像センシング展で公開
(05/14)  中国(上海)へ行って来ました
(04/12)  韓国へ行って来ました
(03/10)  私の求める新人像
(01/18)  エレクトロテストジャパンにカラー光切断法のデモを出展しました。
(12/23)  ユニークアクセス200万達成!
(12/10)  【カラー光切断法】YouTube動画まとめ
(11/04)  国際画像機器展2014にカラー光切断法を出展します。
(10/05)  第25回コンピュータビジョン勉強会@関東に参加してきました。
(09/08)  フーリエ変換の記事を追加しました。
(08/09)  【画像処理】ランキング低下中
(07/06)  記事の更新が停滞中...
(06/08)  画像センシング展2014でカラー光切断法のデモを行います。
(05/17)  カラー光切断法の動画を公開しました。
(04/30)  ソニーα NEX-5Rで星空撮影
(04/10)  カラー光切断法の取込結果を追加しました
(03/08)  Korea Vision Show 2014へ行ってきました
(02/05)  フーリエ変換シリーズを始めます。
(01/06)  2014年、あけましておめでとうございます。
(12/04)  カラー光切断法を公開(国際画像機器展2013にて)
(11/13)  国際画像機器展2013に出展します
(10/14)  「画像処理のためのC#」はじめます。
(09/16)  【C#,VB.NET】高速描画コントロールをバージョンアップしました。
(09/04)  拡大鏡に輝度値表示、ルーラー機能を追加した個人ツールを公開
(08/05)  7月の拍手Top5
(07/06)  2013年6月人気記事Top5
(05/12)  SONY α NEX-5Rレビュー
(04/24)  SONY α NEX-5RY購入

【.NET】Graphicsオブジェクトのアフィン変換(グローバル変換)

メインページC++/CLI プログラミング

前回、アフィン変換について説明しましたが、.NETプログラミング(VB.NET、C#、C++/CLI)においてもアフィン変換が用意されているのですが、マイクロソフトだけはDirectXも含めて、ちょっと特殊な行列表現をします。
このマイクロソフトで用いるアフィン変換の行列は、変換前の座標を(x, y)、変換前の座標を(x', y')とすると

.NETのアフィン変換

のように表現します。
この時の座標系は、ピクチャボックス等の左上が原点で時計回りが正の回転方向となります。

.NETのアフィン変換

X軸方向へTx、Y軸方向へTyだけ移動する平行移動の変換行列をTとすると、

  .NETのアフィン変換

X軸方向へSx倍、Y軸方向へSy倍だけ拡大する変換行列をSとすると、

  .NETのアフィン変換
原点まわりにθ°回転移動する変換行列をRとすると

  .NETのアフィン変換

のように表現されます。
この表現方法は、あくまでもマイクロソフトだけなので、一般的なアフィン変換と混同しないようにご注意下さい。

また、.NET Frameworkでは、それぞれGraphicsオブジェクトに対して、それぞれの変換を行うメソッドが用意されています。

平行移動はTranslateTransform
拡大縮小はScaleTransform
回転移動はRotateTransform

を用います。
また、行列を用いて変換しているので、行列を掛ける順番(平行移動や回転移動をする順番)が異なると結果も異なるのでご注意下さい。

C++/CLIのサンプルコード

【平行移動してから回転移動した場合】
// ビットマップファイルの読み込み
Bitmap^ bmp = gcnew Bitmap("Lenna.bmp");
// グラフィックオブジェクトの作成
Graphics^ g = pictureBox1->CreateGraphics();
// ワールド変換行列を単位行列にリセット
g->ResetTransform();
// 平行移動
g->TranslateTransform(100, 0, Drawing2D::MatrixOrder::Append);
// 20°回転
g->RotateTransform(20, Drawing2D::MatrixOrder::Append);
// 画像の描画
g->DrawImage(bmp, 0, 0);

(処理結果)
.NETのアフィン変換

回転移動してから平行移動した場合】
// ビットマップファイルの読み込み
Bitmap^ bmp = gcnew Bitmap("Lenna.bmp");
// グラフィックオブジェクトの作成
Graphics^ g = pictureBox1->CreateGraphics();
// ワールド変換行列を単位行列にリセット
g->ResetTransform();
// 20°回転
g->RotateTransform(20, Drawing2D::MatrixOrder::Append);
// 平行移動
g->TranslateTransform(100, 0, Drawing2D::MatrixOrder::Append);
// 画像の描画
g->DrawImage(bmp, 0, 0);

(処理結果)
.NETのアフィン変換
また、変換行列を直接指定してアフィン変換を行う事も可能です。
ただし、変換行列は最初に説明したマイクロソフト特有の変換行列です。

変換行列を直接指定した場合】
// ビットマップファイルの読み込み
Bitmap^ bmp = gcnew Bitmap("Lenna.bmp");
// グラフィックオブジェクトの作成
Graphics^ g = pictureBox1->CreateGraphics();
// ワールド変換行列を単位行列にリセット
g->ResetTransform();
// 回転行列
float CosTh = Math::Cos(20.0 / 180.0 * Math::PI);
float SinTh = Math::Sin(20.0 / 180.0 * Math::PI);
// 回転→平行移動の行列
Drawing2D::Matrix^ matRot
         = gcnew Drawing2D::Matrix(
                    CosTh,  SinTh,
                    -SinTh, CosTh,
                    100.0f, 0.0f
                    );
// 変換行列を指定
g->Transform = matRot;
// 画像の描画
g->DrawImage(bmp, 0, 0);

(処理結果)
.NETのアフィン変換

参考記事
http://msdn.microsoft.com/ja-jp/library/8667dchf%28v=VS.100%29.aspx
http://msdn.microsoft.com/ja-jp/library/c499ats3%28v=vs.80%29.aspx

Loading...
スポンサーリンク

スポンサーリンク 最近の記事
(09/18)  計測測定展に光切断のデモを出展しました
(08/17)  ディジタル画像技術事典200に記事が載りました
(06/09)  光切断を画像センシング展で公開
(05/14)  中国(上海)へ行って来ました
(04/12)  韓国へ行って来ました
(03/10)  私の求める新人像
(01/18)  エレクトロテストジャパンにカラー光切断法のデモを出展しました。
(12/23)  ユニークアクセス200万達成!
(12/10)  【カラー光切断法】YouTube動画まとめ
(11/04)  国際画像機器展2014にカラー光切断法を出展します。
(10/05)  第25回コンピュータビジョン勉強会@関東に参加してきました。
(09/08)  フーリエ変換の記事を追加しました。
(08/09)  【画像処理】ランキング低下中
(07/06)  記事の更新が停滞中...
(06/08)  画像センシング展2014でカラー光切断法のデモを行います。
(05/17)  カラー光切断法の動画を公開しました。
(04/30)  ソニーα NEX-5Rで星空撮影
(04/10)  カラー光切断法の取込結果を追加しました
(03/08)  Korea Vision Show 2014へ行ってきました
(02/05)  フーリエ変換シリーズを始めます。
(01/06)  2014年、あけましておめでとうございます。
(12/04)  カラー光切断法を公開(国際画像機器展2013にて)
(11/13)  国際画像機器展2013に出展します
(10/14)  「画像処理のためのC#」はじめます。
(09/16)  【C#,VB.NET】高速描画コントロールをバージョンアップしました。
(09/04)  拡大鏡に輝度値表示、ルーラー機能を追加した個人ツールを公開
(08/05)  7月の拍手Top5
(07/06)  2013年6月人気記事Top5
(05/12)  SONY α NEX-5Rレビュー
(04/24)  SONY α NEX-5RY購入

【C++/CLI】矢印の大きさ変更、任意形状の指定方法

メインページC++/CLI プログラミング

.NETで矢印を描画する場合、線種、線幅、終端形状、接合形状の設定でも紹介したようにStartCapEndCapのプロパティでArrowAnchorを指定すれば、矢印を描画する事はできますが、デフォルト状態では、矢印が小さすぎてあまり使い物になりません。

そこで、矢印の大きさを指定、任意形状を指定する方法を紹介したいと思います。

まずは、実行結果と、そのプログラムを参照下さい。

【実行結果】
矢印の大きさの変更、任意形状の指定
【サンプルプログラム】
private: System::Void pictureBox1_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e) {

                 //黒の線幅1のペンを作成
                 Pen^ p = gcnew Pen(Color::Black, 1);

                 ////////////////////////
                 //サイズ指定した矢印の描画


                 //サイズを指定した矢印を作成する。
                 System::Drawing::Drawing2D::AdjustableArrowCap^ myArrow
                        = gcnew System::Drawing::Drawing2D::AdjustableArrowCap(20, 20, false);

                 //線の終端に作成した矢印を指定する。
                 p->CustomEndCap = myArrow;

                 //矢印の描画
                 e->Graphics->DrawLine(p, 10, 50, 200, 50);

                 ////////////////////////
                 //任意矢印の描画

                 //GraphicsPathの作成

                 System::Drawing::Drawing2D::GraphicsPath ^hPath
                     = gcnew System::Drawing::Drawing2D::GraphicsPath();

                 array<Point>^ pts
                     = gcnew array<Point>{Point(0, 0), Point(-10, -20)
                        , Point(0, -14), Point(10, -20), Point(0, 0)};

                 // GraphicsPathへ多角形(矢印)を追加
                 hPath->AddPolygon(pts);

                 //塗りつぶさないカスタムキャップの定義
                 System::Drawing::Drawing2D::CustomLineCap ^HookStartCap
                     = gcnew System::Drawing::Drawing2D::CustomLineCap(nullptr, hPath);
                 //カスタムキャップの指定
                 p->CustomStartCap = HookStartCap;

                 //塗りつぶすカスタムキャップの定義
                 System::Drawing::Drawing2D::CustomLineCap ^HookEndCap
                     = gcnew System::Drawing::Drawing2D::CustomLineCap(hPath, nullptr);
                 //カスタムキャップの指定
                 p->CustomEndCap = HookEndCap;

                 //矢印の描画
                 e->Graphics->DrawLine(p, 10, 100, 200, 100);

                 //ペン幅を指定して矢印を描画
                 p->Width = 3;
                 e->Graphics->DrawLine(p, 10, 180, 200, 180);

             }

まず、矢印の大きさはSystem::Drawing::Drawing2D::AdjustableArrowCapクラスで幅と高さを指定します。
幅と高さの関係は以下のようになっています。
矢印の大きさの変更、任意形状の指定
また、塗りつぶした矢印を描きたい場合は

System::Drawing::Drawing2D::AdjustableArrowCap^ myArrow
                 = gcnew System::Drawing::Drawing2D::AdjustableArrowCap(20, 20, true);

のように指定します。

また、任意形状の矢印を描画したい場合は、矢印の形状そのものはGraphicPathで指定した形状をSystem::Drawing::Drawing2D::CustomLineCapクラスに指定する事で矢印を描画できます。

この時、GraphicPathで矢印の形状を指定する時の座標系は以下のように、線の中心から線の端点へ向かう方向が+Y軸方向となり、その反時計まわりに90度の方向が+X軸方向となります。
矢印の大きさの変更、任意形状の指定

塗りつぶさない矢印を描画する場合は
System::Drawing::Drawing2D::CustomLineCap ^HookStartCap
                  = gcnew System::Drawing::Drawing2D::CustomLineCap(nullptr, hPath);

塗りつぶす矢印を描画する場合は
System::Drawing::Drawing2D::CustomLineCap ^HookStartCap
                  = gcnew System::Drawing::Drawing2D::CustomLineCap(hPath, nullptr);

のように、CustomLineCapのどちらかに引数に作成したGraphicPathを指定します。

ここで、バグ?のような動作があり、同じGraphicPathを指定しているにも関わらず、塗りつぶすか?塗りつぶさないか?によって実際に描画される大きさが異なる場合もあるようにです。

また、実際に描画される矢印の大きさは線の幅(PenWidthプロパティ)の値に応じて大きさが変わります。

Loading...
スポンサーリンク

スポンサーリンク 最近の記事
(09/18)  計測測定展に光切断のデモを出展しました
(08/17)  ディジタル画像技術事典200に記事が載りました
(06/09)  光切断を画像センシング展で公開
(05/14)  中国(上海)へ行って来ました
(04/12)  韓国へ行って来ました
(03/10)  私の求める新人像
(01/18)  エレクトロテストジャパンにカラー光切断法のデモを出展しました。
(12/23)  ユニークアクセス200万達成!
(12/10)  【カラー光切断法】YouTube動画まとめ
(11/04)  国際画像機器展2014にカラー光切断法を出展します。
(10/05)  第25回コンピュータビジョン勉強会@関東に参加してきました。
(09/08)  フーリエ変換の記事を追加しました。
(08/09)  【画像処理】ランキング低下中
(07/06)  記事の更新が停滞中...
(06/08)  画像センシング展2014でカラー光切断法のデモを行います。
(05/17)  カラー光切断法の動画を公開しました。
(04/30)  ソニーα NEX-5Rで星空撮影
(04/10)  カラー光切断法の取込結果を追加しました
(03/08)  Korea Vision Show 2014へ行ってきました
(02/05)  フーリエ変換シリーズを始めます。
(01/06)  2014年、あけましておめでとうございます。
(12/04)  カラー光切断法を公開(国際画像機器展2013にて)
(11/13)  国際画像機器展2013に出展します
(10/14)  「画像処理のためのC#」はじめます。
(09/16)  【C#,VB.NET】高速描画コントロールをバージョンアップしました。
(09/04)  拡大鏡に輝度値表示、ルーラー機能を追加した個人ツールを公開
(08/05)  7月の拍手Top5
(07/06)  2013年6月人気記事Top5
(05/12)  SONY α NEX-5Rレビュー
(04/24)  SONY α NEX-5RY購入

【C++/CLI】大文字/小文字、全角/半角、ひらがな/カタカナを区別せず比較する

メインページC++/CLI プログラミング

文字列を比較する際に、文字の大文字/小文字、全角/半角、ひらがな/カタカナを区別せず比較したい場合があります。

大文字/小文字を区別せずに比較するのは、比較的、情報も多く、System.StringクラスCompareメソッドを使います。
使用例はこんな感じ↓

String^ strA = "Labeling";
String^ strB = "labeling";

if (String::Compare(strA, strB, true) == 0){
      MessageBox::Show("strAとstrBは同じ");
}

ただ、実際には、日本語を比較する場合は、全角/半角、ひらがな/カタカナを区別しないで比較したい場合が多く、この場合はSystem.Globalization.CompareInfoクラスCompareメソッドを使います。

(使用例)
System::Globalization::CompareInfo^ ci =
    System::Globalization::CultureInfo::CurrentCulture->CompareInfo;

String^ strA = "ラベリング";
String^ strB = "らべりんぐ";

if (ci->Compare(strA, strB,
    System::Globalization::CompareOptions::IgnoreWidth |         //全角/半角を無視
    System::Globalization::CompareOptions::IgnoreCase |          //大文字/小文字を無視
    System::Globalization::CompareOptions::IgnoreKanaType    //ひらがな/カタカナを無視
    ) == 0){
           MessageBox::Show("strAとstrBは同じ");
}

詳しくはDOBON.NETの
2つの文字列が等しいかを調べる
大文字小文字、半角全角、ひらがなカタカナの区別をしないで文字列を比較する

が参考になります。

実は"ラベリング""ラベリング"の文字列を比較するのに大はまりして、
ひらがな"ベ" と カタカナの "ベ" がある事に気が付くまで、とても苦労してしまいました...


Loading...
スポンサーリンク

スポンサーリンク 最近の記事
(09/18)  計測測定展に光切断のデモを出展しました
(08/17)  ディジタル画像技術事典200に記事が載りました
(06/09)  光切断を画像センシング展で公開
(05/14)  中国(上海)へ行って来ました
(04/12)  韓国へ行って来ました
(03/10)  私の求める新人像
(01/18)  エレクトロテストジャパンにカラー光切断法のデモを出展しました。
(12/23)  ユニークアクセス200万達成!
(12/10)  【カラー光切断法】YouTube動画まとめ
(11/04)  国際画像機器展2014にカラー光切断法を出展します。
(10/05)  第25回コンピュータビジョン勉強会@関東に参加してきました。
(09/08)  フーリエ変換の記事を追加しました。
(08/09)  【画像処理】ランキング低下中
(07/06)  記事の更新が停滞中...
(06/08)  画像センシング展2014でカラー光切断法のデモを行います。
(05/17)  カラー光切断法の動画を公開しました。
(04/30)  ソニーα NEX-5Rで星空撮影
(04/10)  カラー光切断法の取込結果を追加しました
(03/08)  Korea Vision Show 2014へ行ってきました
(02/05)  フーリエ変換シリーズを始めます。
(01/06)  2014年、あけましておめでとうございます。
(12/04)  カラー光切断法を公開(国際画像機器展2013にて)
(11/13)  国際画像機器展2013に出展します
(10/14)  「画像処理のためのC#」はじめます。
(09/16)  【C#,VB.NET】高速描画コントロールをバージョンアップしました。
(09/04)  拡大鏡に輝度値表示、ルーラー機能を追加した個人ツールを公開
(08/05)  7月の拍手Top5
(07/06)  2013年6月人気記事Top5
(05/12)  SONY α NEX-5Rレビュー
(04/24)  SONY α NEX-5RY購入

【C++/CLI】.NETクラスライブラリの作成、使用方法

メインページC++/CLI プログラミング

一言でライブラリと言っても、従来のC言語で作成されたライブラリと.NET環境(VB.NET、C#、C++/CLI)で作成されたライブラリとがあります。
どちらもファイル形式は*.dllなので、見分けが付きにくいのですが、.NETで作られたライブラリでは.NETのどの言語(VB.NET、C#、C++/CLI)からも使う事ができ、使い方も簡単です。
(C++/CLIで作成したライブラリは引数にポインタなどを用いると互換が取れない場合があります。)

.NETクラスライブラリの作成方法

ファイル→新規作成→プロジェクトで Visual C++→CLRクラスライブラリを選択しプロジェクト名を記入しOKボタンをクリックします。
.NETクラスライブラリの作成方法、使用方法

すると、以下のようにcppファイルhファイルが作成されます。

【DotNetClassLibrary.cpp】ファイル
// これは メイン DLL ファイルです。

#include "stdafx.h"

#include "DotNetClassLibrary.h"

【DotNetClassLibrary.h】ファイル
// DotNetClassLibrary.h

#pragma once

using namespace System;

namespace DotNetClassLibrary {

    public ref class Class1
    {
        // TODO: このクラスの、ユーザーのメソッドをここに追加してください。
    };
}

Class1というクラス名はあまりにも...なので、クラス名を Calc に変更し、簡単な足し算のメソッドを追加したものが、以下の通りとなります。

【DotNetClassLibrary.cpp】ファイル
// これは メイン DLL ファイルです。

#include "stdafx.h"

#include "DotNetClassLibrary.h"


using namespace DotNetClassLibrary;

double Calc::Add(double a, double b)
{
    return (a + b);
}


【DotNetClassLibrary.h】ファイル
// DotNetClassLibrary.h

#pragma once

using namespace System;

namespace DotNetClassLibrary {

    public ref class Calc
    {
        // TODO: このクラスの、ユーザーのメソッドをここに追加してください。
        public:
                double Add(double a, double b);
    };
}

これでプロジェクトをビルドすると、DotNetCladdLibrary.dllというファイルが作成され、DotNetCladdLibrary::CalcクラスAddメソッドをメンバにもつクラスが作成されます。

これで、.NETクラスライブラリの作成は完了です。

.NETクラスライブラリの使用方法(ライブラリをデバッグする場合)

まずは、ライブラリを評価するための簡単なプロジェクトを現在のソリューション(*.sln)に追加作成します。

今回は評価用のプログラムなので ファイル→追加→新しいプロジェクトで Visual C++→CLRクWindowsフォームアプリケーションを選択しプロジェクト名を記入しOKボタンをクリックします。
(今回はTestSampleという名前のプロジェクトを作成しました。)
.NETクラスライブラリの作成方法、使用方法

作成した評価用のプロジェクトから、.NETクラスライブラリをデバッグできるようにするためには、.NETクラスライブラリのプロジェクトを参照設定する必要があります。

参照設定方法は、プロジェクト名右クリック→参照 とクリックします。
.NETクラスライブラリの作成方法、使用方法

すると以下のようなウィンドウが表示されるので、『新しい参照の追加』ボタンをクリックします。
.NETクラスライブラリの作成方法、使用方法
表示されたウィンドウの『プロジェクト』のタブを選択し、参照するプロジェクトを選択OKボタンをクリックします。
.NETクラスライブラリの作成方法、使用方法
これで、作成したDotNetClassLibraryという.NETクラスライブラリを使用する準備ができました。
.NETクラスライブラリの作成方法、使用方法

次に、評価用のプロジェクトと.NETクラスライブラリのプロジェクトをデバッグするには、評価用のプロジェクトから起動し、.NETクラスライブラリを参照するような順番で起動して欲しいので、最初に起動するプロジェクトの設定を行います。

最初に起動するプロジェクトの設定方法は、プロジェクト名右クリック→スタートアッププロジェクトに設定クリックで設定ができます。

.NETクラスライブラリの作成方法、使用方法

実際に作成したAddメソッドの使用例は以下の通りです。

DotNetClassLibrary::Calc^ func = gcnew DotNetClassLibrary::Calc();

double x = func->Add(36.0, 24.0);

これで、デバッグ実行が可能となります。

ただ、今回作成したメソッドのように、ただ、足し算をするだけなのに、いちいちgcnewをするのは面倒だと思ったりしますよね?
そんな時には、.NETクラスライブラリのメソッド定義部分(ヘッダファイル(*.h))の先頭にstaticを付ける事でgcnewする事なく直接メソッドを呼び出す事が可能となります。

【DotNetClassLibrary.h】ファイル
// DotNetClassLibrary.h

#pragma once

using namespace System;

namespace DotNetClassLibrary {

    public ref class Calc
    {
        // TODO: このクラスの、ユーザーのメソッドをここに追加してください。
        public:
       
        static double Add(double a, double b);
    };
}

staticを付けた場合のAddメソッドの使用例は以下の通りです。

double x = DotNetClassLibrary::Calc::Add(36.0, 24.0);

.NETクラスライブラリの使用方法(ライブラリを使うだけの場合)

ライブラリをデバッグする時は、プロジェクト名右クリック→参照 とクリックし『プロジェクト』のタブを選択しましたが、今回は『参照』のタブを選択します。

次に作成した.NETクラスライブラリのファイルの場所を選択し、.NETクラスライブラリファイルを選択しOKボタンをクリックします。
.NETクラスライブラリの作成方法、使用方法
.NETのライブラリの場合は、ただ、この設定だけでライブラリを使用する事が可能となります。
(*.libや*.hファイルは必要ありません。)

本当は、次に作成したライブラリをC:\Windows\assemblyへインストールして・・・、マニフェストが・・・という話もあるかと思いますが、あまり分かっていないので、今回はここまでで...


Loading...
スポンサーリンク

スポンサーリンク 最近の記事
(09/18)  計測測定展に光切断のデモを出展しました
(08/17)  ディジタル画像技術事典200に記事が載りました
(06/09)  光切断を画像センシング展で公開
(05/14)  中国(上海)へ行って来ました
(04/12)  韓国へ行って来ました
(03/10)  私の求める新人像
(01/18)  エレクトロテストジャパンにカラー光切断法のデモを出展しました。
(12/23)  ユニークアクセス200万達成!
(12/10)  【カラー光切断法】YouTube動画まとめ
(11/04)  国際画像機器展2014にカラー光切断法を出展します。
(10/05)  第25回コンピュータビジョン勉強会@関東に参加してきました。
(09/08)  フーリエ変換の記事を追加しました。
(08/09)  【画像処理】ランキング低下中
(07/06)  記事の更新が停滞中...
(06/08)  画像センシング展2014でカラー光切断法のデモを行います。
(05/17)  カラー光切断法の動画を公開しました。
(04/30)  ソニーα NEX-5Rで星空撮影
(04/10)  カラー光切断法の取込結果を追加しました
(03/08)  Korea Vision Show 2014へ行ってきました
(02/05)  フーリエ変換シリーズを始めます。
(01/06)  2014年、あけましておめでとうございます。
(12/04)  カラー光切断法を公開(国際画像機器展2013にて)
(11/13)  国際画像機器展2013に出展します
(10/14)  「画像処理のためのC#」はじめます。
(09/16)  【C#,VB.NET】高速描画コントロールをバージョンアップしました。
(09/04)  拡大鏡に輝度値表示、ルーラー機能を追加した個人ツールを公開
(08/05)  7月の拍手Top5
(07/06)  2013年6月人気記事Top5
(05/12)  SONY α NEX-5Rレビュー
(04/24)  SONY α NEX-5RY購入

【C++/CLI】画像データの拡大縮小

メインページC++/CLI プログラミング

以前、画像表示の拡大縮小については画像の拡大縮小表示(高機能版)として紹介しましたが、今回は画像データのそのものを拡大縮小する方法を紹介します。

画像データを拡大縮小するにはSystem.Drawing.Bitmapクラスの以下のコンストラクタを用いる事で可能となります。

Bitmap (
    Image^ original,
    int width,
    int height
)

概要
指定したサイズを使用して、指定した既存のイメージで Bitmap クラスの新しいインスタンスを初期化します。

パラメータ
original新しい Bitmap の作成元の Image
width新しい Bitmap の幅 (ピクセル単位)
height新しい Bitmap の高さ (ピクセル単位)

処理例
//元の画像
Bitmap^ src = gcnew Bitmap("test.bmp");
//縮小画像(1/2に縮小)
Bitmap^ dstSmall = gcnew Bitmap(src, src->Width / 2, src->Height / 2);
//画像の保存
dstSmall->Save("SmallImage.bmp", Imaging::ImageFormat::Bmp);
//拡大画像(2倍に拡大)
Bitmap^ dstBig = gcnew Bitmap(src, src->Width * 2, src->Height * 2);
//画像の保存
dstBig->Save("BigImage.bmp", Imaging::ImageFormat::Bmp);

処理結果
元の画像(test.bmp)
画像データの拡大縮小
縮小画像(SmallImage.bmp)
画像データの拡大縮小
拡大画像(BigImage.bmp)
画像データの拡大縮小

補間モード(InterpolationMode)を指定して保存したい場合は、いったGraphicsを通して画像を描画することで、補間モードを設定します。

//元の画像
Bitmap^ src = gcnew Bitmap("test.bmp");
//拡大画像データの確保
Bitmap^ dst = gcnew Bitmap(src->Width * 2, src->Height * 2);
//Graphicsオブジェクトの確保
Graphics^ g = Graphics::FromImage(dst);
//補間モードの設定
g->InterpolationMode = Drawing2D::InterpolationMode::HighQualityBicubic;
//拡大してGraphicsへ描画
g->DrawImage(src, 0, 0, src->Width * 2, src->Height * 2);
//画像の保存
dst->Save("BigImage.bmp", Imaging::ImageFormat::Bmp);

ただし、この方法では元の画像データ(src)がモノクロデータ(8Bit)の場合、上記のプログラムのままではR,G,Bの値が等しい24Bitのカラー画像として保存されてしまいます。
モノクロ画像データとして保存したい場合は、カラー画像からモノクロ画像に変換するしかなさそうです。

【関連記事】
画像の拡大縮小表示(高機能版)
8Bitモノクロのカラーパレット設定
画素の補間(Nearest neighbor,Bilinear,Bicubic)


Loading...
スポンサーリンク

スポンサーリンク 最近の記事
(09/18)  計測測定展に光切断のデモを出展しました
(08/17)  ディジタル画像技術事典200に記事が載りました
(06/09)  光切断を画像センシング展で公開
(05/14)  中国(上海)へ行って来ました
(04/12)  韓国へ行って来ました
(03/10)  私の求める新人像
(01/18)  エレクトロテストジャパンにカラー光切断法のデモを出展しました。
(12/23)  ユニークアクセス200万達成!
(12/10)  【カラー光切断法】YouTube動画まとめ
(11/04)  国際画像機器展2014にカラー光切断法を出展します。
(10/05)  第25回コンピュータビジョン勉強会@関東に参加してきました。
(09/08)  フーリエ変換の記事を追加しました。
(08/09)  【画像処理】ランキング低下中
(07/06)  記事の更新が停滞中...
(06/08)  画像センシング展2014でカラー光切断法のデモを行います。
(05/17)  カラー光切断法の動画を公開しました。
(04/30)  ソニーα NEX-5Rで星空撮影
(04/10)  カラー光切断法の取込結果を追加しました
(03/08)  Korea Vision Show 2014へ行ってきました
(02/05)  フーリエ変換シリーズを始めます。
(01/06)  2014年、あけましておめでとうございます。
(12/04)  カラー光切断法を公開(国際画像機器展2013にて)
(11/13)  国際画像機器展2013に出展します
(10/14)  「画像処理のためのC#」はじめます。
(09/16)  【C#,VB.NET】高速描画コントロールをバージョンアップしました。
(09/04)  拡大鏡に輝度値表示、ルーラー機能を追加した個人ツールを公開
(08/05)  7月の拍手Top5
(07/06)  2013年6月人気記事Top5
(05/12)  SONY α NEX-5Rレビュー
(04/24)  SONY α NEX-5RY購入

【C++/CLI】アンカープロパティによるフォームのリサイズ処理

メインページC++/CLI プログラミング

フォームのリサイズ時にボタンなどの位置をフォームの大きさに合わせて調整する場合、位置を調整するコントロールのAnchorプロパティを設定すると簡単に位置調整が可能となります。

Anchorプロパティによるフォームリサイズ時の位置調整

Anchorプロパティは指定した方向がリサイズ時の位置の基準となり、指定した方向の距離が一定に保たれるようにコントロールの位置が調整されます。

何はともあれ、以下の動きを見て頂くと分かりやすいと思います。

【button1~button4:Top,Leftの場合】※Top,Leftはデフォルト設定値です。
Anchorプロパティによるフォームリサイズ時の位置調整



【button4:Bottom,Rightの場合】
Anchorプロパティによるフォームリサイズ時の位置調整



【button2,button4:Top,Left,Rightの場合】
Anchorプロパティによるフォームリサイズ時の位置調整



【button3,button4:Bottomの場合】
Anchorプロパティによるフォームリサイズ時の位置調整



【button4:Top,Bottom,Left,Rightの場合】
Anchorプロパティによるフォームリサイズ時の位置調整





VB6.0の時はフォームのリサイズイベントで座標を計算しながら位置を調整していましたが、.NETからは、このAnchorプロパティを使う事でやたらと簡単になりました。

Loading...
スポンサーリンク

スポンサーリンク 最近の記事
(09/18)  計測測定展に光切断のデモを出展しました
(08/17)  ディジタル画像技術事典200に記事が載りました
(06/09)  光切断を画像センシング展で公開
(05/14)  中国(上海)へ行って来ました
(04/12)  韓国へ行って来ました
(03/10)  私の求める新人像
(01/18)  エレクトロテストジャパンにカラー光切断法のデモを出展しました。
(12/23)  ユニークアクセス200万達成!
(12/10)  【カラー光切断法】YouTube動画まとめ
(11/04)  国際画像機器展2014にカラー光切断法を出展します。
(10/05)  第25回コンピュータビジョン勉強会@関東に参加してきました。
(09/08)  フーリエ変換の記事を追加しました。
(08/09)  【画像処理】ランキング低下中
(07/06)  記事の更新が停滞中...
(06/08)  画像センシング展2014でカラー光切断法のデモを行います。
(05/17)  カラー光切断法の動画を公開しました。
(04/30)  ソニーα NEX-5Rで星空撮影
(04/10)  カラー光切断法の取込結果を追加しました
(03/08)  Korea Vision Show 2014へ行ってきました
(02/05)  フーリエ変換シリーズを始めます。
(01/06)  2014年、あけましておめでとうございます。
(12/04)  カラー光切断法を公開(国際画像機器展2013にて)
(11/13)  国際画像機器展2013に出展します
(10/14)  「画像処理のためのC#」はじめます。
(09/16)  【C#,VB.NET】高速描画コントロールをバージョンアップしました。
(09/04)  拡大鏡に輝度値表示、ルーラー機能を追加した個人ツールを公開
(08/05)  7月の拍手Top5
(07/06)  2013年6月人気記事Top5
(05/12)  SONY α NEX-5Rレビュー
(04/24)  SONY α NEX-5RY購入

【C++/CLI、C#】enum型(列挙型)をキャストしないで使いたい

メインページC++/CLI プログラミング

C++/CLIでenumクラスを以下のように宣言し、

public enum class origin_enum
{
        top_left_origin,           //トップダウン
        bottom_left_origin     //ボトムアップ
};

このenumクラスを

int ImageType = origin_enum::top_left_origin;

というように使おうとすると

error C2440: '初期化中' : 'enumtest::enum_origin' から 'int' に変換できません。
この変換には static_cast、C スタイル キャストまたは関数スタイル キャストが必要です。

と怒られてしまうので、enumクラスを使う場合には

int ImageType = (int )origin_enum::top_left_origin;

とキャストしないといけない。
これが、ちょっとだけ使うならいいけど、何回も使う場合にはいちいちキャストするのは面倒なので、クラスで代用すれば同じ様な事が出来るのですが、ちょっとだけポイントがあって、以下のようにします。

C++/CLIの場合

public ref class origin_class
{
public:
        literal int top_left_origin = 0;            //トップダウン
        literal int bottom_left_origin = 1;     //ボトムアップ
};

literalを使うのがポイント!

C#の場合

public class origin_class
{
        public const int top_left_origin = 0;            //トップダウン
        public const int bottom_left_origin = 1;     //ボトムアップ
};

constを使うのがポイント!

ただ、結論からするとEnumを使う場合は数値として使うのではなく、Enumのまま使う(値を代入する方もEnumで使う)のがベスト
 

Loading...
スポンサーリンク

スポンサーリンク 最近の記事
(09/18)  計測測定展に光切断のデモを出展しました
(08/17)  ディジタル画像技術事典200に記事が載りました
(06/09)  光切断を画像センシング展で公開
(05/14)  中国(上海)へ行って来ました
(04/12)  韓国へ行って来ました
(03/10)  私の求める新人像
(01/18)  エレクトロテストジャパンにカラー光切断法のデモを出展しました。
(12/23)  ユニークアクセス200万達成!
(12/10)  【カラー光切断法】YouTube動画まとめ
(11/04)  国際画像機器展2014にカラー光切断法を出展します。
(10/05)  第25回コンピュータビジョン勉強会@関東に参加してきました。
(09/08)  フーリエ変換の記事を追加しました。
(08/09)  【画像処理】ランキング低下中
(07/06)  記事の更新が停滞中...
(06/08)  画像センシング展2014でカラー光切断法のデモを行います。
(05/17)  カラー光切断法の動画を公開しました。
(04/30)  ソニーα NEX-5Rで星空撮影
(04/10)  カラー光切断法の取込結果を追加しました
(03/08)  Korea Vision Show 2014へ行ってきました
(02/05)  フーリエ変換シリーズを始めます。
(01/06)  2014年、あけましておめでとうございます。
(12/04)  カラー光切断法を公開(国際画像機器展2013にて)
(11/13)  国際画像機器展2013に出展します
(10/14)  「画像処理のためのC#」はじめます。
(09/16)  【C#,VB.NET】高速描画コントロールをバージョンアップしました。
(09/04)  拡大鏡に輝度値表示、ルーラー機能を追加した個人ツールを公開
(08/05)  7月の拍手Top5
(07/06)  2013年6月人気記事Top5
(05/12)  SONY α NEX-5Rレビュー
(04/24)  SONY α NEX-5RY購入

【C++/CLI】ToolStripにチェックボックスなどのコントロールを追加する

メインページC++/CLI プログラミング

ToolStripには標準的にはボタンやラベル、テキストボックスなどが追加できますが、その他のコントロール(例えばCheckBoxなど)を追加すれば良いのか?調べてみたところ、情報源としては

http://dobon.net/vb/dotnet/control/tstoolstripcontrolhost.html
http://msdn.microsoft.com/ja-jp/library/9k5etstz.aspx
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.toolstripcontrolhost.aspx

などがあるのですが、C++/CLIではデザイナ(Formのエディタ)でエラーになったり、デザイナ上で追加したはずのコントロールが表示されなかったりするので、いろいろ試してみたところ、何とかこんな感じ↓でできました。

ToolStripに任意コントロールを追加する

情報源のページではToolStripControlHostを使うとあるのですが、これをFormのファイルに記述するとデザイナがエラーとなってしまいます。
そのため、この部分は別ファイルに記述します。

以下、ToolStripにCheckBoxを追加する例として説明します。

ヘッダファイル(ToolStripCheckBox.h)の作成 (ヘッダファイル名は何でも大丈夫です。)
#pragma once

using namespace System::Windows::Forms;

public ref class ToolStripCheckBox :
public ToolStripControlHost
{
public:
    ToolStripCheckBox(void) : ToolStripControlHost(gcnew CheckBox){}

    //チェックボックスコントロールの公開
    property CheckBox^ CheckBoxControl
    {
        CheckBox^ get(){
            return static_cast<CheckBox^>(Control);
        }
    }
};

上記で作成したヘッダファイルをプロジェクトに追加して、フォームのヘッダファイル(Form1.hなど)へは以下のように記述します。(背景色が水色の部分の4箇所を追記しています。)

#pragma once

#include "ToolStripCheckBox.h"

namespace ToolStripAdd {

    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;

    /// <summary>
    /// Form1 の概要
    ///
    /// 警告: このクラスの名前を変更する場合、このクラスが依存するすべての .resx ファイルに関連付けられた
    ///          マネージ リソース コンパイラ ツールに対して 'Resource File Name' プロパティを
    ///          変更する必要があります。この変更を行わないと、
    ///          デザイナと、このフォームに関連付けられたローカライズ済みリソースとが、
    ///          正しく相互に利用できなくなります。
    /// </summary>
    public ref class Form1 : public System::Windows::Forms::Form
    {
    public:
        Form1(void)
        {
            InitializeComponent();
            //
            //TODO: ここにコンストラクタ コードを追加します
            //
        }

    protected:
        /// <summary>
        /// 使用中のリソースをすべてクリーンアップします。
        /// </summary>
        ~Form1()
        {
            if (components)
            {
                delete components;
            }
        }
    private: System::Windows::Forms::ToolStrip^  toolStrip1;
    protected:
    private: System::Windows::Forms::ToolStripButton^  toolStripButton1;
    private: ToolStripCheckBox^  toolStripCheckBox1;

    private:
        /// <summary>
        /// 必要なデザイナ変数です。
        /// </summary>
        System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
        /// <summary>
        /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
        /// コード エディタで変更しないでください。
        /// </summary>
        void InitializeComponent(void)
        {
            System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(Form1::typeid));
            this->toolStrip1 = (gcnew System::Windows::Forms::ToolStrip());
            this->toolStripButton1 = (gcnew System::Windows::Forms::ToolStripButton());
            this->toolStripCheckBox1 = (gcnew ToolStripCheckBox());
            this->toolStrip1->SuspendLayout();
            this->SuspendLayout();
            //
            // toolStrip1
            //
            this->toolStrip1->Items->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(2) {this->toolStripButton1,
                this->toolStripCheckBox1});
            this->toolStrip1->Location = System::Drawing::Point(0, 0);
            this->toolStrip1->Name = L"toolStrip1";
            this->toolStrip1->Size = System::Drawing::Size(168, 25);
            this->toolStrip1->TabIndex = 0;
            this->toolStrip1->Text = L"toolStrip1";
            //
            // toolStripButton1
            //
            this->toolStripButton1->DisplayStyle = System::Windows::Forms::ToolStripItemDisplayStyle::Image;
            this->toolStripButton1->Image = (cli::safe_cast<System::Drawing::Image^  >(resources->GetObject(L"toolStripButton1.Image")));
            this->toolStripButton1->ImageTransparentColor = System::Drawing::Color::Magenta;
            this->toolStripButton1->Name = L"toolStripButton1";
            this->toolStripButton1->Size = System::Drawing::Size(23, 22);
            this->toolStripButton1->Text = L"toolStripButton1";
            //
            // toolStripCheckBox1
            //
            this->toolStripCheckBox1->Name = L"toolStripCheckBox1";
            this->toolStripCheckBox1->Size = System::Drawing::Size(15, 22);
            //
            // Form1
            //
            this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
            this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
            this->ClientSize = System::Drawing::Size(168, 130);
            this->Controls->Add(this->toolStrip1);
            this->Name = L"Form1";
            this->Text = L"Form1";
            this->toolStrip1->ResumeLayout(false);
            this->toolStrip1->PerformLayout();
            this->ResumeLayout(false);
            this->PerformLayout();

        }
#pragma endregion
    };
}

これで、追加ができました...

InitializeComponentメソッドの中をいじくるのはあまりしたくは無いのですが、色々試した感じでは、この位置で記述しないとエラーになるようです。


Loading...
スポンサーリンク

スポンサーリンク 最近の記事
(09/18)  計測測定展に光切断のデモを出展しました
(08/17)  ディジタル画像技術事典200に記事が載りました
(06/09)  光切断を画像センシング展で公開
(05/14)  中国(上海)へ行って来ました
(04/12)  韓国へ行って来ました
(03/10)  私の求める新人像
(01/18)  エレクトロテストジャパンにカラー光切断法のデモを出展しました。
(12/23)  ユニークアクセス200万達成!
(12/10)  【カラー光切断法】YouTube動画まとめ
(11/04)  国際画像機器展2014にカラー光切断法を出展します。
(10/05)  第25回コンピュータビジョン勉強会@関東に参加してきました。
(09/08)  フーリエ変換の記事を追加しました。
(08/09)  【画像処理】ランキング低下中
(07/06)  記事の更新が停滞中...
(06/08)  画像センシング展2014でカラー光切断法のデモを行います。
(05/17)  カラー光切断法の動画を公開しました。
(04/30)  ソニーα NEX-5Rで星空撮影
(04/10)  カラー光切断法の取込結果を追加しました
(03/08)  Korea Vision Show 2014へ行ってきました
(02/05)  フーリエ変換シリーズを始めます。
(01/06)  2014年、あけましておめでとうございます。
(12/04)  カラー光切断法を公開(国際画像機器展2013にて)
(11/13)  国際画像機器展2013に出展します
(10/14)  「画像処理のためのC#」はじめます。
(09/16)  【C#,VB.NET】高速描画コントロールをバージョンアップしました。
(09/04)  拡大鏡に輝度値表示、ルーラー機能を追加した個人ツールを公開
(08/05)  7月の拍手Top5
(07/06)  2013年6月人気記事Top5
(05/12)  SONY α NEX-5Rレビュー
(04/24)  SONY α NEX-5RY購入

【C++/CLI】Bitmapより画像のビット数を取得する

メインページC++/CLI プログラミング

BitmapをLockBit~UnlockBitsを使ってポインタで画像データを参照する時にはどうしても画像のビット数が欲しくなります。
PixelFormatを見て条件分けをしてもいいですが、直接取得出来るメソッドが

   System::Drawing::ImageクラスのGetPixelFormatSize

です。

【使用例】
Bitmap^ bmp = gcnew Bitmap("test.bmp")

int Bitcount = bmp->GetPixelFormatSize(bmp->PixelFormat);


Loading...
スポンサーリンク

スポンサーリンク 最近の記事
(09/18)  計測測定展に光切断のデモを出展しました
(08/17)  ディジタル画像技術事典200に記事が載りました
(06/09)  光切断を画像センシング展で公開
(05/14)  中国(上海)へ行って来ました
(04/12)  韓国へ行って来ました
(03/10)  私の求める新人像
(01/18)  エレクトロテストジャパンにカラー光切断法のデモを出展しました。
(12/23)  ユニークアクセス200万達成!
(12/10)  【カラー光切断法】YouTube動画まとめ
(11/04)  国際画像機器展2014にカラー光切断法を出展します。
(10/05)  第25回コンピュータビジョン勉強会@関東に参加してきました。
(09/08)  フーリエ変換の記事を追加しました。
(08/09)  【画像処理】ランキング低下中
(07/06)  記事の更新が停滞中...
(06/08)  画像センシング展2014でカラー光切断法のデモを行います。
(05/17)  カラー光切断法の動画を公開しました。
(04/30)  ソニーα NEX-5Rで星空撮影
(04/10)  カラー光切断法の取込結果を追加しました
(03/08)  Korea Vision Show 2014へ行ってきました
(02/05)  フーリエ変換シリーズを始めます。
(01/06)  2014年、あけましておめでとうございます。
(12/04)  カラー光切断法を公開(国際画像機器展2013にて)
(11/13)  国際画像機器展2013に出展します
(10/14)  「画像処理のためのC#」はじめます。
(09/16)  【C#,VB.NET】高速描画コントロールをバージョンアップしました。
(09/04)  拡大鏡に輝度値表示、ルーラー機能を追加した個人ツールを公開
(08/05)  7月の拍手Top5
(07/06)  2013年6月人気記事Top5
(05/12)  SONY α NEX-5Rレビュー
(04/24)  SONY α NEX-5RY購入

【C++/CLI】スクリーン座標、クライアント座標

メインページC++/CLI プログラミング

スクリーン座標とは、デスクトップ画面の左上を原点とした座標で、
クライアント座標とは、各コントロール(ボタンやラベルなど)の左上を原点とした座標を言います。

スクリーン座標、クライアント座標

各座標の取得、変換方法は以下のように行ないます。
以下の例はPictureBoxのMouseMouveイベントでのマウスポインタの位置を取得しています。

private: System::Void pictureBox1_MouseMove(System::Object^  sender,     System::Windows::Forms::MouseEventArgs^  e) {
                 
                 //クライアント座標の取得
                 label1->Text = "(X, Y) = ("
                     + e->X.ToString() + ", " + e->Y.ToString() + ")";

                 //スクリーン座標の取得(その1)
                 label2->Text = "(X, Y) = ("
                     + Cursor->Position.X.ToString() + ", " + Cursor->Position.Y.ToString() + ")";

                 //スクリーン座標の取得(その2)
                 label3->Text = "(X, Y) = ("
                     + MousePosition.X.ToString() + ", " + MousePosition.Y.ToString() + ")";
                 
                 //クライアント座標→スクリーン座標変換
                 Point ScreenPoint = pictureBox1->PointToScreen(Point(e->X, e->Y));
                 label4->Text = "(X, Y) = ("
                     + ScreenPoint.X.ToString() + ", " + ScreenPoint.Y.ToString() + ")";

                 //スクリーン座標→クライアント座標変換
                 Point ClientPoint = pictureBox1->PointToClient(Cursor->Position);
                 label5->Text = "(X, Y) = ("
                     + ClientPoint.X.ToString() + ", " + ClientPoint.Y.ToString() + ")";
             }

上記プログラムの実行例が以下の通りです。

スクリーン座標、クライアント座標

PointToScreenPointToClientメソッドを用いる事で、あるコントロールの座標が別のコントロールの座標から見ると、どのような座標になるのか?を求める事が可能となります。



Loading...
スポンサーリンク



現在の閲覧者数: / 合計