PHP,MySQL,Flex,JSな日々+イラストとか このページをアンテナに追加 RSSフィード Twitter

2014年05月07日

ちょっちブログへ移動しまーっす

なにやらブログへ簡単に移動できるってことで、そちらへ移動になりまーっす

今後はこちらへどぞー

http://mugimugi.hatenablog.com/

Android Studioで最速開発

ちょいとAndroid Studioで簡単開発をしてみました。

その際のインストールなどをメモ。

1.Android Studioのインストール

公式サイトより、Android Studioをダウンロードして、インストールを行う。

Getting Started with Android Studio | Android Developers

2.JDKのインストールと設定

Andorid StudioにはJDKが必要なのでダウンロードをしてインストールを行う。

Java SE - Downloads | Oracle Technology Network | Oracle

次に、Android StudioにJDKがどこにインストールされたかを知らせるためにマイコンピュータを右クリックして「システム詳細設定」の「環境変数」にJAVA_HOMEを追加設定する。

C:\Program Files\Java\jdk1.8.0_05

3.スマフォのドライバのインストール(実機でもデバッグしてみたい場合)

実機でデバッグを行いたい場合は、事前にドライバのインストールが必要になるので、ダウンロードしてインストールを行う。

LG LGL22 サポート : 製品に関する取扱説明書の検索 | LGエレクトロニクス・ジャパン

4.スマフォでデバッグする際の設定(実機でもデバッグしてみたい場合)

さらに、開発者向けオプションを有効にして、Android Studioからデバッグできる端末として、見えるようにする。

Android 4.2以降の端末で「開発者向けオプション」を表示させる方法 » 使い方・方法まとめサイト - usedoor

簡単に開発を始められるのでおすすめ。あとデザインモードもあるのでFlexユーザーにはとっつきやすいかなあって思います。

2014年03月10日

Windows8 64bit 、ruby 64bit において、mysql2をインストールする

Windows8 64bit 、ruby 64bit において、mysql2をインストールする際にエラーが出たのでメモ

結論としては、64bit の ruby ではなく 32bit で統一すればOK

インストール方法

mysql2 をインストールするには mysqlコネクタの32bit版 が必要なので、ダウンロードする。

ファイルをC:\などに解凍し、インストールする際に下記のように指定をする。

$ gem install mysql2 -- '--with-mysql-dir="C:\mysql-connector-c-6.1.3-win32"'

インストールが済んだら、C:\mysql-connector-c-6.1.3-win32\bin フォルダの libmysql.dll を C:\ruby\bin フォルダにコピーをする。

これで、rails s が起動するようになる。

自分は結構64bit版でなんとか粘ったものの、rails sでエラーが吐きまくったので、断念して、32bitで統一。

初心者は32bitでインストールしたほうがいいのかも。ちなみにMySQL自体は別に64bitでも問題ないみたい。

参考リンク

2014年02月21日

Windows8(64bit)にruby on rails をインストールする

Windows8(64bit)にruby on rails をインストールするにはいくつかファイルとコマンドが必要

Ruby 2.0.0-p353 (x64) を公式サイトからダウンロードし、インストールする

※インストールする際は、pathの追加にチェックを入れると、コマンドプロンプトのどこからでもrubyコマンドが呼び出せる

DevKit-mingw64-64-4.7.2-20130224-1432-sfx.exe を公式サイトからダウンロードし、実行→解凍をする

ファイルを「c:\Ruby200-x64\devkit」に配置

以下のコマンドをコマンドプロンプトより実行

rubyの更新

gem update --system

devkit の初期化とインストール

$ cd c:\Ruby200-x64\devkit
$ ruby dk.rb init;
$ ruby dk.rb install;

ruby on rails のインストール

$ gem install rails;

2013年10月27日

FileAPIを使って画像をアップする際はバイナリチェックも

FileAPIを使って画像をアップする際は、ファイルの拡張子を偽装してもアップできるので、バイナリチェックを行うほうがよりしっかりします。

JPEG画像をFileAPIを使ってアップすると、下記のようなbase64文字列を取得することができます。

data:image/jpeg;base64,/9j/4AAQSkZJRgABA....

画像ファイルの先頭バイトには、拡張子を判断するフラグが挿入されており、この/9j/がJPEGを表す文字列となります。

画像タイプバイナリbase64
jpegaa
pngaa
gifaa
アニメーションgifaa

作成中・・・

※PHP側で生データーを取得した際は、このヘッダーを見て画像形式を判断します。

そこで、ためしに、拡張子をJPEGと偽装した、ZIPファイルをFileAPIで上げてみたところ、

data:image/jpeg;base64,{ZIPファイルをbase64でエンコードしたもの}

となり、ブラウザはdata:image/jpegで扱おうとします。

