2012年5月30日水曜日

カメラプレビューにちょっとした機能を追加

SurfaceViewを使ってカメラプレビューを実装する
以前にAndroidでのカメラプレビューの実装のやり方を載せましたがこれに機能を追加してみました

  • 撮影機能
  • オートフォーカス機能

内容的にはオートフォーカスは画面をタッチ、撮影はカメラボタン(カメラボタンがない機種もあるのでボリュームボタンも)、撮影時に向きの調整。
オートフォーカスはまぁわりと簡単に実装できました。
(本当はタッチフォーカス機能まで実装したかったんですが、今回は断念。。。)
// オートフォーカス処理
private AutoFocusCallback mAutoFocusListener =
    new AutoFocusCallback() {
        @Override
        public void onAutoFocus(boolean success, Camera camera) { }
    };

// 画面タッチ時にオートフォーカスを実装
public boolean onTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        Camera.Parameters params = myCamera.getParameters();
        if (!params.getFocusMode().equals(Camera.Parameters.FOCUS_MODE_FIXED)) {
            myCamera.autoFocus(mAutoFocusListener);
        }
    }
    return true;
}

オートフォーカスの処理自体にはコードを書かなくても動作します。
ですので画面タッチしたときにそれを動くようにしてやるだけでOK。

次に撮影してAndroidのギャラリーに登録します。
// 写真を撮る
private PictureCallback mPictureListener = 
    new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            ContentResolver resolver = getContentResolver();

            // 日時からファイル名を生成
            Date token = Calendar.getInstance().getTime();
            String name = photoName.format(token) + ".jpg";

            // データを生成する
            Bitmap tmp_bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

            // 画像データを保存する
            MediaStore.Images.Media.insertImage(resolver, tmp_bitmap, name, null);

            // カメラを再開
            myCamera.startPreview();
        }
    };

// キー操作で撮影
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_CAMERA
                    || keyCode == KeyEvent.KEYCODE_VOLUME_UP
                    || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
            myCamera.takePicture(null, null, mPictureListener);
            return true;
        }

        return super.onKeyDown(keyCode, event);
    }

単純に保存するだけなら難しい処理がなくても動作すると思います。
ただこれだけを書いて実行してみるとわかると思いますが保存した画像は横向きで保存されていることがわかると思います。

いろいろ調べていて
int rotation = getWindowManager().getDefaultDisplay().getRotation();

これで回転がとれると思ったんですが端末の自動画面回転を有効にするのとアプリの画面向きがデフォルトのままでないと動作が確認できませんでした。
アプリの画面向きはともかく端末の自動画面回転を有効にしないと動かないってのはちょっと。。。
ということでセンサを使って判断しました。
なんかもっといいやり方あったら教えてください(>_<)

撮影した画像の向きを変えるのはgraphics.Matrixを使ってできます。
    // データを生成する
    Bitmap tmp_bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
    int width = tmp_bitmap.getWidth();
    int height = tmp_bitmap.getHeight();

    Matrix matrix = new Matrix();
    matrix.setRotate(90);

    // 画像データを保存する
    Bitmap bitmap = Bitmap.createBitmap(tmp_bitmap, 0, 0, width, height, matrix, true);
    MediaStore.Images.Media.insertImage(resolver, bitmap, name, null);


とりあえず作ったものをGitHubに置いています。
https://github.com/hayashida/CameraTest/



2012年5月28日月曜日

iOSでカメラプレビューを試してみました

顔認識のアプリを作りたいんですがまだまだそこまで知識がないので
とりあえずiOS Dev CenterのSqureCamを見ながらカメラのプレビュー画面を表示するものを作ってみました。

いつも通りXcode > Create a Xcode Project > Single View Application
ProductName : CameraTest

まず、以下のようなかんじで画面を作成します。

次に、割り当てたViewとBar Button Itemをそれぞれ関連付けを行います。

とりあえずここまででビルドしてエラーがでないことを確認します。

次に、AVFoundation.frameworkをプロジェクトに追加します。

次に、割り当てたView(previewView)の部分にカメラプレビューを表示します。
ViewController.h
@interface ViewController : UIViewController
{
    AVCaptureVideoPreviewLayer *previewLayer;
}

ViewController.m
- (void)ViewDidLoad
{
    [super viewDidLoad];

    [self setupAVCapture];
}

