Robinit

IT関連メモ

nodistでNode.jsをVersion管理する(Windows)

nodistのインストール

nodistはNode.jsをVersion管理できるツール

nodistのインストーラを以下よりダウンロードする
github.com

現時点の最新であるv0.8.8を選択しダウンロードしインストールする
今回は特に初期設定のまま変更せずにインストールした

コマンドプロンプトを開き、node -v を実行しインストールしたVersionが表示されればOK
f:id:wonder_three:20180210154358p:plain

nodistの使い方

nodistのアップデート

nodistのアップデートを実行、更新があればアップデートされる

C:\WINDOWS\system32>nodist selfupdate
現在取得したNode.jsのVesionと指定しているVersionの確認

現在取得したNode.jsのVesionと指定しているVersionの確認
以下はv9.5.0が指定されていることがわかる

C:\WINDOWS\system32>nodist
  (x64)
  8.8.1
  8.9.4
> 9.5.0  (global: 9.5.0)
nodistでインストール可能なNode.jsのバージョンを表示

nodistでインストール可能なNode.jsのバージョンを表示

C:\WINDOWS\system32>nodist dist
   :
  9.3.0
  9.4.0
  9.5.0
nodistでVesionを指定しNode.jsをインストール

nodistで例えばv9.3.0を指定しNode.jsをインストールする

C:\WINDOWS\system32>nodist + v9.3.0
 9.3.0 [===============] 21825/21825 KiB 100% 0.0s
9.3.0
nodistでNode.jsのバージョンを切り替え

nodistでNode.jsをv9.3.0に切り替える

C:\WINDOWS\system32>nodist 9.3.0
9.3.0
Default global pacakge update dsuccessful.
WindowsのNode.jsのバージョンを確認

Node.jsのVersionを確認する

C:\WINDOWS\system32>node -v
v9.3.0

Node.jaのVersionが切り替わらない場合

今回、nodistでNode.jsのインストールはうまくいくけど、
Node.jsのVersion切り替えに失敗するという現象に陥った。。
調べていると、元々Node.jsをインストールしていた後にnodistをインストールすると、
うまく切り替えられないみたい。
その場合は、もともと入っているNode.jsをアンインストールすればOK

郵便番号検索 Webアプリを作る(2)

郵便番号検索 Webアプリを作る(1)の続き
ソースコードの各処理の内容をみていく

HTML Head

<meta charset=" ">

について、「charset属性」は、HTML5から単独で使えるようになった属性
文字コードは、「Shift_JIS」「UTF-8」などがありますが、HTML5から、UTF-8 を使用することが推奨されている
理由はWin、MacLinuxUnix、どんな OSでもOKなのと、
2バイト文字(漢字や仮名などの日本語・中国語・ハングル・アラビア語など)も含めた、世界中の言語の文字を表示できるから

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

でbootstrapのCSSを指定し読み込む

<style type="text/css">

以降で、HTML文書にCSSを適用する

<head>
    <meta charset="UTF-8">
    <title>郵便番号検索</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <style type="text/css">
        .container {
            text-align: center;
            margin-top: 100px;
            width: 450px;
        }
        .result {
            margin-top: 20px;
        }
    </style>
</head>

HTML Body

Bootstrapで基本的なformを作るために

<div class="form-group">

<input type~  class="form-control" 

を指定し、レイアウトを利用する

    <div class="container">
        <h1>郵便番号検索</h1>
        <div class="form-group">
            <label for="exampleInputText">住所を入力してください</label>
            <input type="text" id="city" class="form-control" placeholder="ex. 大阪府大阪市北区小松原町">
        </div>
        <button class="btn btn-primary" id="btn">検索</button>
        <div class="result" id="str"></div>
    </div>

Google Maps Geocoding API

検索ボタンが押下されたら、
入力された住所の郵便番号を取得する処理を行う
郵便番号の取得には、Google Maps Geocoding API を利用する。

事前準備として以下サイトでAPI Keyを取得する。
developers.google.com

キーの取得のページに遷移する
f:id:wonder_three:20180208002243p:plain

API Keyを取得したらメモする

次に住所から郵便番号を取得するために以下のAPIを使う
https://maps.googleapis.com/maps/api/geocode/json?address=[住所]&key=[取得したAPI Key]

