キリンを召還するブログ。

Unity,OpenCVとRaspberryの事とか書くと思います。普段はiOSとかAndroidの枯れたアプリ技術を中心にやってます。なので、たまに失敗メモとして日常のハマった事とかも書きます。センサーも好きです。

【OpenCV】OpenCVで画像2値化(エッジ抽出)サンプルを試してみた

OpenCVを使ってやってみたかった事の一つに画像の二値化(エッジ抽出)があってそのサンプルを入手して試してみました。二値化って僕も専門外なので最近知ったのですがある決まった値(閾値)を元にその上か下かで分けてしまうという、白黒はっきりさせます的な処理です。
これをやるとどんな画像が出来るのかというと、こんな感じになります。
f:id:jkawasaki:20140105221516p:plain

では、中身を見てみましょう。
■サンプルコード

#include <iostream>
#include <opencv2/opencv.hpp>

#define IMAGE(x, y) img.at<float>(y, x)
#define	THRESHOLD	85		// 閾値

void Thinning(cv::Mat &img)
{
    const int width = img.cols;
    const int height = img.rows;
    cv::rectangle(img, cv::Point(0, 0), cv::Point(width - 1, height - 1),
                  CV_RGB(0, 0, 0));
    cv::Mat four_neighbor = cv::getStructuringElement(cv::MORPH_CROSS,
                                                      cv::Size(3, 3));
    
    int step = 0;
    while (1) {
        step++;
        cv::Mat candidate = img.clone();
        cv::erode(candidate, candidate, four_neighbor);
        candidate = img - candidate;
        
        int	num_delete = 0;
        for (int y = 1; y < height - 1; y++) {
            for (int x = 1; x < width - 1; x++) {
                if (candidate.at<uchar>(y, x) == 0) {
                    continue;	                }
 
                int dx[8] = {1,  1,  0, -1, -1, -1,  0,  1};
                int dy[8] = {0, -1, -1, -1,  0,  1,  1,  1};
                unsigned char n[8];
                int num = 0;
                for (int i = 0; i < 8; i++) {
                    n[i] = img.at<uchar>(y + dy[i], x + dx[i]) ? 1 : 0;
                    num += n[i];
                }
                if (num < 3) {
                    continue;
                }
                //連結数の確認
                int m = 0;
                for (int i = 0; i < 4; i++) {
                    int k0 = i * 2;
                    int k1 = (k0 + 1) % 8;
                    int k2 = (k1 + 1) % 8;
                    m += n[k0] * (1 - n[k1] * n[k2]);
                }
                if (m == 1) {
                    img.at<uchar>(y, x) = 0;
                    num_delete++;
                }
            }
        }
        // 終了判定
        if (num_delete == 0) {
            break;
        }
    }
}
int main(int argc, char **argv)
{
    char *window_capture = "capture";
    cv::namedWindow(window_capture, CV_WINDOW_AUTOSIZE);
    char *window_output = "output";
    cv::namedWindow(window_output, CV_WINDOW_AUTOSIZE);
	
    cv::VideoCapture cap;
    cap.open(0);
    if (!cap.isOpened()) {
        std::cerr << "cannot find camera or file" << std::endl;
        return -1;
    }
    while (1) {
        cv::Mat frame;
        cap >> frame;
        
        cv::Mat gray, sobel, edge, edge_x, edge_y, result;
        cv::cvtColor(frame, gray, CV_BGR2GRAY);
        cv::Sobel(gray, sobel, CV_16S, 1, 0, 3);
        cv::convertScaleAbs(sobel, edge_x);
        cv::Sobel(gray, sobel, CV_16S, 0, 1, 3);
        cv::convertScaleAbs(sobel, edge_y);
        edge = edge_x + edge_y;
        cv::threshold(edge, result, THRESHOLD, 255, CV_THRESH_TOZERO);
        
        Thinning(result);
        cv::imshow(window_capture, frame);
        cv::imshow(window_output, result);
        
        int key = cv::waitKey(5);
        if (key == 3 || key == 27 || key == 'q') {
            break;
        }
    }   
    return 0;
}