base64には使用できる文字が限られているため、XSSなどはできませんが、思わぬトラブルが起きる可能性がありますので、バイナリチェックも入れておくと、余計なファイルがアップされなくて済みます。

サンプルソースはこちら

<!DOCTYPE html>
<html>
<head>
  <title></title>
  <input type="file" id="files" name="files[]" multiple />
  <script>
    function doFileSelect(evt) {
      var files = evt.target.files;
      for (var i = 0, file; file = files[i]; i++) {
        if (!file.type.match('image.*')) {
          continue;
        }
        var freader = new FileReader();
        freader.onload = (function(theFile) {
          return function(e) {
            if( ( e.target.result ).substr(5,10) == "image/jpeg" ){
              if( ( e.target.result ).substr(23,4) == "/9j/" ){
                alert("This is JPEG file !! ");
              }
            }
          };
        })(file);
        freader.readAsDataURL(file);
      }
    }
    document.getElementById('files').addEventListener('change', doFileSelect, false);
  </script>
</head>
<body>
</body>
</html>

参考リンク

2013年10月24日

SVGアニメーション

Adobeさんより、SVGライブラリが出ましたので、ちょっと試してみました♪

f:id:haru-komugi:20131024164206j:image

サンプルはこちら

※更新ボタンクリックでランダムに円が配置されます。

スマフォのChromeでも普通に再生されるからいいのかなあっと。

あとはCanvasと比べて、負荷がどうなるのかも気になるところです。

現状、一番高速なのはWebGLだと思います。

ソースコードはこちら

<!DOCTYPE html>
<html>
<head>
  <title></title>
  <script src="lib/snap.svg-min.js"></script>
  <script>
    window.onload = function () {
      //マイランダム関数
      var random = {};
      //最小値・最大値のランダム整数取得
      random.getNumber = function( minInt , maxInt ){
        return Math.floor( Math.random() * ( maxInt - minInt + 1 ) ) + minInt;
      };
      //ランダムカラー取得
      random.getColor = function(){
        return Math.floor(Math.random() * 0xFFFFFF).toString(16);
      };
      //メイン
      var main = {};
      //メイン初期化
      main.init = function(){
        //キャンバス作成
        var s = Snap(800,800);
        //ランダムで10個の円を作成
        for( var i = 0 ; i < 10 ; i ++ ){
          //x・y座標をランダム作成
          var nRandomIntX = random.getNumber( 1 , 800 );
          var nRandomIntY = random.getNumber( 1 , 800 );
          //円の作成
          var bigCircle = s.circle( nRandomIntX, nRandomIntY, 0 );
          //円の要素設定
          bigCircle.attr({
            fill:"#" + random.getColor(),
            stroke:"#" + random.getColor(),
            strokeWidth:5
          });
          //円のアニメーション設定
          bigCircle.animate({
              r: random.getNumber( 0 , 100 ),
              stroke:"#" + random.getColor(),
              fill:"#" + random.getColor()
            }
            ,random.getNumber( 1000 , 3000 )
            ,mina.bounce
          );
        }
      };
      //メインスタート
      main.init();
    }
  </script>
</head>
<body>
</body>
</html>

参考リンク

Snap.svg - Home

2013年06月30日

twitteroauthを使ってつぶやく+緯度経度情報付き

twitteroauthを使ってつぶやいてみました。

ソースコードはこちら

<?php
require_once("twitteroauth.php");
//アクセストークンなど
$consumer_key = "xxxxxxxxxxxxxxxxxxxx";
$consumer_secret =  "xxxxxxxxxxxxxxxxxxxx";
$access_token =  "xxxxxxxxxxxxxxxxxxxx";
$access_token_secret =  "xxxxxxxxxxxxxxxxxxxx";
//緯度経度を調べる(例:香港)
$address = "hongkong";
$address = urlencode( $address );
$url = "http://www.geocoding.jp/api/?v=1.1&q={$address}";
//緯度経度取得
$file = file_get_contents( $url );
$xml = new SimpleXMLElement($file);
$lat = (double) $xml->coordinate[0]->lat;
$lng = (double) $xml->coordinate[0]->lng;
//TwitterAPIへアクセス
$message = "香港なう";
$to = new TwitterOAuth($consumer_key,$consumer_secret,$access_token,$access_token_secret);
$params = array(
                "status"  => $message,
                'lat'      => $lat,
                'long'     => $lng
                );
$req = $to->OAuthRequest("https://api.twitter.com/1.1/statuses/update.json","POST", $params );
var_dump( $req );
exit;
?>

画像投稿もしてみたいのですが、これはちょっと難しそう。

参考リンク

2013年06月25日

郵便番号から住所検索

なにやら便利なjQueryプラグインが出ていたので使ってみました。

tkengo/jquery.ajaxzip2 · GitHub

f:id:haru-komugi:20130625102003j:image