例えば、住所に「千代田区千代田」を入れてAPIを実行
[https://maps.googleapis.com/maps/api/geocode/json?address=千代田区千代田&key=[取得したAPI Key]

結果として以下のJSONが取得できる

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "千代田",
               "short_name" : "千代田",
               "types" : [ "political", "sublocality", "sublocality_level_2" ]
            },
            {
               "long_name" : "",
               "short_name" : "",
               "types" : [ "political", "sublocality", "sublocality_level_4" ]
            },
            {
               "long_name" : "千代田区",
               "short_name" : "千代田区",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "東京都",
               "short_name" : "東京都",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "日本",
               "short_name" : "JP",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "100-0001",
               "short_name" : "100-0001",
               "types" : [ "postal_code" ]
            }
         ],
         "formatted_address" : "日本、〒100-0001 東京都千代田区千代田1",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 35.6905143,
                  "lng" : 139.7614146
               },
               "southwest" : {
                  "lat" : 35.6773769,
                  "lng" : 139.7443137
               }
            },
            "location" : {
               "lat" : 35.6838012,
               "lng" : 139.7539454
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 35.6905143,
                  "lng" : 139.7614146
               },
               "southwest" : {
                  "lat" : 35.6773769,
                  "lng" : 139.7443137
               }
            }
         },
         "place_id" : "ChIJ4bzvNguMGGARUXRpAo8Oi6s",
         "types" : [ "political", "sublocality", "sublocality_level_2" ]
      }
   ],
   "status" : "OK"
}

取得した値のそれぞれの値はデベロッパー ガイドを参考にすればよいが、
今回は郵便番号なので、"postal_code"を利用する

入力された住所から郵便番号を取得し結果を表示する

jQueryAJAXメソッドを使って「Google Maps Geocoding API」をよびだすので、
jQueryのライブラリを読み込む

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

以下で検索ボタンがクリックされたときのイベント処理を実装する

    <script type="application/javascript">
        var postalCode = "";
        var btn = document.getElementById('btn');
        btn.addEventListener('click', function() {

住所が入力されていなければalert()で警告表示し結果表示部分にも、
「郵便番号が見つかりません。」という文言を表示する。
その際、Bootstrapのalertsのレイアウトを使って表示する
Alerts · Bootstrap

            var city = document.getElementById('city');
            if (city.value == "") {
                alert("住所を入力してください");
                document.getElementById("str").innerHTML = "<div class=\"alert alert-primary\" role=\"alert\">郵便番号が見つかりません。</div>";

Google Maps Geocoding APIの第1引数 addressに入力された住所、第2引数に取得したAPI Keyを指定し、
ajaxメソッドを利用してAPIをよび出す

APIの呼び出しが成功すれば、
$.each()をつかい、取得したデータにpostal_codeがないか?検索する
postal_codeがあれば、郵便番号を表示する

            } else {
                const API_KEY = xxxxxxxxxxx; //個人のAPI key
                var url = "https://maps.googleapis.com/maps/api/geocode/json?address=" + city.value + "&key=" + API_KEY;
                $.ajax({
                    url: url,
                    type: "GET",
                    success: function(data) {
                        postalCode = "";
                        $.each(data['results'][0]['address_components'], function(key, value) {
                            if (value["types"][0] == "postal_code") {
                                postalCode = value["long_name"];
                            }
                        })
                        if (postalCode) {
                            document.getElementById("str").innerHTML = "<div class=\"alert alert-primary\" role=\"alert\">郵便番号は、" + postalCode + "です。</div>";
                        } else {
                            document.getElementById("str").innerHTML = "<div class=\"alert alert-primary\" role=\"alert\">郵便番号が見つかりません。</div>";
                        }
                    }
                })
            }
        })
    </script>

※$.each() は配列やハッシュに対して繰り返し処理を行うことができる
$.each() は以下のように記述する。

$.each(対象のオブジェクト, function(index, val) {
  繰り返し実行する処理
});)

配列 array に対して繰り返し処理を行う場合は、以下のように記載する。

array = ["Apple", "Orange", "Grape"];
$.each(array, function(index, val) {
  $('ul').append("<li>" + index + ":" + val + "</li>");
});

郵便番号検索 Webアプリを作る(1)

初めてのWebアプリを作ってみる。
ということで、住所を入力すれば郵便番号を表示するアプリを作成する

以下イメージです。
f:id:wonder_three:20180204220921p:plain

住所を入力を入力すると、郵便番号を表示してくれる簡単なWebアプリ。
f:id:wonder_three:20180204221346p:plain

開発技術

HTML + JavaScript で実装
郵便番号の取得は、Google Maps Geocoding APIjQueryで呼び出す
デザインはBootStrapを活用