今回はちょっとサンプルを変更して閾値として定義している値をTHRESHOLDを85にしてみました。
ちょうど半分だと白の割合が多くなっちゃったので。
色味についてはcvtColorの引数になっているCV_BGR2GRAYを変更すると代わりますが、そもそもRGBとかになってしまうと二値じゃなくなるので今回はCV_BGR2GRAYだけで試します。閾値も85のまま設定だけ変更してみます。

それ以外にthreshold関数の引数を変更する事で風合いが変わります。設定出来るパラメータと内容は下記の通りです。
————————
THRESH_BINARY : 閾値を超えるピクセルは MAXに,それ以外のピクセルは 0 になります.
THRESH_BINARY_INV : 閾値を超えるピクセルは 0 に,それ以外のピクセルは MAXになります.
THRESH_TRUNC : 閾値を超えるピクセルは threshold に,それ以外のピクセルは変更されません.
THRESH_TOZERO : 閾値を超えるピクセルは変更されず,それ以外のピクセルは 0 になります.
THRESH_TOZERO_INV : 閾値を超えるピクセルは 0 に,それ以外のピクセルは変更されません.
————————

実際に試すとこんな感じ。
f:id:jkawasaki:20140105220846p:plain

画像自体がちょっと怖めになったり、カメラ画像そのまま映すと動きがヌルヌルして見えるのでなんだか色々使い道があるような気がします。
静止画だと伝わらない気がしたので今回は動画をUPしてみました。

設定によってはレンダリングに時間がかかってカクついたりしてしまうのが難点です。
プログラム自体はシンプルなものですが使い方次第では色々使えるような気がしてます。

ただ、白黒反転したかったけどまだやり方分かんないので引き続きOpenCV、修行します。

【OpenCV】OpenCV2.4.7をMacにインストールしてサンプルを動かしてみる

OpenCVを始めるにあたってインストールと動作確認までが無知だと結構厳しい感じだったので噛み砕いた内容を一応書いておこうと思います。備忘録てきに。

最初はOpenCVを適当にインストールしときゃ良いんでしょくらいに考えていてWindowsでチャレンジしたら環境変数とかが結構面倒で、しかも僕の環境はWindows8.1+VisualStudio2013なので何かうまく行かずにとりあえず断念。今回入れたのはOpenCV 2.4.7でMac(OS X 10.9)とXcode5.0.2を使ってます。

1.準備

まず準備ですがMacにXcodeが入っている事が前提になります。AppleさんがもはやXcode5以下は許さないという強硬なスタンスなのですが、Xcode5.0.2はLionだと入れられなかったのでMavericksにアップデートさせられました。OpenCVやりたいだけなのに何故かPCが最新化されていく。ご存知かと思いますがMavericksは無償でアップデートできます。ちなみにOSアップデートに通信環境良くても数時間かかって、Xcodeのインストールと合わせると半日コースになるのでご注意を。

2.MacPortsのインストール

OS側の環境が整ったらMacPortsをインストールします。MacPortsOS X用のパッケージ管理システムで使わなくてもOpenCVの環境は作れますが使った方が俄然簡単です。MacPortsのダウンロードサイトに行ってインストールを行いましょう。

MacPortsダウンロードサイト

http://www.macports.org/install.php

f:id:jkawasaki:20140105164426p:plain

MacPortsは/opt/local/bin配下にインストールされます。僕はそのままでもインストール出来たのですが参考ドキュメントを見る限りだと「.bashrcに下記を記入してくれ」という記載があったので一応。

export PATH=$PATH:/opt/local/bin

パスを通すって事ですね。通した後に下記コマンドを実行します(bash前提)。

$ source .bashrc

ちなみにここから先はターミナルでの作業になりますのでターミナル慣れてない方はちょっと厳しいと思いますが頑張ってください。

3.OpenCVインストール

さて、いよいよOpenCVを入れていきます。手始めにMacPortsを使ってOpenCVの情報を下記コマンドで確認してみましょう。

$ port info opencv

こんな感じの結果が出ると思います。

f:id:jkawasaki:20140105164803p:plain

まーライセンスとかその他色々です。このコマンド効かなかったらMacPortsが使えてないってことになります。

次にOpenCVをインストールする前に必要なライブラリパッケージをインストールします。下記コマンドを実行しましょう。sudoはパスワードを聞かれるので適宜入力してください。パスワードが分からない場合はちょっとこの先には進めないのでその場合は親御さんに相談してください。