住所データーのjsonファイルをダウンロードして、dataの場所を指定すればとりあえず、動くみたいです。

ソースコードはこちら

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=sjis" />
  <title>QUnit sample</title>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
  <script src="/pathto/jquery.ajaxzip2.js"></script>
<script>
$(function(){
  $("#search").bind( "click" , function(){
    $('#zip1, #zip2').zip2addr({
      path: '/pathto/data/', //住所データの場所
      pref: '#pref_id',
      city: '#city',
      area: '#area',
      street: '#street',
      success: function() {
        alert('onSuccess');
      },error: function() {
        alert('onError');
      }
    });
  });
});
</script>
</head>
<body>
<div>
<p>郵便番号</p>
<input type="text" name="zip1" id="zip1" value="871"/> - <input type="text" name="zip2" id="zip2" value="0029"/>
<input type="button" value="検索" id="search" />
</div>
<div>
<p>都道府県ID</p>
  <select name="pref_id" id="pref_id">
    <option value="1">北海道</option>
    <option value="2">青森県</option>
    <option value="3">岩手県</option>
    <option value="4">宮城県</option>
    <option value="5">秋田県</option>
    <option value="6">山形県</option>
    <option value="7">福島県</option>
    <option value="8">茨城県</option>
    <option value="9">栃木県</option>
    <option value="10">群馬県</option>
    <option value="11">埼玉県</option>
    <option value="12">千葉県</option>
    <option value="13">東京都</option>
    <option value="14">神奈川県</option>
    <option value="15">新潟県</option>
    <option value="16">富山県</option>
    <option value="17">石川県</option>
    <option value="18">福井県</option>
    <option value="19">山梨県</option>
    <option value="20">長野県</option>
    <option value="21">岐阜県</option>
    <option value="22">静岡県</option>
    <option value="23">愛知県</option>
    <option value="24">三重県</option>
    <option value="25">滋賀県</option>
    <option value="26">京都府</option>
    <option value="27">大阪府</option>
    <option value="28">兵庫県</option>
    <option value="29">奈良県</option>
    <option value="30">和歌山県</option>
    <option value="31">鳥取県</option>
    <option value="32">島根県</option>
    <option value="33">岡山県</option>
    <option value="34">広島県</option>
    <option value="35">山口県</option>
    <option value="36">徳島県</option>
    <option value="37">香川県</option>
    <option value="38">愛媛県</option>
    <option value="39">高知県</option>
    <option value="40">福岡県</option>
    <option value="41">佐賀県</option>
    <option value="42">長崎県</option>
    <option value="43">熊本県</option>
    <option value="44">大分県</option>
    <option value="45">宮崎県</option>
    <option value="46">鹿児島県</option>
    <option value="47">沖縄県</option>
  </select><br/>
</div>
<div>
<p>市区町村</p>
<input type="text" name="city" id="city" />
</div>
<div>
<p>町域</p>
<input type="text" name="area" id="area" />
</div>
<div>
<p>番地</p>
<input type="text" name="street" id="street" />
</div>
</body>
</html>

2013年06月19日

MySQLのgeometry型を使い、距離を出す

最近のMySQLは緯度経度が扱えるgeometry型がありますので、そちらを使い、2点間の距離を出してみました。

テーブル mygis の作成

気をつける点としては、ENGINEはMyISAM型がよいのと、最新のバージョンのMySQLでないとgeometry型は扱えないようです。