- (void)setupAVCapture
{
    // セッション生成
    AVCaptureSession *session = [AVCaptureSession new];
    [session setSessionPreset:AVCaptureSessionPreset640x480];
    
    // 入力設定
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
    
    if ([session canAddInput:deviceInput])
        [session addInput:deviceInput];
    
    // 画面表示設定
    previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
    [previewLayer setBackgroundColor:[[UIColor blackColor] CGColor]];
    [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspect];
    
    CALayer *rootLayer = [previewView layer];
    [rootLayer setMasksToBounds:YES];
    [previewLayer setFrame:[rootLayer bounds]];
    [rootLayer addSublayer:previewLayer];
    [session startRunning];
}

一応、これだけでアプリ内のView (previewView)の部分にカメラのプレビューが表示されると思います。

これだけだと何も使えないんでフォーカスを合わせて画面をキャプチャするか機能を追加してみます。
(一応作ってはいるんですが、そのうち載せます)



2012年5月25日金曜日

顔認識について

Androidでは顔認識(FaceDetector)はAPI Level1からあるみたいなんですが、静止画が対象となります。
Android4.0からは動画も対応できるようになったみたいです。
偶然自分のスマホがAndroid4.0なんでまぁ試してみようかなと思ってます。
時間があればここでも紹介したいと思います。


またiOSの顔認識(CIDetector)はiOS5からなんで古いバージョンは対応することができません。
iOSのほうはiOS Dev Centerのなかにサンプル(SquareCam)があるんでそれは参考にするといいと思います。
特に何もする必要もなく動作すると思います。
少し触っただけですが認識もそれほど悪くないですし複数の同時認識も問題なく動作しました。

ざっと使っただけですが、何か使えそうというか面白そうです。



SurfaceViewを使ってカメラプレビューを実装する

久しぶりにAndroidを触ってみました。
ほんと久しぶりだったんでけっこう忘れてるというか戸惑いました。
本当はFaceDetectorを使って顔認識するアプリを作ろうかと思ってたんですがその前にカメラビューを表示させるところから。
顔認識(FaceDetector)のところはまた今度しようかと思ってます。

まず、Eclipseを起動してプロジェクトを作成します。
それからカメラの機能を使うんでマニフェストファイル(AndroidManifest.xml)に以下を追記します。
<uses-permission android:name="andoird.permission.CAMERA" />

続いてレイアウトファイルにSurfaceViewを追加します。
<SurfaceView
 android:id="@+id/surface_view"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 />

最後にカメラプレビューを実装する部分を作ります。
package jp.kuseful.cameratest;

import java.util.List;

import android.app.Activity;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup;

public class CameraTestActivity extends Activity {
 
    private Camera myCamera;
    private SurfaceView mySurfaceView;