$ sudo port install pkgconfig zlib

するとわらわらと何やらインストールが始まります。

f:id:jkawasaki:20140105164909p:plain

そしていよいよOpenCVのインストールを行います。下記コマンドを実行しましょう。

$ sudo port install opencv

わらわらとインストールが始まります。結構長い(15分くらい?)です。

4.サンプルアプリの作成

無事インストールが出来たという事で実際にOpenCVが使えるようになっているかをXCodeからサンプルプログラムで試してみます。

今回はカメラを使ってみるのでMac OS X用の「Command Line Tool」アプリを作成します。

f:id:jkawasaki:20140105165736p:plain

プロジェクト名は適当に付けて新規プロジェクトを作成してください。Bundleとかはサンプルなので正直なんでも良いです。

やるべき事は5つです。

①Header Search Pathの設定

TARGETのBuileSettingで検索窓に”header”といれて検索するとHeader Search Pathという項目が見つかります。ここから下記パスを追加してください。

/opt/local/include

f:id:jkawasaki:20140105165715p:plain

f:id:jkawasaki:20140105165918p:plain

オプション部分はnon-recursiveで設定してください。recursiveだと謎のエラーが出ますので。これでOpenCVのヘッダーファイルを参照するパスの設定が出来ました。


②Library Searh Pathの設定
次にライブラリの参照設定をします。これを行わないとリンカーの設定が上手くいかないでビルドした時に下記のようなエラーが出ちゃいます。最初見たドキュメントにこの記載がなかったのでちょっとハマりました。設定箇所はヘッダーの時と同様にLibraryで検索すればすぐ見つかります。下記パスを設定しましょう

/opt/local/lib
ターミナルで見ると分かるのですが、このディレクトリ配下にOpenCVのライブラリ群が揃っています。

③ライブラリへのリンク指定
Build Phaseの「Link Binary With Libraries」という項目からリンクライブラリを選択します。追加するのは下記3つのライブラリです。

libopencv_core.2.4.7.dylib
libopencv_highgui.2.4.7.dylib
libopencv_imgproc.2.4.7.dylib

+ボタンを選択すると一覧が出てくるのですが僕の場合は何故か表示されなかったので”Add Other”から直接ファイルを探して追加しました。

f:id:jkawasaki:20140105170010p:plain

④サンプルプログラム(main.cpp)を記述

main.cppにサンプルプログラムとして下記を記述します。

#include <iostream>
#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;

int main()
{
    VideoCapture cap(0);
    Mat frame;

    while (waitKey(1)!='q') {
        cap >> frame;
        imshow("sample", frame);
    }
    return 0;
}

⑤その他
ここまででビルドする準備は整ったのですが、最新環境でそのまま実行するとDevelopment Targetが10.9になっているので失敗します。このサンプルは10.7向けになっているので変更してあげてください。

あと諸々のセッティングでエラーが出る場合には一度[product]➡[clean]してみてください

いざ実行。

f:id:jkawasaki:20140105165627p:plain

無事表示されました。

iPhoneでも同じプログラムが実行出来ると思うのですがそれを試すくらいならば先に進んだ方が良さそうなので今回は試さないです。

これでOpenCVが最低限動く環境となったのであとは好きに遊んでいきましょう。

【Unity】移動&衝突判定するキリンと崩れる箱をさくっと作ってみる

今回はキリンの衝突判定を行いたいと思います。

技術書の序盤に載ってるような超基礎なのですがあんまし参考ブログ見なかったので備忘録までに。ちなみに前回作ったARとは似ているようで実は全然違うものです。あしからず。

さて、Unityでは面倒な物理計算は全てAPIがこなしてくれちゃったりします。なのでキリンが箱にぶつかって箱が倒れるのも以外にサクッと出来てしまうものです。

では、レッツトライ。

1.下準備

まずは動くキリンを作りましょう。新規プロジェクトでCharactorContorollerを選んでください。

f:id:jkawasaki:20140103004655p:plain

Sceneに必要なのはキリンのオブジェクトとぶつかる対象となる箱の山です。Capsuleを配置して[Hierarchy]から"CharactorContoroller"を追加して上げましょう。

これでキー操作でCapsuleが動くようになりました。スピードとかは[Inspector]の値設定で適当にいじってください。