CREATE TABLE IF NOT EXISTS `mygis` (
  `id` int(11) NOT NULL,
  `geo` geometry NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

geometry型にデーターを挿入

GeomFromText と POINT を使うのがポイント

INSERT INTO mygis (
 id, geo
)values(
 '1', GeomFromText('POINT( 131.547546 33.229498 )')
);

福岡市(130.384369 33.590599)から、距離が近いもの順に表示

SELECT
 ROUND(
  GLENGTH(
    GEOMFROMTEXT( CONCAT( 'LineString( 130.384369 33.590599 , ', X( geo ) ,  ' ', Y( geo ) ,  ')' )
  )
 ) * 111000 ) AS distance
FROM
 mygis
ORDER BY
 distance

WHERE区で len <= 1000とすれば1km以内のデーターを表示できたります。

ちなみに、ガチな距離計算方法

select
 ((ACOS(SIN( 33.590599 * PI() / 180) * SIN( lat * PI() / 180) + COS( 33.590599 * PI() / 180)
* COS( lat * PI() / 180) * COS(( 130.384369 - lng ) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS distance
FROM
 mygis
ORDER BY
distance

ベンチマークを測ったところ、それほど、どちらも変わらない感じがしたので、精度やお好みで使うといいのかも

参考リンク

2013年06月17日

Googleマップの中心の緯度経度を表示する

ちょっと、古めの内容ですが、Googleマップの中心の緯度経度を表示してみました。

こんな感じで、ドラッグしても、センターの場所を教えてくれます。

f:id:haru-komugi:20130617214002j:image

ソースコードはこちらっ

<html xmlns="http//www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title></title>
  <script src="http://maps.google.com/maps?file=api&v=2&key=APIKEY&sensor=false" type="text/javascript"></script>
  <script type="text/javascript">
  function initialize() {
    if (GBrowserIsCompatible()) {
      //マップの初期化
      var map = new GMap2( document.getElementById("map") );
      var point = new GLatLng( 35 , 139 );
      console.log( point );
      map.setCenter( point , 18);
      map.addControl(  new GLargeMapControl(),
                       new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(5,30))
                     );
      map.addControl(new GMapTypeControl());
      map.addControl(new GScaleControl());
      //十字アイコン作成
      var icon        = new GIcon();
      icon.image      = "/image/top/gmap_cursor.gif";
      icon.iconSize   = new GSize(100, 100);
      icon.iconAnchor = new GPoint(50, 50);
      var marker      = new GMarker( point , icon );
      map.addOverlay(marker);
      //マップ移動イベント
      GEvent.addListener( map , "move" , function(){
        //現在の緯度経度を表示する
        showLatLon();
      });
      //十字アイコンが示す座標を表示
      showLatLon= function (){
        //マップの中央を取得
        var point = map.getCenter();
        //マーカーをセンターに配置する
        marker.setPoint( point );
        document.getElementById("latlon").innerHTML ="緯度:" + point.lng() + "<br />経度:" + point.lat();
      };
      showLatLon();
    }
  }
  </script>
</head>
<body onload="initialize()" onunload="GUnload()">
<div id="latlon" style="padding:10px;">
  緯度:読み込み中・・・<br>
  経度:読み込み中・・・
</div>
<div id="map" style="width:480px;height:480px;"></div>
</body>
</html>

参考リンク

2013年06月15日

画像選択後に自動でサーバーに画像をアップ

フォームにて、画像選択後に自動でサーバーに画像をアップすることができます。

ちなみにAndroidではカメラ画像でも撮影→サーバーアップが可能となっています。

ファイル送信側ソース

<html>
<head>
<script>
window.addEventListener("load", function(){
  if (!window.File){
    result.innerHTML = "File API 使用不可";
    return;
  }
  result.innerHTML = "画像を選択してください";
  document.getElementById("imageFile").addEventListener("change", function(){
    var reader = new FileReader();
    var file = document.getElementById("imageFile").files[0];
    result.innerHTML = "画像の設定を設定しています・・・";
    reader.onload = function(event){
      document.getElementById("img").src = reader.result;
      var file = document.getElementById("imageFile").files[0];
      var fileName = file.name;
      var fileSize = file.size;
      result.innerHTML = '【画像情報】<br/>ファイル名:' + file.name + '<br />' + '種類: ' + file.type + '<br />' + 'サイズ: ' + file.size + '<br />';
      $.ajax({
        type: 'POST',
        url: 'upload.php',
        data: {photo{$id}: event.target.result},
        success: function(){
          result.innerHTML = "画像の設定が完了しました!";
        },
        error: function(a, b, c){
          result.innerHTML = 'ファイルのアップロードに失敗しました。';
          console.log(a, b, c);
        }
      });
    }
  reader.readAsDataURL(file);
  } , true );
} , true );
</script>
</head>
<body>
<h2>画像ファイルで更新</h2>
<form>
  <input type="file" accept="image/*;capture=camera" id="imageFile"/>
</form>
<div id="result"></div>
<img id="img"width="100%">
</body>
</html>

受け取るPHP側ソース

<?php
//POSTデーターの中にbase64で送られるのでPHPがデコードできるように修正
$from_arr = array( " " , "data:image/png;base64," , "data:image/jpg;base64," , "data:image/jpeg;base64," , "data:image/gif;base64," );
$to_arr   = array( "+" , "" , "" , "" , "" );
//base64からバイナリ画像に変換
$photo    = base64_decode( str_replace( $from_arr , $to_arr , $_POST[ $photoname ] ) );
//先頭8文字からファイルの拡張子を判定する
$head = substr( $photo , 0 , 8 );
if (strncmp("\x89PNG\x0d\x0a\x1a\x0a", $head, 8) == 0) {
  $ext = ".png";
} else if (strncmp('BM', $head, 2) == 0) {
  $ext = ".bmp";
} else if (strncmp('GIF87a', $head, 6) == 0 || strncmp('GIF89a', $head, 6) == 0) {
  $ext = ".gif";
} else if (strncmp("\xff\xd8", $head, 2) == 0) {
  $ext = ".jpg";
} else {
  echo "拡張子が見つかりません";
  exit;
}
//ファイル出力
file_put_contents( "uploadedimage{$ext}" , $photo );
?>