ソースコード

先にソースコードを記載する。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>郵便番号検索</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <style type="text/css">
        .container {
            text-align: center;
            margin-top: 100px;
            width: 450px;
        }
        .result {
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>郵便番号検索</h1>
        <div class="form-group">
            <label for="exampleInputText">住所を入力してください</label>
            <input type="text" id="city" class="form-control" placeholder="ex. 大阪府大阪市北区小松原町">
        </div>
        <button class="btn btn-primary" id="btn">検索</button>
        <div class="result" id="str"></div>
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script type="application/javascript">
        var postalCode = "";
        var btn = document.getElementById('btn');
        btn.addEventListener('click', function() {
            var city = document.getElementById('city');
            if (city.value == "") {
                alert("住所を入力してください");
                document.getElementById("str").innerHTML = "<div class=\"alert alert-primary\" role=\"alert\">郵便番号が見つかりません。</div>";
            } else {
                const API_KEY = xxxxxxxxxxx; //個人のAPI key
                var url = "https://maps.googleapis.com/maps/api/geocode/json?address=" + city.value + "&key=" + API_KEY;
                $.ajax({
                    url: url,
                    type: "GET",
                    success: function(data) {
                        //console.log(data);
                        postalCode = "";
                        $.each(data['results'][0]['address_components'], function(key, value) {
                            if (value["types"][0] == "postal_code") {
                                postalCode = value["long_name"];
                            }
                        })
                        if (postalCode) {
                            document.getElementById("str").innerHTML = "<div class=\"alert alert-primary\" role=\"alert\">郵便番号は、" + postalCode + "です。</div>";
                        } else {
                            document.getElementById("str").innerHTML = "<div class=\"alert alert-primary\" role=\"alert\">郵便番号が見つかりません。</div>";
                        }
                    }
                })
            }
        })
    </script>
</body>
</html>

内容の詳細は次回に記載する。

PHPで天気情報APIのOpenWeatherMapを使う

ユーザが都市名を入力すると天気情報APIのOpenWeatherMapを使い、
現在の天気を表示するWebアプリをPHPで作成する。
f:id:wonder_three:20180203234119p:plain

はじめに

天気情報を取得するためにOpenWeatherMapのAPIを利用するが、
利用するにはユーザ登録が必要。

OpenWeatherMapにアクセスし、ユーザー登録を行う
openweathermap.org

ユーザ登録すれば、APIを利用するのに必要な、
API Keyが発行されるので、それをメモしておく。

コード

先にコードを記載する。

<?php
        $weather = "";
        if (array_key_exists('city', $_GET)) {
            $urlContents = file_get_contents("http://api.openweathermap.org/data/2.5/weather?q=".$_GET['city']."&appid=XXXXXXXXXXXXXXXXXXXXXXXXX");    //appidにはAPI Keyを入れる
            
            $weatherArray = json_decode($urlContents, true);    //連想配列の場合は第2引数へtrueを指定
            //print_r($weatherArray);
            $weather = $_GET['city']."'s Weather:".$weatherArray['weather'][0]['main'].",".$weatherArray['weather'][0]['description'];
        }
?>
    <h1>What's The Weather?</h1>
    <form>
        <label for="city">Enter the name of a city.</label>
        <input type="text" class="form-control" name="city" id="city" placeholder="Eg. London, Tokyo" value="<?php if (array_key_exists('city', $_GET)) {
                echo $_GET['city']; }?>">
        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
    <?php 
        if ($weather) {
              echo '<div class="alert alert-success" role="alert">'.$weather.'</div>';
        }
    ?>

天気情報APIのOpenWeatherMapを使う

今回は簡単に実装するため、file_get_contents()にAPIを渡す
appidにはユーザ登録で取得したAPI Keyを渡す
※file_get_contents()にAPIを渡す場合、
 タイムアウトが設定通り動かない、リクエストが失敗した場合は、過去の成功したヘッダ情報を返してしまう
 などの問題があるので注意が必要。

$urlContents = file_get_contents("http://api.openweathermap.org/data/2.5/weather?q=".$_GET['city']."&appid=XXXXXXXXXXXXXXXXXXXXXXXXX"); 

次に返ってきたJSONjson_decode()を使い配列に入れてユーザに通知する。

$weatherArray = json_decode($urlContents, true); 

今回は現在の天気とその詳細を表示するだけですが、
返ってきたJSONの中に最高/最低気温や湿度などの情報もある
また5日間の天気予報情報を取得できるAPIもあるので、色々と使ってみたい。