f:id:jkawasaki:20140103001007p:plain

このままだとキリンの見た目にならないのでCapsuleとキリンのモデリングをくっつけて上げます。

くっつけるのは簡単でScene上でCapsuleにキリンのオブジェクトを融合させて、HierarchyでキリンをCapsureの小要素にした上げるだけです。

f:id:jkawasaki:20140103001107p:plain

2.cubeを配置して物理的に存在させる

では倒すためのブロックを配意していきましょう。

まずは1つ、cubeオブジェクトをSceneに追加します。このまま動かすと物理的にはcubeも存在するのでその上にキリンを乗せたりする事は出来ますが相互の物理は干渉されません。cubeは今はただ存在しているだけなので、3Dの世界の重力も何も影響を受けません。

ちゃんと物質として存在させる為に"Rigidbody"というコンポーネントを足してあげましょう。コンポーネントはオブジェクトを選択した状態でメニューのCompornentから追加出来ます。[Compornent]➡[Physics]➡[Rigidbody]で追加してください。

f:id:jkawasaki:20140103001413p:plain

これでこのcubeはこの世界の物理的干渉を受ける事になりました。

ちなみにこのcube、一個一個に設定しないとそれぞれ物理干渉しないのですが、command+Dでコピーすれば設定もそのまま量産出来るので沢山同じオブジェクトを作りたいときは便利す。

3.キリンパワー注入

さて、ここでキリンにcubeを押す物理パワーを与えましょう。

[project]の[Assets]➡[Source]➡[Scripts]に新規JavaScriptファイルを作ってください。このJSにキャラクターのシナリオってやつを書いていきます。今回は押すためのファイルなので[pusher]というファイル名にしました。で、Rigidbodyを押すための関数「OnControllerColliderHit」を追加します。

JSファイルをエディタで開いて下記をペーストしてください。

var pushPower = 2.0;

function OnControllerColliderHit (hit : ControllerColliderHit)

{

    var body : Rigidbody = hit.collider.attachedRigidbody;

    // no rigidbody

    if (body == null || body.isKinematic)

        return;

        

    // We dont want to push objects below us

    if (hit.moveDirection.y < -0.3) 

        return;

    

    // Calculate push direction from move direction, 

    // we only push objects to the sides never up and down

    var pushDir = Vector3 (hit.moveDirection.x, 0, hit.moveDirection.z);

 

    // If you know how fast your character is trying to move,

    // then you can also multiply the push velocity by that.

    

    // Apply the push

    body.velocity = pushDir * pushPower;

}

関数はリファレンスとしてWeb上に転がってます。

ちなみにデフォルトでstart()とかの関数がJSファイルに書かれてますが、これは無視して消してしまいましょう

エディタを修正したら保存して、projectからsceneのキリンにドラッグ&ドロップします。この時、コンポーネントを追加するのは小要素のキリンじゃなくて親要素のcapsuleの方って事に気をつけてください。これでコンポーネントが自動で追加(便利!)されてinspectorでも見れるようになります。

で、実行すると

 

無事cubeを押せるキリンが誕生しました。

f:id:jkawasaki:20140103004721p:plain

 

次回こそはコイツに炎を吐かせて箱を倒したいと思います。

 

【30分でできる】Unityで簡単にARアプリを作る

UnityでサクッとARアプリ作れるのでせっかくなので書いておきます。ググると他にも同じ内容出てくるのでとってもポピュラーな事なのですが技術書みるとどうしてもUnityはゲームよりになっちゃうので、ARで使いたい人はお試しください。

 

誤解のないよう、先に書いておくと「Unity=AR」ではないです。正確にはAR用のライブラリを使ってUnityパッケージを作成して、そのパッケージ使うってだけです。

今回は「vuforia」ってライブラリを使った方法をご紹介。他にもいくつか有名どころがあるのでそれはまた後日使ってレポートしたいと思います。

 

では早速つくっていきましょう。

 

1.vuforiaでアカウントを作る

何はともあれvuforiaのDeveloperサイトにいってアカウントをつくりましょう。

f:id:jkawasaki:20131227185958p:plain

右上の「Register」ボタンから必要項目を入力すれば作れます。先も長いのでここは割愛します。

2・Dattabaseの作成とマーカーのアップロード