    private SurfaceHolder.Callback mSurfaceListener = 
            new SurfaceHolder.Callback() {
                @Override
                public void surfaceDestroyed(SurfaceHolder holder) {
                    // カメラを停止する
                    if (myCamera != null) {
                        myCamera.stopPreview();
                        myCamera.release();
                        myCamera = null;
                    }
                }

                @Override
                public void surfaceCreated(SurfaceHolder holder) {
                    // カメラを起動する
                    myCamera = Camera.open();
                    try {
                        myCamera.setPreviewDisplay(holder);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void surfaceChanged(SurfaceHolder holder, int format
                        , int width, int height) {
                    myCamera.stopPreview();

                    Camera.Parameters parameters = myCamera.getParameters();

                    boolean portrait = isPortrait();

                    // 画面の向きを変更する
                    if (portrait) {
                        myCamera.setDisplayOrientation(90);
                    } else {
                        myCamera.setDisplayOrientation(0);
                    }

                    // サイズを設定
                    List sizes = parameters.getSupportedPreviewSizes();
                    Camera.Size size = sizes.get(0);
                    parameters.setPreviewSize(size.width, size.height);

                    // レイアウト調整
                    ViewGroup.LayoutParams layoutParams = mySurfaceView.getLayoutParams();
                    if (portrait) {
                        layoutParams.width = size.height;
                        layoutParams.height = size.width;
                    } else {
                        layoutParams.width = size.width;
                        layoutParams.height = size.height;
                    }
                    mySurfaceView.setLayoutParams(layoutParams);

                    myCamera.setParameters(parameters);
                    myCamera.startPreview();
                }
            };

    // 画面の向きを取得する
    protected boolean isPortrait() {
        return (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
    }
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mySurfaceView = (SurfaceView)findViewById(R.id.surface_view);
        SurfaceHolder holder = mySurfaceView.getHolder();

        // コールバックを登録
        holder.addCallback(mSurfaceListener);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }
}

surfaceChangedのメソッド部分に大半のコードを書いてます。
その部分を簡単に説明すると

  1. カメラを一時的に停止する
  2. 状態を取得する
  3. デバイスの向きにあわせて画面を回転させる
  4. カメラプレビューの大きさを設定する
  5. レイアウト(アスペクト比)を調整する
  6. 状態を設定する
  7. カメラを再開する
とまぁこんなかんじの流れです。
実際に使うとなるともぉちょっと調整が必要ですがこれでカメラプレビューの実装自体はできると思います。

今度はこれから顔認識するようなものを作ってみようかと思います。


カメラは基本的に横向きの設定を持ってるみたいなんで縦も対応させようとすると回転させる必要がありました。(マニフェストファイルとかなんか設定できそうですけどね)

2012.5.30 ちょっと続きを書いてみました。そちらもどうぞー
カメラプレビューにちょっとした機能を追加



2012年5月22日火曜日

Gitをちょっとだけ触ってみた

ちょっと流行ってるみたいなんで触ってみました。
幸い?MacにはGitが最初から入っていたんでインストールを不要!
簡単に触ってみる分にはいいかもしれません。

まずターミナルを起動して
$ git --version
git version 1.7.7.5 (Apple Git-26)

これが表示されればGitは既にインストールされています。

個人的に使う分でいけばローカルにリポジトリを作ってそこで管理してやるといいので以下みたいなかんじ。
$ mkdir repo.git
$ cd repo.git
$ git init
Initialized empty Git repository in repo.git/.git/

これで空のリポジトリが作成されます。
ここに適当にファイルを作成してコミットします。
$ touch test.txt
$ git add test.txt
$ git commit -m 'first commit'
$ git log
commit : xxxx
Anchor : xxxx
Date : 

    first commit

こんなかんじ動けばOKだと思います。

ただこれだと自分のローカルだけでしかバージョン管理できないので複数での開発とかになるとちょっと面倒です。

そこでこれを共有リポジトリとして登録し、管理するようにします。
今回は以下のようなディレクトリ構成

staff A (~/)
    └ git (←ここが共有リポジトリ)
        └ repo-sv.git
    └ workspace
        └ repo.git
            └ test.txt

staff B (~/)
    └ workspace
        └ repo.git
            └ test.txt

サーバとなる端末で共有リポジトリを作成します。
(今回はローカルPC内に共有リポジトリを作成します)
// staff A
$ mkdir repo-sv.git
$ cd repo-sv.git
$ git init --bare --shared=true
Initialized empty shared Git repository in repo-sv.git

これで先ほどと同様空のリポジトリが作成されます。
次にこの共有リポジトリにバージョン管理するもの登録します。
// staff A
$ cd workspace
$ git push ~/git/repo-sv.git master

そして別のPCから共有リポジトリをcloneしてきます。
// staff B
$ cd workspace
$ git clone <User Name>@<Host Name>:git/repo-sv.git repo.git

あとは修正してコミットしてを試して見てください。
// staff B
$ cd repo.git
$ vi test.txt
test
$ git add test.txt
$ git commit -m 'staff B modified'
// 変更を共有リポジトリにPush
$ git push <User Name>@<Host Name>:git/repo-sv.git master


// staff A
// staff Bで変更された内容をPullします
$ cd workspace/repo.git
$ git pull ~/git/repo-sv.git
$ cat test.txt
test

いつも通りざっとしてますが、こんなかんじでちょっとだけ触ってみました。

※ git のアドレス
今回、git から cloneするところのアドレスを <User Name>@<Host Name>:git/repo-sv.gitとしてますがMacの環境のせいかこういうアドレス形態になってしまいました。
同じようにLinux環境でGitをたててやってみるとssh://<User Name>@<Host Name>/git/repo-sv.gitでつながりました。
内容というか原因はよくわかりませんがアドレスの指定のしかたになんかありそうです。




2012年5月18日金曜日

apacheのaliasでハマった

EclipseでPHPを開発するためにPHPのワークスペースをユーザドキュメントの中に作っていました。
そこにApacheの仮想ディレクトリのエイリアスを作ったんですが、パーミッションのエラーが。。。

ワークスペースの権限ばかり気にしていたんですがもっと上の階層(今回はドキュメントディレクトリ)で権限が足りてませんでした。

メモ程度ですがしたこと

Eclipseのワークスペース: ~/Documents/Workspace/php

httpd.conf
<IfModule alias_module>
    (省略)
    Alias /~php/ "Users/<User Name>/Documents/Workspace/php"
</IfModule>

<Directory "/Users/<User Name>/Documents/Workspace/php">
    AllowOverride None
    Options Indexes FollowSymLinks
    Order allow,deny
    Allow from all
</Directory>

ターミナル起動
$ chmod 755 ~/Documents

いやーハマりました。。。



2012年5月17日木曜日

PHP+MSSQLのインストール

Mac環境のPHP+MSSQLをインストールするやり方。
まず、http://www.freetds.org/から安定版のfreetdsをダウンロードします。

Mac環境(Linuxでも同じだと思いますが)でMSSQLに接続したい場合には、このfreetdsというのを使います。

ダウンロードしたファイルを解凍して、「/usr/local/src」に配置します。

次にターミナルを起動して配置したディレクトリに移動します。
$ cd /usr/local/src/freetds-0.91

次にfreetdsの設定・コンパイル・インストールを行います。
$ ./configure --prefix=/usr/local/freetds --enable-msdblib
$ make
$ sudo make install
password:

PHPで使用したいのでモジュールの追加を行います。
$ cd /usr/local/src/php-5.3.13
$ ./configure --with-apxs2=/usr/local/apache2/bin/apxs --enable-mbstring --with-mssql=/usr/local/freetds
$ make
$ sudo make install
password:

これで設定はOK。
Apacheを再起動してphpinfoを確認すると、下のようにMSSQLの項目が表示されると思います。


※phpinfoにはでてきてるんですが実際にプログラムを組んでみるとうまく動きませんでした。なんか設定があるのかな。調べ中です。。。

2012.5.18 追記
実際にSQLServerに接続しようとした場合、うまく動かなかったんですがインスタンス名が含まれる場合?に接続できませんでした。
マニュアルでは<computer>\<instance name>と書いてはいるんですがだめでした。

私の場合、以下のように/usr/local/freetds/etc/freetds.confに追記を行うことで接続することができました。
[server\sqlexpress]
host = server
instance = sqlexpress
tds version = 7.2

これでプログラムそのままでSQLServerに接続することができました。

Macに入れたPHP・MySQLでつまづいた点(続)

先日までセットアップしてたPHP・MySQLのセットアップで
エラーが気になって再度一から構築してみようと試みましたがやっぱり同じ箇所でつまづいてしまいました。
さらに途中からsudo -sでroot権限に切り替えないとPHPのインストールとApacheの起動ができなくなってしまったりMySQLも起動しなくなるなどボロボロ。。。

バージョンの問題なのかなと思いMySQLを5.5.24から5.1.63に変えました。
するとすんなりインストールが完了。
.bash_profileを書き換えたりする必要もなく。
また合わせてMySQLの配置を「/usr/local/mysql-5.1.63」から「/usr/local/mysql」に変更してます。
(シンボリックリンクでもいいと思います)

んーやっぱりバージョンの相性なのかな。。。



2012年5月15日火曜日

Macに入れたPHP・MySQLでつまづいた点

昨日・今日でMacにバイナリパッケージからApache・PHP・MySQLをインストールしてきましたが、単にインストールするだけなら特別問題もなくインストールできました。
Mac OS X(Lion)にApache2を手動でインストールする
Mac OS X(Lion)にPHP5.3を手動でインストールする
Mac OS X(Lion)にMySQLを手動でインストールする

本当にただ動かすためだけにインストールしてたんで
これからさらにPHP+MySQLを試みてたんですがエラーの連続でなかなかうまいこといきませんでした。
各バージョンの問題なのかOSバージョンの問題なのか
理由はいろいろなんでしょうがとりあえず調べるのに時間がかかったところだけ備忘録程度に。。。

phpizeでエラー
これはさっき書いたんで省略しますがmysqlのモジュールを追加しようと思ってこれをやってたんですが、結果追加モジュールからはうまく動いてくれませんでした。
# cd /usr/local/src/php-5.3.13
# cd ext/mysql
# phpize
# ./configure --with-mysql=/usr/local/mysql-5.5.24
# make
# make install

で結局、phpのconfigureから再コンパイルしてっとやってたんですがMySQLがうまく動いてくれません。というかmakeでエラーが出ました。
# cd /usr/local/src/php-5.3.13
# ./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql=/usr/local/mysql-5.5.24
# make clean
# make

これを実行すると以下のエラー
Undefined symbols for architecture x86_64:
  "_res_9_init", referenced from:
      _zif_dns_get_mx in dns.o
      _zif_dns_get_record in dns.o
      _zif_dns_check_record in dns.o
  "_res_9_search", referenced from:
      _zif_dns_get_mx in dns.o
      _zif_dns_get_record in dns.o
      _zif_dns_check_record in dns.o
  "_res_9_dn_skipname", referenced from:
      _zif_dns_get_mx in dns.o
      _zif_dns_get_record in dns.o
  "_res_9_dn_expand", referenced from:
      _zif_dns_get_mx in dns.o
      _php_parserr in dns.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [libs/libphp5.bundle] Error 1

内容はよくわかりませんでした。
が、ぐぐった結果、.bash_profileを変更するということだったのでこんなかんじ。
# vi ~/.bash_profile
-----
export EXTRA_CFLAGS=-lresolv
-----
# source ~/.bash_profile

これで再度コンパイルからmakeを実行。
すると今度は以下のエラー
yld: Library not loaded: libmysqlclient.18.dylib
  Referenced from: /usr/local/src/php-5.3.13/sapi/cli/php
  Reason: image not found
/bin/sh: line 1: 94225 Trace/BPT trap: 5       ` if test -x "/usr/local/src/php-5.3.13/sapi/cli/php"; then /usr/local/src/php-5.3.13/build/shtool echo -n -- "/usr/local/src/php-5.3.13/sapi/cli/php -n"; if test "x" != "x"; then /usr/local/src/php-5.3.13/build/shtool echo -n -- " -d extension_dir=/usr/local/src/php-5.3.13/modules"; for i in bz2 zlib phar; do if test -f "/usr/local/src/php-5.3.13/modules/$i.la"; then . /usr/local/src/php-5.3.13/modules/$i.la; /usr/local/src/php-5.3.13/build/shtool echo -n -- " -d extension=$dlname"; fi; done; fi; else /usr/local/src/php-5.3.13/build/shtool echo -n -- "/usr/local/src/php-5.3.13/sapi/cli/php"; fi;` -d 'open_basedir=' -d 'output_buffering=0' -d 'memory_limit=-1' -d phar.readonly=0 -d 'safe_mode=0' /usr/local/src/php-5.3.13/ext/phar/build_precommand.php > ext/phar/phar.php
make: *** [ext/phar/phar.php] Error 133

もぉよくわかりません。
とりあえず、ぐぐった結果、これまた.bash_profileを変更。。。
# vi ~/.bash_profile
-----
export DYLD_LIBRARY_PATH=/usr/local/mysql-5.5.24/lib:$DYLD_LIBRARY_PATH
-----
# source ~/.bash_profile

これで再度コンパイルからmakeを実行。
やっとエラーが消えました。

内容はよくわかりませんが、バージョンの問題なのかOSの問題なのか。。。

2012.5.17
こちらも参考程度にリンクつけときます。
Macに入れたPHP・MySQLでつまづいた点(続)



phpizeでエラー

phpizeはphpの拡張モジュールをビルドする環境を作る為のコマンドですが、ここでエラーが発生。。。
Cannot find autoconf. Please check your autoconf installation and the $PHP_AUTOCONF environment variable is set correctly and then rerun this script.

autoconfが入ってない的なエラー。

ということでautoconfをインストールします。

まず、http://www.gnu.org/software/autoconf/から任意のバージョンのautoconfをダウンロードします。
(今回はautoconf-2.69をダウンロードしました。)

ダウンロードしたファイルを解凍して、「/usr/local/src」に配置します。

以下、ターミナルを起動してインストールを行います。
$ cd /usr/local/src/autoconf-2.69
$ ./configure --prefix=/usr
$ make
$ sudo make install

これでOK。


Mac OS X(Lion)にMySQLを手動でインストールする

えー引き続き今度はMySQLのインストールのやり方。
まず、http://www-jp.mysql.com/から任意のバージョンのMySQLをダウンロードします。
(今回は、MySQL-5.5.24をダウンロードしました。)

ダウンロードしたファイルを解凍して「/usr/local」に配置します。
Apache・PHPとは違いconfigureとかmakeとか必要ない?のかな

ターミナルを起動して今回はroot権限で操作を行っていきます。
$ sudo -s
password:

次にMySQLを実行するためのユーザとグループの確認をしておきます。
# grep _mysql /etc/passwd
_mysql:*:74:74:MySQL Server:/var/empty:/usr/bin/false
# grep _mysql /etc/group
_mysql:*:74

上のように表示されていればOKです。
次に配置したディレクトリに移動します。
# cd /usr/local/mysql-5.5.24

MySQLのディレクトリの権限を変更します。
# chown -R _mysql .
# chgrp -R _mysql .

次にデータベースを初期化して権限を再度変更します。
# scripts/mysql_install_db --user=_mysql
# chown -R root .
# chown -R _mysql data

これでMySQL自体は動作できるようになりますが
念のため設定ファイルをコピーしておきます。
# cp support-files/my-medium.cnf /etc/my.cnf

これでMySQLを起動・停止してみてください。
// MySQLの起動
# /usr/local/mysql-5.5.24/bin/mysqld_safe --user=_mysql &

// MySQLの停止
# /usr/local/mysql-5.5.24/bin/mysqladmin -uroot shutdown

起動したらMySQLにログインして「show databases」等、コマンドを打って動作の確認を行ってください。


細かい設定は省いていますがこれで、apache・PHP・MySQLのインストールできると思います。



Mac OS X(Lion)にPHP5.3を手動でインストールする

昨日構築したApache2のwebサーバでPHPを動かせるように
今度はPHPのインストールのやり方。

まず、http://www.php.net/から任意のPHPのバージョンのダウンロードをします。
(今回は、PHP-5.3.13をダウンロードしました。)

ダウンロードしたファイルを解凍して「/usr/local/src」に配置します。

次にターミナルを起動して配置したディレクトリに移動します。
$ cd /usr/local/src/php-5.3.13

次にインストールの設定を行います。Apache2のときと同様、本来はいろいろ設定が必要なところですがとりあえず動くようにします。
$ ./configure --with-apxs2=/usr/local/apache2/bin/apxs

これでエラーがでなければOK。
続けて、コンパイルとインストールを行います。
$ make
$ sudo make install
password:

これでPHPのインストールは完了です。

ただし、このままではPHPをインストールしただけなので次にApacheでPHPを動かすように設定を変更します。

Apacheのhttpd.confファイルを開きます。(viエディタの例です)
$ sudo vi /usr/local/apache2/conf/httpd.conf

PHPの共有モジュールをロードするように以下を追加します。
(自動的に追加されてると思いますが確認まで)
LoadModule php5_module modules/libphp5.so

そのままPHPの拡張子を認識させるためにファイルタイプを指定します。
<IfModule mime_module>
    (途中省略)

    AddType application/x-httpd-php .php
    AddType application/x-httpd-php-source .phps
</IfModule>

これで設定は完了です。
修正した内容を保存してApacheを再起動します。

Apacheのドキュメントルートに「phpinfo.php」を作成して
<?php phpinfo(); ?>

http://127.0.0.1/phpinfo.php
これを開いてPHPの状態画面が表示されればOKです。




2012年5月14日月曜日

Mac OS X(Lion)にApache2を手動でインストールする

以前に、Mac OS X(Lion)にApache2+PHPをインストールという記事を書きましたが
これはMacにデフォルトで入っているwebサーバの動かし方だったんで
今度はバージョンを指定して任意のディレクトリにApache2をインストールするやり方。

まず、http://httpd.apache.org/から任意のバージョンのApacheをダウンロードします。
(今回は、Apache-2.2.22をダウンロードしました)

ダウンロードしたファイルを解凍して「/usr/local/src」に配置します。

次にターミナルを起動して配置したディレクトリに移動します。
$ cd /usr/local/src/httpd-2.2.22

次にインストールの設定を行います。本来は細かな設定をしていくところですが
今回は割愛してとりあえずそのままの状態でサーバをインストールします。
$ ./configure

続けてコンパイルを行います。
$ make

最後にインストールを行います。
$ sudo make install
password:

これでApacheのインストールは完了です。

Apache側の設定もいろいろとありますがとりあえず動かします。
$ sudo /usr/local/apache2/bin/apachectl start

これでエラーがでなければOK。
http://127.0.0.1/を開いて「It Works!」が表示されれば完了です。


※以下、私の環境でちょっと戸惑った件
XCode4.3をインストールしていたせいなのかもともとなのかよくわかりませんが
「make」コマンドが使えませんでした。
いろいろ調べた結果、「Command Line Tools」というものをインストールしなければなりませんでした。
これはXCode > Menu > Open Developer Tool > More Developer tools... からダウンロードしてインストールすることができます。
他の人のXCode4.2の環境では「make」コマンドは使えそうなかんじだったんで4.3からかもしれません。





2012年5月9日水曜日

AndoirdでARアプリを試してみる(Vuforia)

調子にのってAndroid版も動かしてみました。

内容はiOS同様さっぱりですが、とりあえず動きました。

iOS同様、まずSDK(vuforia-sdk-android-1-5-9.zip)をダウンロードします。
https://ar.qualcomm.at/qdevnet/sdk

ダウンロードしたファイルを解凍してvuforia-sdk-android-1-5-9.appからインストールを行います。
インストール後は上のようなかんじになってると思います。

次にサンプルを動かしますが、なかなかうまくいきませんでした。。。
(Eclipseを日本語してないせいもあってかな)

samples入っているImageTargetsをEclipseで開くと
QCAR_SDK_ROOTが見つからないみたいなエラーがでました。
(SDKのインストールパスを変えたせい??)
とりあえずEclipseの環境設定からクラスパスを追加します。
Macのメニュー Eclipse > 環境設定から Preference画面を開き、Java > Build Path > ClassPath Variablesを開きます。
Name : QCAR_SDK_ROOT
Path : <インストールディレクトリ>/vuforia-sdk-android-1-5-9

これでエラーが消えると思いきや消えず。。。
Android Tools > Fix Project Properties をクリックしてようやくエラーが消えました。

これでようやく実機につなげて実行としましたが起動した直後、アプリが落ちました。
ログを見ると「libQCAR.so could not be loaded」というエラー。。。

いろいろと調べた結果、Android NDKをインストールしておかないだめみたいです。
ということでAndroid NDKをインストール。。。
http://developer.android.com/intl/ja/sdk/ndk/index.html

android-ndk-r8-darwin-x86.tar.bz2をダウンロードして任意のディレクトリに解凍します。
それからインストールしたNDKのディレクトリにパスを通します。
ターミナルを起動して「vi .bash-profile」以下を追記します。
ANDROID_NDK_ROOT=<インストールディレクトリ>/android-ndk-r8
export PATH=$PATH:${ANDROID_NDK_ROOT}

これを保存して「source .bash-profile」で設定を反映させます。

そしてこのNDKを使用してプロジェクトをビルドします。
ターミナルからプロジェクトのディレクトリに移動して「ndk-build」

これが成功して初めて実機での実行に成功しました。

なんかとりとめもないですが、やっと動くようになりました。
サンプルの実行とかはVuforiaのGetting Startingにも載ってますので一度見ておいたほうがいいかもです。

確認した機種
・htc EVO WiMax(Android 2.3.4)
・Galaxy Nexus(Android 4.0.2)




iOSでARアプリを試してみる(vuforia)

iOSでARアプリに挑戦してみよう
と思ってとりあえずvuforiaを使ってみました。

使ってみただけで内容はさっぱりわかりませんがサンプルを動かすまでと
ARの認識画像を変更するところまでは動きました。

まずはQDevNetからSDK(vuforia-sdk-ios-1-5-8.zip)をダウンロードします。
https://ar.qualcomm.at/qdevnet/sdk/ios
(ダウンロードにはユーザ登録が必要です)

ダウンロードしたファイルを解凍してvuforia-sdk-ios-1-5-8.appからインストールを行います。
これでSDKのインストールは完了です。


次にサンプルを動かしてみます。
インストール後、ディレクトリは以下のようになっていると思います。

ディレクトリ内にあるsampleから今回はImageTargetsを動かしてみます。
とりあえずプロジェクトを開いてビルド。
エラーがないことを確認して実機でデバッグ。

ImageTargets > media のjpgファイルを見るとこんなかんじで表示されると思います。
(印刷する環境がなかったのでパソコンの画面をそのまま。。。)

次に認識する画像を追加する方法。
(上の画像を認識させるようにします)

まずこの画像のTrackable(特徴みたいなもの?)を取得する必要があります。
QDevNetにアクセスしMyTrackablesを開きます。
「New Project」をクリックし「Project name」に「ImageTargets」と入力し「Save」をクリックします。
プロジェクトが登録されてると上の画面が表示されますので「create a trackable」をクリックします。
Trackable Name : 適当に名称を入力
Select Trackable Type : Single Image Or Multi Target - cuboid Or Multi Target - cube
(今回は Single Image を選択します)
Trackable Scene Size :
Width : 認識させる画像の横幅を入力

上の内容を入力後、「Create Trackable」をクリックします。
次に画像を選択する画面が表示されます。「Upload」をクリックして画像を選択します。
画像のアップロードが完了すると下のような画面が表示されます。
アップロードした画像上に解析した結果?みたいなものが表示され、また右には★マークが表示されています。この★が多いほうが画像を認識しやすくなるみたいです。

最後にパンリストから「ImageTargets」をクリックしてtrackablesをダウンロードします。

これで認識させる準備は完了です。


次にプロジェクトにこれらを設定していきます。
上でダウンロードしたファイル「ImageTargets.zip」を解凍すると「ImageTargets.dat」と「ImageTargets.xml」というファイルができると思います。
これをXcodeのプロジェクトに配置します。
(プロジェクトにファイルを追加時「Copy items into destination group's folder」のチェックを忘れないように)

最後にImageTargetsAppDelegate.mmファイルを開き、以下のように修正します。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    QCARutils *qUtils = [QCARutils getInstance];
    
    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    window = [[UIWindow alloc] initWithFrame: screenBounds];
    
    [self setupSplashContinuation];
    
    // Provide a list of targets we're expecting - the first in the list is the default
    [qUtils addTargetName:@"Stones & Chips" atPath:@"StonesAndChips.xml"];
    [qUtils addTargetName:@"Tarmac" atPath:@"Tarmac.xml"];

    // ココを追記します
    [qUtils addTargetName:@"ImageTargets" atPath:@"ImageTargets.xml"];
    
    // Add the EAGLView and the overlay view to the window
    arParentViewController = [[ARParentViewController alloc] init];
    arParentViewController.arViewRect = screenBounds;
    [window insertSubview:arParentViewController.view atIndex:0];
    [window makeKeyAndVisible];
    
    return YES;
}

qUtils addTargetname:atPathを追記してビルド。
これでエラーがでなければ実機でデバッグしてみます。


こんなかんじでとりあえず動きました。

今回はImageTargetsのサンプルを動かしてみましたがほかにもいくつかサンプルがあるのでいろいろ試してみてください。


2012年5月2日水曜日

GestureRecognizerを使用して複数のジェスチャを認識させる方法

GestureRecognizerはそのままの状態では複数のジェスチャを同時に認識させることはできませんがUIGestureRecognizerDelegateプロトコルのメソッドから動作を変更させることができます。

ヘッダーファイル
@interface ViewController : UIViewController
<
    UIGestureRecognizerDelegate
>


対象のUIViewにUIGestureRecognizerを追加してDelegateを設定します。
UILongPressGestureRecognizer *longGesture = [[UIGestureRecognizer alloc]
 initWithTarget:self action:@selector(handleLong:)];
    longGesture.minimumPressDuration = 1.0f;
    longGesture.delegate = self; // ←ココ
    [aImageView addGestureRecognizer:longGesture];
    [longGesture release];

そして gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: を実装することで動作を変更することができます。
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
 shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

とまぁこんな感じです。
同時に認識させること自体はそれほど難しいものでもありませんがこれをどう使うか組み合わせるかけっこう迷う。