PHP+MySQLで簡単なログインフォームを作成する

PHP+MySQLで簡単なログインフォームを作成する。

f:id:wonder_three:20180131232324p:plain

ログインフォームにメールアドレスとパスワードを入力して、
f:id:wonder_three:20180131232444p:plain

登録ボタンを押下するとMySQLのDBにデータが登録される簡単なWebアプリ
f:id:wonder_three:20180131232601p:plain

開発言語:PHP
環境:MAMPApacheMySQL

MySQLのデータベースを追加する

phpMyAdminにアクセスする
以下にデータベース名を入力して[作成]ボタンを押下する
f:id:wonder_three:20180131234136p:plain

作成したデータベースにテーブルを追加する
今回はusersというテーブル名でカラムはEmail、Password、Nameとするので3を入力します。
f:id:wonder_three:20180131234242p:plain

次に挿入タブから3つほどデータを追加しておく
今回は以下のデータを用意した
f:id:wonder_three:20180131235044p:plain

ソースコード

先にソースコードを以下に記載する

<?php
    // データーベースへ接続
    $link = mysqli_connect("localhost","root","root","MemberApp");
    
    // 接続に失敗すれば強制終了
    if(mysqli_connect_error()){
        die("Failed Connect DB.");
    }
    //データが入力されているかどうかチェックする
    if(array_key_exists('email',$_POST) OR array_key_exists('password', $_POST))
    {
        if($_POST['email'] == ''){
            echo "Emailアドレスを入力してください";
        }
        elseif($_POST['password']==''){
            echo "Passwordを入力してください";
        }
        else{
            //メールアドレスが既に使用されていないかチェックする
            $query = "SELECT `id` FROM `users` WHERE email = '".mysqli_real_escape_string($link,$_POST['email'])."'";
            $result = mysqli_query($link,$query);
            if(mysqli_num_rows($result) > 0){
                echo "既にそのメールアドレスは使用されています。";
            }else{
                //未使用の場合、データベースに登録する
                $query = "INSERT INTO `users` (`email`,`password`) VALUES('"
                    .mysqli_real_escape_string($link,$_POST['email'])
                    ."','"
                    .mysqli_real_escape_string($link,$_POST['password'])
                    ."')";
                if(mysqli_query($link,$query)){
                    echo "登録が成功しました。";
                } else{
                    echo "登録が失敗しました";
                }
            }
        }
    }
?>
<!DOCTYPE html>
<form method="post">
    <input type="text" name="email" placeholder="Email">
    <input type="password" name="password" placeholder="password">
    <input type="submit" value="登録する">
</form>

データーベースへ接続

mysqli_connect()を使ってデータベースへ接続

    $link = mysqli_connect("localhost","root","root","MemberApp");

第1引数はMySQL サーバーのホスト名もしくはIPアドレス
第2引数はMySQLのユーザー名
第3引数はMySQLのパスワード
第4引数はクエリが行われるデフォルトのデータベース

詳細は以下
PHP: mysqli::__construct - Manual

mysqli_connect_error() で""以外が返ってきた場合、
接続に失敗したとみなし、die()で強制終了する

    if(mysqli_connect_error()){
        die("Failed Connect DB.");
    }

データが入力されているかどうかチェックする