アカウントが出来たらログインをして上部メニューから「TargetManager」にはいってください。画面内に「CreateDatabase」と出るのでコレを押してマーカ画像のDBを作成します。DB名は適当で良いです。

f:id:jkawasaki:20131227190038p:plain

ここではお試しなので「KawaSample」というDBをつくります。

f:id:jkawasaki:20131227190134p:plain

DBを作成したら次はターゲット(マーカ)を登録します。「Add Target」ボタンを押して必要な項目を入力します。

f:id:jkawasaki:20131227190209p:plain

TargetName … ターゲットの名前

Target Type … ターゲットとなるオブジェクトの形状

Target Dimension …大きさ?

Target ImageFile …登録する画像

登録後、反映までに2〜3分かかります。適当な所でブラウザをリフレッシュして、画像が表示されたらOKです。

 

3・ターゲットのダウンロード

ダウンロードしたいターゲットを選択状態にして上部にある「Downlard Targets」を選択します。デフォルトではSDKが選択状態となっていますが、今回はUnityを使うので"Unity Editer"を選択してCreateボタンを押します。押したらすぐダウンロードがされます。

f:id:jkawasaki:20131227190236p:plain

 

4・vuforia SDKのダウンロード

これでマーカは出来ましたがARを行うのにvuforiaのSDKが必要になります。SDKはvuforiaトップページの「Doeload the SDK」(theって必要なのか?)から落とせますので落としてください。

5・Unity起動

ここでいよいよUnityの起動です。起動して適当に新規projectを作ってください。オプションとか付いてない、空のプロジェクトで大丈夫です。プロジェクトを作成すると"Heararchy"にCameraがデフォルトで用意されますが、不要なので削除してください。

6・パッケージインポート

先ほどvuforiaで作成した2つのパッケージをインポートします。

[Assets]➡[Import Package]➡[custom package]から先にダウンロードした2つのパッケージ(「KawaSample.unitypackage」と「vuforia-unity-android-ios-2-8-7.unitypackage」)をそれぞれインポートしてください。

インポートされたらprojectのAssetsに入ってくるので分かるかと思います。

f:id:jkawasaki:20131227190438p:plain

 

7・ARカメラの設定とImageTargetの設定

この状態では"Heararchy"になにも存在しない状態です。

まずはここに"ARCamera"を追加しましょう。"ARCamera"はさっきダウンロードしたSDKに入ってます。projectの[Qualcomm Augmented Reality]➡[Prefabs]に入っているのでドラッグして入れてください。

f:id:jkawasaki:20131227190617p:plain

もう一つ、同じ場所にあるImageTargetも同様にドラッグして設定します。

8・ARCameraの設定

[Data Set Load Behaviour]という項目の"Load Data Set Test"にチェックを入れましょう。その下にある"Active"にも同様にチェックを入れましょう。これを忘れるとオブジェクト自体は認識されるけど画面には何も映らない、という残念な状況になります。

(これで30分くらいはまりました。。)

ここまで行くとこんな感じで真っ白なターゲットだけがScaneに乗っている状態になります。

f:id:jkawasaki:20131227190826p:plain

9・ImageTargetの設定

次にマーカをImageTargetに設定します。やり方は単純です。[ImageTargetBehavier]の中にDataSetとImageTargetの2つの項目があり、デフォルトでは"EMPUTY"となっています。ここを選択するとプルダウンで先ほどインポートしたファイルが選べるので選べばイメージがセットされます。これでマーカを読み込む準備が出来ました。

f:id:jkawasaki:20131227190859p:plain

10・表示するオブジェクトの設定

今回僕は訳あって、キリンを出すのを目的にしています。なのでキリンの3Dオブジェクトを探しましたが残念ながら無かったので羊のオブジェクトにキリンのテクスチャを貼ったもので代用します。

オブジェクトはprojectに適当に「Texture」とか「obj」みたいにフォルダ切ってそこに突っ込めばOKです。突っ込んだオブジェクトをSceneにドラッグすれば配置出来ます。適当にマーカの上に置きましょう。

f:id:jkawasaki:20131227190955p:plain

 

この時注意なのが、オブジェクトは必ず「ImageTarget」の子要素にしてください。

子要素にしたい場合は親要素にドラッグしてあげればOKです。