array_key_exists()でPOSTで受け取ったデータに
'email'もしくは'password'が入っていなければ、エラー表示を行う。

    if(array_key_exists('email',$_POST) OR array_key_exists('password', $_POST))
    {
        if($_POST['email'] == ''){
            echo "Emailアドレスを入力してください";
        }
        elseif($_POST['password']==''){
            echo "Passwordを入力してください";
        }

メールアドレスが既に使用されていないかチェックする

初めに作成したusersテーブルからSELECT文を使い、
入力されたemailがデータベースに登録済みかどうか判定する

            //メールアドレスが既に使用されていないかチェックする
            $query = "SELECT `id` FROM `users` WHERE email = '".mysqli_real_escape_string($link,$_POST['email'])."'";
            $result = mysqli_query($link,$query);
            if(mysqli_num_rows($result) > 0){
                echo "既にそのメールアドレスは使用されています。";
            }else{

mysqli_query()でデータベース上でクエリを実行する。
第1引数は、mysqli_connect() で取得したリンクID
第2引数は実行するクエリ、今回はSELECT文
PHP: mysqli::query - Manual

mysqli_real_escape_string()は、
接続の現在の文字セットを考慮して、SQL 文で使用する文字列の 特殊文字エスケープする 関数
例えば名前に'が入っている場合は、そのまま渡すとクエリの実行に失敗するので、
この関数で特殊文字エスケープしておく

mysqli_num_rows()で取得した結果が何個あるか?を取得する。
今回は入力したemailとデータベースに登録されているemailが一致しなければ、
未登録のemailと判断して次に進む

データベースに登録する

INSERT文で入力されたemailとpasswordをデータベースへ登録する。
mysqli_query()が成功すれば登録されたと判断し echo でその旨ユーザに通知する

$query = "INSERT INTO `users` (`email`,`password`) VALUES('"
    .mysqli_real_escape_string($link,$_POST['email'])
    ."','"
    .mysqli_real_escape_string($link,$_POST['password'])
    ."')";
if(mysqli_query($link,$query)){
    echo "登録が成功しました。";
} else{
    echo "登録が失敗しました";

OpenCVでヒストグラム計算する

OpenCVを利用しヒストグラム計算する

以下のように、Webカメラで取得した画像にヒストグラムのグラフを重ねて表示するアプリを作成する。
f:id:wonder_three:20180127231011p:plain

開発環境の構築は以下参照。
OS:Windows
言語:C++
IDE:Visual Stdio2015
robinit.hatenablog.com

ヒストグラムとは??

画像処理の分野では、各濃度値に対してその濃度値を持った画素数を求めたもので、
濃度ヒストグラムまたは単純にヒストグラムという。
詳細は以下参照
http://izumi-math.jp/sanae/inf_box/histgram/histgram.htm

ヒストグラム比較による近似確認や濃度変換など、
ヒストグラムは画像処理で様々なケースで利用される。

ヒストグラムは主に横軸が濃度値、縦軸に画素数をとったグラフで表現される

カメラ画像取得

VideoCapture cap(0) でカメラをオープン。引数の"0"はデフォルトのカメラを意味する。
2台目のカメラを接続しオープンする場合は、"1"を指定する。

VideoCapture::isOpened() でカメラがオープンされたかチェック

cap >> frame で現在のフレームをcv::Matに取得。

VideoCapture cap(0); // デフォルトカメラをオープン					
if (!cap.isOpened())  // 成功したかどうかをチェック					
	return -1;
do {
	cap >> frame;	 // カメラから新しいフレームを取得
} while (frame.empty());

グレースケール化

ヒストグラムの計算に使用する画像はグレイスケール化が必要
OpenCVの cv::cvtColor を利用してグレースケール化する

Mat gray;
cvtColor(frame, gray, CV_BGR2GRAY);

ヒストグラム計算

以下のようにOpenCVの cv::calcHist を利用してヒストグラムを求め、
ヒストグラムのグラフ画像を作成する

// ヒストグラムを描画する画像割り当て					
const int ch_width = 256, ch_height = 128;
Mat hist_img(Size(ch_width, ch_height), CV_8UC3, Scalar::all(255));

const int hdims[] = { 256 }; // 次元毎のヒストグラムサイズ					
const float hranges[] = { 0,256 };
const float* ranges[] = { hranges }; // 次元毎のビンの下限上限					
double max_val = .0;

// シングルチャンネルのヒストグラム計算					
// 画像(複数可),画像枚数,計算するチャンネル,マスク,ヒストグラム(出力),					
// ヒストグラムの次元,ヒストグラムビンの下限上限					
calcHist(&gray, 1, 0, Mat(), hist, 1, hdims, ranges);

// 最大値の計算					
minMaxLoc(hist, 0, &max_val);

// ヒストグラムのスケーリング					
hist = hist * (max_val ? ch_height / max_val : 0.);
for (int j = 0; j < hdims[0]; ++j) {
	int bin_w = saturate_cast<int>((double)ch_width / hdims[0]);
	rectangle(hist_img, Point(j * bin_w, hist_img.rows), Point((j + 1) * bin_w, hist_img.rows - saturate_cast<int>(hist.at<float>(j))), Scalar::all(128),-1);
}
// ヒストグラム画像のROI表示重ね合わせ					
Mat roi_img(targetImg, Rect(20, targetImg.rows - hist_img.rows - 20, ch_width, ch_height));
hist_img.copyTo(roi_img);

サンプル実装

以下サンプル実装

#include "opencv2/opencv.hpp"						

using namespace cv;

/*
 ヒストグラムを計算し、ヒストグラムのグラフを描画する
 第一引数: gray ヒストグラムを計算するグレイスケール画像 (in)
 第二引数: targetImg グラフを重畳する画像 (inout)
 第三引数: hist ヒストグラムの計算結果 (out)
*/
void drawHist(const Mat& gray, Mat& targetImg, Mat& hist) {

	// ヒストグラムを描画する画像割り当て					
	const int ch_width = 256, ch_height = 128;
	Mat hist_img(Size(ch_width, ch_height), CV_8UC3, Scalar::all(255));

	const int hdims[] = { 256 }; // 次元毎のヒストグラムサイズ					
	const float hranges[] = { 0,256 };
	const float* ranges[] = { hranges }; // 次元毎のビンの下限上限					
	double max_val = .0;

	// シングルチャンネルのヒストグラム計算					
	// 画像(複数可),画像枚数,計算するチャンネル,マスク,ヒストグラム(出力),					
	// ヒストグラムの次元,ヒストグラムビンの下限上限					
	calcHist(&gray, 1, 0, Mat(), hist, 1, hdims, ranges);

	// 最大値の計算					
	minMaxLoc(hist, 0, &max_val);

	// ヒストグラムのスケーリング					
	hist = hist * (max_val ? ch_height / max_val : 0.);
	for (int j = 0; j < hdims[0]; ++j) {
		int bin_w = saturate_cast<int>((double)ch_width / hdims[0]);
		rectangle(hist_img, Point(j * bin_w, hist_img.rows), Point((j + 1) * bin_w, hist_img.rows - saturate_cast<int>(hist.at<float>(j))), Scalar::all(128), -1);
	}

	// ヒストグラム画像のROI表示重ね合わせ					
	Mat roi_img(targetImg, Rect(20, targetImg.rows - hist_img.rows - 20, ch_width, ch_height));
	hist_img.copyTo(roi_img);

}

int main()
{
	VideoCapture cap(0); // デフォルトカメラをオープン					
	if (!cap.isOpened())  // 成功したかどうかをチェック					
		return -1;

	Mat frame;
	while (1) {
		do {
			cap >> frame;	 // カメラから新しいフレームを取得
		} while (frame.empty());

		// frame画像対象の処理				
		// グレースケール画像に変換				
		Mat gray;
		cvtColor(frame, gray, CV_BGR2GRAY);

		// ヒストグラム計算
		Mat hist;
		drawHist(gray, frame, hist);

		imshow("CatImg", frame);

		int keyVal = waitKey(30);
		if (keyVal == 27) { // Escキー				
			break;
		}
	}
	return 0;
}

PHP 基礎2

GETメソッドの引数を受け取る方法

例えば、URLに以下のような引数をセットしGETメソッドを発行する。

http://localhost:8080/index.php?name=kawa&gender=man&kimi=sugoi 

? 以降が、引数になる。&で各引数をで区切って記述する。
PHPでGETの引数を利用する方法は以下のように記述する。

<?php
print_r($_GET);    //引数すべてを標準出力
echo $_GET['name'];
echo $_GET['gender'];
?>

例えば、フォームから引数を設定する場合、以下のように記述する。

<?php
print_r($_GET);
echo $_GET['name'];
echo $_GET['gender'];
?>

<form>
    <input type="text" name="name">
    <input type="checkbox" name="gender" value="man">man
    <input type="checkbox" name="gender" value="woman">woman
    <input type="submit" value="send">
</form>

POSTメソッドの引数を受け取る方法

POSTメソッドの引数を受け取るサンプル実装
ユーザが名前を入力すれば、”Hello 名前” という文字が表示される。

<?php
    if($_POST){
        echo "Hello ".$_POST['name'];
    }
?>

<form method="post">
    <input type="text" name="name">
    <input type="submit" value="send">
</form>

Emailを送信する方法

mail()メソッドを利用してメールを送信する
mail()メソッドの詳細は以下参照。
PHP: mail - Manual

サンプル実装は以下のとおり。

<?php
$emaitTo = "test@test.com";
$subject = "Test Subject";
$body = "Test Body";
$headers = "";

if(mail($emailTo, $subject, $body, $headers)){
    echo "Email Success";
} else {
    echo "Email Faild";
}
?>

実行して以下のようなエラーが発生した場合、
f:id:wonder_three:20180127141916p:plain
送信元メールアドレスのFromが指定していないことが原因。

php.ini の

; For Win32 only.
;sendmail_from = me@example.com

の部分を、

; For Win32 only.
sendmail_from = 利用するメールアドレス

に更新すること。