さあ、これで準備が出来ました。

11・apkファイルへの書き出し

準備が出来たのでAndroidの実行ファイル(apk)として出力します。

Androidの開発環境を直接は使わないけれど、SDKにアクセスするのでPCに入っている事が前提となります。まずはメニューの[File]➡[BuildSetting]を開きましょう。

下のような画面が上がってくるので「Android」を選んで「Build」を押すだけです。

f:id:jkawasaki:20131227191054p:plain

あとはディレクトリとかを指定すればそこにapkを吐いてくれます。超簡単。

 

12・実行

吐き出されたapkは適当にメールで自分の端末に送るか、慣れている人ならadbコマンドとかでインストールして上げてください。個人的にはGoogleDriveにUPして端末から閲覧するのが一番楽だと思ってますが。

 

で、実行した結果がこちら。

f:id:jkawasaki:20131227191524p:plain

 

30分くらいで楽しく出来ました。

完全にプログラム関係ないので、ものが出来上がっても実感薄めなのですが、それだけUnityが素晴らしいという事で許したいと思います。

ここまで簡単に作れるのですが、実用にあたってはvuforiaもUnityもある程度分かっていないときっとすぐ壁にあたるので引き続き色々作りながら実戦に耐えれるレベルになっていきたいと思っております。

 

メリークリスマス。

 

【10分で出来る】Androidのリリース用「署名付きapkファイル」の作成

Androidのリリース作業について、実施した事ない人がハラハラしないように簡単に説明します。まず、Androidのリリース作業で必要なのは下記です。

 

Googleアカウント(開発者登録済のもの)

②署名付きapkファイル

③アプリアイコン、説明文、スクリーンショット

 

①については単純にGmailアカウントです。ただ、開発者になるには開発者登録を$20払って行っていなくてはなりません。リリースギリギリで実施しようとすると悲惨な事になるので早めに行いましょう。

ビジネスとしてのアプリリリースの場合、

1.ソースコード一式を渡してクライアントが実施する

2.開発者アカウントをクライアントからもらって代行する

3.開発者アカウントの作成から丸投げされる

の何れかになると思います。1のパターンが制作側としては一番楽ですね。特に技術に詳しい人がいない会社では2になる場合が多いです。3に関しては確率は低いですが、開発者アカウントはクレジットカードで支払ったりする事になるのであまり請け負わない方が良いかと思います。

 

で、ここからが本題でリリースに必要な「署名付きapkファイルの作成」を説明します。

Androidアプリはapkファイルを端末にインストールする事で実行出来、apkファイル自体は開発環境でビルドをすればいくらでも作れますが、開発者アカウントと紐付ける「署名」が無いとGooglePLAYでリリースする事は出来ません。

署名付きapkの作成は環境と手順さえ分かっていれば誰でも簡単に作れます。

 

1. keystoreファイルの作成

各アプリ毎発行するkeyファイルになります。これを使って署名を行う重要なファイルです。発行の手順はとっても簡単です。まずはMacでターミナルを開いて、usr/bin配下に移動してください。

 

1-1.ターミナルでキーファイル作成コマンドを実行

keytool -genkey -v -keyalg RSA -keystore ‾/[ファイルを格納するパス]/xxxx.keystore -alias [アプリ名] -validity 10000

赤字の部分はファイルを生成するパスになります。今回は誰のPCにもあるであろうDownloadフォルダに突っ込んでいます。別に生成場所はどこでも大丈夫です。オレンジの場所は作成するキーファイルのファイル名になります。このままコピって使う場合にはj-kawasakiの部分だけ変更して実行すれば大丈夫です。

 

1-2. キーファイルの情報を入力する

「姓名」、「組織名」、「組織単位名」、「都市名」とかを聞かれます。組織単位名とかは分かり難いと思うのですが、組織の○○事業部みたいなので指定したければ入れてください。未入力でもキーの作成には影響しません。関連する国の部分は「jp」といれておけば大丈夫です。これらの情報は特に外部に漏れるものでは無いです。

 

ここまで実行すると、ダウンロードフォルダ内に「xxxx.keystore」というファイルが出来ます。これが署名を行う為のキーファイルになります。

1点注意点として、このキーファイルでの署名はアプリのアップデートにも必要になります。万が一紛失してしまうとアプリがアップデート出来なくなりますので厳重に管理しましょう。(再度別キーファイルにすると別アプリとしてみなされてしまいます)

 

2.署名付きapkの作成

apkへの署名はコマンドでも出来ますが、以前実行したらなんかおかしな事になったのでこのエントリでは開発環境であるeclipceを使った方法を説明します。手順は簡単です。

 

2-1.プロジェクトを右クリックして「Android tools」を選択

 

2-2. 署名付きapkの作成を選択

 

2-3. keyStoreファイルを選択し、パスワードを入力

 

2-4.署名付きapkの格納先を選択

 

で、finishすると署名付きのapkファイルが出来ます。

署名付きapkは未署名と同様に実機にインストールして確認出来ますので配布前に必ず確認しましょう。※既に開発用のapkが端末に入っている場合は必ずアンインストールしてくださいね

 

署名付きファイル同士であれば上書きが出来るので、例えばアプリをバージョンアップする時は上書きインストールすれば実際にユーザがストアからアップデートした時の挙動が確認出来ます。データの引き継ぎとかが気になる場合にはこれも確認しましょう。

 

□今回の要点をざっくりいうと

1. ストアにリリースするには署名付きのapkファイルが必要です

2. 署名をする為のキーファイルは紛失しないように厳重管理しましょう

3. アプリのアップデート時には署名ファイルを使ってアップデート動作確認をしましょう

 

慣れると手順は簡単なのですが、お仕事としてリリースする場合にはミスが無いように神経尖らせて実施しましょう。

【iOS】iOS7のステータスバー問題とXcode4を今すぐ廃止する理由

前々から噂になっていたiOS7のステータスバー問題、あんまり気にしてなかったけど

先日、見事に地雷を踏みました。どういう事かというと、普通に今までの感覚で

画面作ったつもりでもXCode5で実行するとこうなるのです。

f:id:jkawasaki:20131021002848p:plain

※画像は参考で開発した物ではありません

 

見事なまでにヘッダーめりこんでます

何が起きてるかというと、iOS7ではステータスバーが透明になって

さらにステータス領域20pxが「なかった事」になり全体が上に上がってしまう。

しかもこの状態、Xcode4.xでビルドすると発生しないってのが憎い。

対応策はいくつかあり、下記にまとめられてます。

(かぶっても意味ないのでココでは具体的には書きません)

 

iOS7ステータスバー対策まとめ

iOS7でstatusbar(ステータスバー)を消す方法

 

ちなみに僕は申請間際にこの問題に気付き、超絶時間が無い中での対応になりました。

本当は黒背景でステータスバーを「復活」出来ないかな、と思ったのですが、

さすがのAppleはそんな下位互換は簡単にさせてくれないぽかったので、

とりいそぎステータスバーを消す形で対応しました。

でも画面高さからレイアウト指定している箇所が何カ所かあったので

更にいくつか微調整が必要になりました。。

実際には画面毎にステータスバーを動的に表示させたり、

20pxを保持したままってのも出来ますが何か開発者が苦労するばかりで得をしないので

力技での解決はあまりおすすめしません(バグ増えるし)。

かといって、一律、完全に消してしまうと電波が必要な機能なのに表示がないとか、

時間が見えなくて使い難いとかなるので、画面設計で柔軟な対応が求められます。

 

<要約:ステータスバー問題を発生させない為に>

・ちゃんとデザイナーにこの辺を理解してもらう

・デザイン上、ステータスバーが必要な場合は20pxを考慮したデザインをする

・Xcode4.xを使っている人は排除する

 

個人的に一番最後のXcode5の件は他にも想定外の問題を出さないためにも

世界中で直ぐに実施した方が良いとおもいます。

時間があったらまた別途書きますが、Xcode5を使うとまた申請の仕方が違ったり

何故か今までは出来ていた方法でAdHoc配信が出来なかったりと

予期せぬ害が生まれる事が多いです。(開発環境としては使い易くなっていますし)

iOS7に対応してないアプリはリジェクト対象のリスクも含んでいるとの事なので、

使い慣れてるとかアップデートめんどいとかの理由でXcode4系を使い続けないで、

さっさと全員Xcode5に乗り換えた方が良いです。

 

では。