2010年6月29日火曜日

UIToolBarの透過処理

画面をタッチしたらツールバーの表示/非表示が切り替わるようにしました。アニメーション付きで。ひとまずこんな感じのコードになりました。

- (void)switchToolbar {
    // ツールバーの表示/非表示を切り替える
    [UIView beginAnimations:nil context:nil];
    {   
        // 時間を0.25とする
        [UIView setAnimationDuration:0.25];

        CGFloat toAlpha;
        if (toolbar_.hidden) {
            toolbar_.alpha = 0.0;
            toolbar_.hidden = NO;
            toAlpha = 1.0;
        }       
        else {  
            [UIView setAnimationDelegate:self];
            [UIView setAnimationDidStopSelector:@selector(animationDidStop)];
            toAlpha = 0.0;
        }       
        toolbar_.alpha = toAlpha;
    }   
    [UIView commitAnimations];
}

- (void)animationDidStop {
    toolbar_.hidden = YES;
}

toolbar_はIBOutletでUIToolBarにバインドしています。
beginAnimations:context:でアニメーションを開始し、alpha値を変化させることでフワッとツールバーの表示/非表示を切り替えています。

2010年6月27日日曜日

UIActionSheetにプログレスバーを表示する

iPhoneで処理をバックグラウンドで実行する方法を探していて辿り着きました。
今後参考にするかもしれないのでメモ。


ちなみに、バックグラウンド処理にはperformSelectorInBackground:withObject:メソッドを利用します。

Core DataのAttributeに配列を利用する

ちゃんと読んでないけど実現可能?メモ。

2010年6月26日土曜日

クラス定数はない

Objective-Cにクラス定数はないようです。
UIKitとかで使われている定数を見ると、typedef enumで定義されているみたい。
typedef enum {
    MyClassConstValue1,
    MyClassConstValue2,
} MyClassConstValue;

@interface MyClass : NSObject {

}

@end
あ、値を持つ定数はどうするのかな。

2010年6月25日金曜日

Apacheの設定メモ

ごくごく一部分のメモです。Debianでsites-enabled、mods-enabledを有効にするコマンド。

a2ensite

a2enmod

すみません。忘れがちなので…。

Core Data の migration

Core Dataのモデルを変更したときの対処方法です。以下のページ通りやればできるのではということでメモ。


ちなみに、.xcdatamodeldファイルは以下の方法で作成できます。
  1. .xcdatamodelを選択
  2. メニュー「設計」→「データモデル」→「モデルバージョンを追加」を選択

2010年6月24日木曜日

LogCatに何も表示されなくなった時の対応

たまーにLogCatに何も表示されなくなります。そのときの対応方法です。

  1. eclipseを終了
  2. ターミナルで以下のコマンドを実行する
    % adb kill-server
    % adb start-server
  3. eclipseを起動する

以上!

2010年6月22日火曜日

VirtualBoxのインストール

Windows Server 2003にVirtualBoxをインストールすることになりました。ゲストOSはDebianです。

  • VirtualBox 3.2.4をダウンロード。
  • デフォルトの設定でインストール。
  • インストール完了。おぉ、再起動を要求されなかった。
  • Debian 5.0.4のネットワークインストールCDイメージをダウンロード。
  • 新規で仮想マシンを作成。OS:Linux、バージョン:Debian。
  • ストレージ設定でダウンロードしたDebianのISOイメージを選択。
  • ネットワークの設定で「ブリッジアダプタ」に変更。
  • 起動。
  • 普通にインストール→完了。

とりあえず動いた。うん良いんじゃないかな。

2010年6月21日月曜日

Gitを使い始めるまで

いつも忘れるのでメモ。

設定


% git config --global user.name "Name"
% git config --global user.email "mail@example.com"
% git config --global color.ui auto

リモートリポジトリの作成


% mkdir /REPODIR/project.git
% cd project.git
% git init --bare
% cd WHERE
% git clone /REPODIR/project.git project

2010年6月20日日曜日

1日後のNSDateインスタンスを取得する方法

Objective-CのNSDateで日付を1日進めたいときにどうするかです。こうします。
// 日付のオフセットを生成
NSDateComponents *dateComp = [[NSDateComponents alloc] init];

// 1日後とする
[dateComp setDay:1];

// 1日後のNSDateインスタンスを取得する
NSDate *date = [[NSCalendar currentCalendar] dateByAddingComponents:dateComp toDate:[NSDate date] options:0];

[dateComp release];
1日前の日付を取得する場合は[dateComp setDay:-1]で、1ヶ月後とかだとsetMonthを利用します。

自作のUITableViewで編集モードに対応する

UITableViewControllerを使わず、UIViewControllerを継承してUITableViewを操作しています。
編集モード対応でちょっとはまったのでメモを残しておきます。

-tableView:commitEditingStyle:forRowAtIndexPath:を定義


これは当たり前。

-setEditing:animated:を定義


これが必要。こんな感じでUIViewControllerのメソッドをオーバーライドします。
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
    [super setEditing:editing animated:animated];

    // テーブルの編集モードを変更
    [myTableView setEditing:editing animated:animated];
}

2010年6月18日金曜日

pythonメモ

文字列を日付に変換

from datetime import datetime
date = datetime.datetime.strptime('2010/06/18 13:30', '%Y/%m/%d %H:%M')
# => datetime.datetime(2010, 6, 18, 13, 30)

iPhone4を予約

許可が得られたので今日(もう昨日か)地元のソフトバンクショップでiPhone4を予約してきました。
Wホワイトにばっちり強制加入させられたぜー。

iPhoneでSingleton

iPhoneでSingleton。あるインスタンスをたくさんのViewから参照したいです。URLをメモ。


以上です。

2010年6月17日木曜日

カメラのプレビューでFaceDetector

カメラのプレビュー画像で顔認識をやってみました。はまった点は

  • FaceDetector#findFaces()に渡すBitmapはARGB_8888じゃだめ

ってとこです。
RGB_565を使いました。

もっと言うと、モノクロ画像でも顔認識ができるっぽいので、プレビュー画像(YUV420)をRGB変換するのではなく、Y値だけ取り出した画像をfindFaces()に食わせました。

private Bitmap yuv2monochrome(byte data[], int width, int height, int[] buffer) {
    int y;

    for (int i = 0; i < width * height; i++) {
        y = data[i];
        buffer[i] = 0xff000000 | y << 16 | y << 8 | y;
    }

    return Bitmap.createBitmap(buffer, width, height, Config.RGB_565);
}

まぁ、FaceDetectorの処理にとても時間がかかるので、リアルタイムで顔認識はできないんですけど。
んー、微妙...

2010年6月16日水曜日

起動サービスの変更

RedHat系のディストリビューションでサーバ起動時に起動するサービスを変更する方法。
いっっつもコマンドを忘れて調べてしまうのでメモしときます。

chkconfig

2010年6月15日火曜日

フルスクリーン

Androidアプリケーションの画面をフルスクリーンにする方法です。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // タイトルバーを消す
    requestWindowFeature(Window.FEATURE_NO_TITLE);

    setContentView(R.layout.main);

    // ステータスバーを消す
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}

2010年6月14日月曜日

数字を3桁ごとにカンマ区切りにする

こんな感じでやってみた。

ヘッダ。
@interface MyViewController : UIViewController {
    // 3桁NumberFormatter
    NSNumberFormatter *formatter;
}
@property (nonatomic, assign) NSNumberFormatter *formatter;

コード。
- (NSNumberFormatter *)formatter {
    if (formatter == nil) {
        formatter = [[NSNumberFormatter alloc] init];
        [formatter setPositiveFormat:@"#,##0"];
    }

    return formatter;
}

- (void)dealloc {
    [formatter release];
    [super dealloc];
}

使ってみる。
str = [self.formatter stringFromNumber:[NSNumber numberWithInt:2010]];

NSTimerを停止する

参照したページ
えーと、こんな感じで良いのかな。

  • retainではなくassignで
  • (void)invalidate を使う
  • 使わないタイマーにはnilを
// ヘッダ
@property (nonatomic, assign) NSTimer *timer;

// 停止コード
[timer invalidate];
timer = nil;

2010年6月12日土曜日

Core Data デフォルトのデータを用意する

サンプルCoreDataBooksは初期起動時にいくつかの本の情報が入っています。あんな感じで、デフォルトのデータを提供したいのです。

CoreDataBooksはどうやってDocumentsディレクトリにCoreDataBooks.sqliteをコピーしているのかなーと「プロジェクト情報」を見たりなんなりで30分。結局ソースコードでコピーしている事が判明。最初に気づけと。

以下、手順です。

適当なプロジェクト、適当なデフォルトデータを作成する


ここでは、「Navigation-based Application」テンプレート、「Use Core Data for storage」付きでプロジェクトを作成。
アプリケーション起動後、+ボタンを連打し適当なデータを作成しました。

デフォルトデータをプロジェクトに追加する


さっき作った適当データは

/Users/ユーザ名/Library/Application Support/iPhone Simulator/バージョン/Applications/アプリ/Documents

あたりにあるので、それをXcodeのResourceグループあたりに放り込んでやります。


これでアプリケーションバンドルにデータが含まれるようになります。

データをコピーするようにコードを修正


AppDelegateのpersistentStoreCoordinator()というメソッドの中でデータをロードしているはずです。
そこを書き換えます。

変更前。
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"CoreDataTest.sqlite"]];

変更後。
NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"CoreDataTest.sqlite"];
NSFileManager *fileManager = [NSFileManager defaultManager];
// データがなければデフォルトデータをコピーする
if (![fileManager fileExistsAtPath:storePath]) {
    NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"CoreDataTest" ofType:@"sqlite"];
    if (defaultStorePath) {
        [fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
    }
}
NSURL *storeUrl = [NSURL fileURLWithPath:storePath];

これでデフォルトデータを提供できるようになりました。

2010年6月11日金曜日

Provisioning Profilesの作成とインストール

とうとう最後です。Provisioning Profileを作成します。手順の詳細はProvisioning Portal左上「How-To's」の「Creating Provisioning Profiles」に書いてあります。

Development Provisioning Profileの作成

  • 「Provisioning」→「Development」の「New Profile」ボタンを押下します。
  • 「Profile Name」を適当に入力します
  • その他適切に。

submitすると一覧に登録したProvisioning Profileが表示されます。

Development Provisioning Profileのインストール


作成したProfileをXcodeで使えるようにします。
  • Development Provisioning Profileの一覧にダウンロードボタンがあるので、押下しダウンロードする。
  • Xcodeのオーガナイザの「デバイス」→「Provisioning」にある「+ボタン」を押下し、ダウンロードしたProfileを選択する。

以上!さぁ、実機で動かしてみよう。

実機でアプリを動かす

  • Xcodeの左上を「iPhoneシミュレータ」から「iPhoneデバイス」にする。

これだけでOKなはず。実機で動いた。感動。いや、ほんとに長かった。

App IDの作成

実機でアプリケーションを動かすまであとちょっとです。今度はApp IDなるものを作成します。手順の詳細はProvisioning Portal左上「How-To's」の「Creating App ID」に書いてあります。

App IDの生成

  • 「App IDs」→「Manage」の「New App ID」ボタンを押下。
  • 「Description」を適当に入力。
  • 「App ID」を適切に入力。こちらの説明がわかりやすかったです。

Submitして完了!リストに追加したApp IDが表示されるはずです。

カメラのプレビューにOpenGLを重ねてみる

カメラのプレビューにOpenGLのモデルを重ねてみました。OpenGLのモデルは、ApiDemosのcom.example.android.apis.graphics.TranslucentGLSurfaceViewActivityで使われているCubeRendererを利用しました。
というか、むしろTranslucentGLSurfaceViewActivityにカメラのプレビューを突っ込んだ感じ。

まずは、layoutのXML。
<RelativeLayout
    android:id="@+id/RelativeLayout01"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    >
    <android.opengl.GLSurfaceView
        android:id="@+id/GlView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:keepScreenOn="true">
    </android.opengl.GLSurfaceView>
    <com.example.CameraView
        android:id="@+id/CameraPreview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
    </com.example.CameraView>
</RelativeLayout>
SurfaceViewを継承したCameraViewを追加しています。

次に、Activity。
package com.example;

import android.app.Activity;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

public class GLTestActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 画面を構築
        setContentView(R.layout.main);

        // GL
        GLSurfaceView glSurfaceView = (GLSurfaceView)findViewById(R.id.GlView);
        glSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0); 
        glSurfaceView.setRenderer(new CubeRenderer(true));
        glSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
    }
}
ポイントはGLSerfaceView#setEGLConfigChooser()とSurfaceHolder#setFormat()です。
CubeRendererクラスは、ApiDemosそのままです。

最後に、CameraView.java
package com.example;

import android.content.Context;
import android.hardware.Camera;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder _holder;
    private Camera _camera;

    public CameraView(Context context) {
        super(context);

        // サーフェイスホルダーの生成
        _holder = getHolder();
        _holder.addCallback(this);
        
        // プッシュバッッファの指定
        _holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public CameraView(Context context, AttributeSet attrs) {
        super(context, attrs);

        // サーフェイスホルダーの生成
        _holder = getHolder();
        _holder.addCallback(this);
        
        // プッシュバッッファの指定
        _holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        // カメラのプレビュー開始
        Camera.Parameters parameters = _camera.getParameters();
        parameters.setPreviewSize(width, height);
        _camera.setParameters(parameters);
        _camera.startPreview();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // カメラの初期化
        try {
            _camera = Camera.open();
            _camera.setPreviewDisplay(holder);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // カメラのプレビュー停止
        _camera.setPreviewCallback(null);
        _camera.stopPreview();
        _camera.release();
        _camera = null;
    }
}

実現はできたのですが、いまいち良く分かっていません。これ以上進むには、OpenGLの勉強が必要ですね...

デバイスの登録

少しずつ進んで行きます。次はデバイス(iPhone)を登録します。手順の詳細は「How-To's」の「Assigning Devices」に書いてあります。

Unique Device Identifier(UDID)の確認


UDIDとやらがデバイス登録に必要なので確認しておきます。
  • デバイス(iPhoneなど)を接続する
  • Xcodeを起動する
  • メニューの「ウィンドウ」→「オーガナイザ」を選択
  • デバイスを選択し表示される「Identifier」の値が次の手順で必要となる

デバイスを追加する


  • iPhone Provisioning Portalの「Device」→「Add Devices」を押下
    • 「Device Name」を適当に入力する
    • 「Device ID」に先ほど確認したUDIDを入力する
  • submit

証明書の取得

iPhone Developer Programへの登録が完了すると「iPhone Provisioning Portal」が利用できるようになります。
実機でのアプリ開発を目指し、このページで証明書の取得、デバイスの登録などを行っていきます。

まずは証明書の取得です。手順の詳細は、「How-To's」の「Obtaining your Certificate」に書いてあります。
以下に私の作業メモを残しておきます。

1. Certificate Signing Request(CSR)を生成

  • アプリケーション→ユーティリティ→キーチェーンアクセスを起動
  • メニュー「設定」→「証明書」の「OCR」と「CRL」が「切」になっていることを確認
  • メニュー「キーチェーンアクセス」→「証明書アシスタント」→「認証局に証明書を要求」を選択
    • メールアドレスと通称は、iPhone Developerに登録しているやつを入力
    • CAメールアドレスは空でOK
    • 「ディスクに保存」「鍵ペア情報を指定」をチェック
  • 任意の場所に保存する。2048bit、RSAで。

2. CSRを登録

  • 「iPhone Provisioning Portal」の「Certificates」→「Development」→「Request Certificate」を選択
  • さっき保存したCSRを選択し、submit

3. 証明書のダウンロードとインストール

しばらく待ってページをリロードすると、証明書一覧がこんな感じになるはず。
2つの証明書(.cer)をダウンロードします。
実行するとキーチェーンアクセスが起動し、証明書が登録されます。

4. 秘密鍵のバックアップ

How-To'sによるとしておくべきらしい。
  • キーチェーンアクセスでさっき作成した秘密鍵を選択
  • メニュー「ファイル」→「書き出す」
  • フォーマットは「個人情報交換(.p12)」
  • 保存が完了したら他のマシンで保管しておこう

2010年6月10日木曜日

iPhone Developer Program登録完了!

夜、サポートからメールがきました。
「もう1回アクティベーションコードをクリックしてみて」


無事、登録完了しました!
サポートの対応が早くてびっくりです。

続続・iPhone Developer Programに登録

あー、タイトルうぜーですね。
夕方、Apple Developer Supportからメールが来ました。対応が早いな。すごい。

アップルストアの購入履歴を見て
  1. 『ご請求、ご連絡先』
  2. 注文番号 (W+数字8桁)
を教えてくれとのこと。メール送った。

続・iPhone Developer Programに登録

昼頃にiPhone Developer Programのアクティベーションコードがメールで送られてきました。


早速メールのリンクをクリックすると、、、


エラー... orz
素直に「Contact Us」します。
「Your Region」を「Japan」にすれば日本語でメッセージを書いても大丈夫みたい。

送信したら「受理したからしばし待て」的なメールが来た。
待ちますとも。

iPhone Developer Programに登録

今までエミュレータでアプリケーションを作り込んできたけど、そろそろ実機で動かしたくなりました。
iPhone4も出るしここいらでiPhone Developer Programに登録してしまえってことで登録してみました。

登録方法についてはネット上のいたるところに情報が転がっているので割愛しますが、
アカウント情報に2バイト文字が含まれないように注意し、手続きを進め、
無事にApple Online Storeで購入するところまでいきました。

24時間以内にメールが届くって事なので待っときます。
以下、この先の作業で参考にしようと思っているページです。


明日が楽しみだ。

2010年6月9日水曜日

カメラのプレビュー画像をいじってみる(2)

数日前にやっていたカメラのプレビュー画像操作。実機で色々試したあげく、以下のコードに落ち着きました。他にやりようあるかしら。

private class PreviewDraw implements Runnable {
    private byte[] _data;

    @Override
    public void run() {
        bitmap = BitmapUtil.yuv2rgb(_data, _previewSize.width, _previewSize.height, _rgbBuffer);

        // 描画
        if (bitmap != null) {
            Canvas canv = holder.lockCanvas();
            if (canv != null) {
                canv.drawBitmap(bitmap, 0, 0, null);
                holder.unlockCanvasAndPost(canv);
            }
        }
    }

    public void setData(byte[] data) {
        _data = data;
    }
}

private final Camera.PreviewCallback previewCallback =
    new Camera.PreviewCallback() {
        public void onPreviewFrame(byte[] data, Camera camera) {
            _previewDraw = new PreviewDraw();
            _previewDraw.setData(data);
            Thread thread = new Thread(_previewDraw);
            thread.start();
        }
    };

YUV420からRGBの変換で1.2秒くらい時間がかかってます。はっきり言って現実的ではないです。
モノクロ画像の表示(Y成分だけ抜き出す)でも0.3秒くらいかかります。うーん。

2010年6月8日火曜日

git archive

いつも忘れるのでメモしておきます。gitでtar.gzを作成する方法です。

git archive --format=tar --prefix=project-dir/ HEAD | gzip > project.tgz

2010年6月7日月曜日

結局Hummings2に

mac版のtwitterクライアントを色々試していたのですが、結局、初めて使ったHummings2に落ち着きました。マウスを使わずに操作できる点が秀逸です!

2010年6月6日日曜日

xperia googleアカウントの削除

会社のxperiaに個人のgoogleアカウントを設定してしまいました。
メニューなどから簡単に変更ができる訳ではないみたい。
以下、googleアカウントの削除方法です。

  1. 「設定」→「アプリケーション」→「アプリケーションの管理」
  2. 「google apps」を選択
  3. 「データの削除」を選択

これでgoogleアカウントの情報が削除されるみたいです。
必要ならば、「Gmail」なども同様に「データの削除」をしとくと良いかも。

ApiDemos(1.6)のビルド

Android 1.6のApiDemosがエラーになってビルドできませんでした。
原因は「IRemoteServiceを解決できない」とか「Rを解決できない」とかとか。
確かにgenの下にR.javaができていません。
R.javaは勝手に作成されるのでは?と思いつつ調べても解決できず。

ふとコンソールをみると、string.xmlにエラーがあるとのこと。

ApiDemos/res/values/strings.xml:365: エラー: Apostrophe not preceded by \ (in I'm on! :))
ApiDemos/res/values/strings.xml:366: エラー: Apostrophe not preceded by \ (in I'm off! :()
ApiDemos/res/values/strings.xml:643: エラー: Apostrophe not preceded by \ (in The Android platform is a software stack for mobile devices including an

言われた通りに、'(アポストロフィ)の前に\(バックスラッシュ)を入れてみると。。。

ビルドできました!

2010年6月2日水曜日

Blogger Syntax Highlighterを導入しました

以下のページを参考にし、ソースコードをハイライトする「Blogger Syntax Highlighter」を導入しました。
以下、導入の手順です。

1.FaziBear's Blogger Widgetsのページにアクセスするも...

なんか「添付ファイルをダウンロード」となってしまい、期待するページに行きませんでした。


しょうがないので素直にblogger.htmlをダウンロードしました。

2.blogger.htmlをブラウザで表示

WEBブラウザで表示してみました。


お、それっぽい。「Add to Blogger」をクリック。

3.Bloggerに追加

ログインすると以下の画面に。


タイトルを空にしてから「ウィジェットを追加」をクリックします。そうしないと、ブログのウィジェット欄に入力したタイトルが表示されてしまいます。


保存すれば終了。

4.これで使えるはず

試してみます。

<pre name="code" class="c">
int main() {
  printf("Hello, World!");

  exit(0);
}
</pre>
int main() {
  printf("Hello, World!");

  exit(0);
}

できた!

カメラのプレビュー画像をいじってみる(1)

Androidカメラのプレビュー画像をいじってみたいと思っています。リアルタイムで白黒反転したりしたいなーと。

単純にカメラのプレビュー画像をアプリケーション上で表示したいなら、SurfaceViewを生成してCamera#setPreviewDisplay()でSurfaceHolderを渡してあげれば良いんだけど、それだとプレビュー画像をいじれない。

プレビュー画像を横取りするには、Camera.PreviewCallbackを利用します。
紆余曲折いろいろなサイトを参考にこんなん作ってみました。

layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<framelayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<com.example.CameraView
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:id="@+id/SurfaceView01" 
/>
</FrameLayout>

CameraTest.java
package com.example;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;

public class CameraTest extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.main);
    }
}

CameraView.java
package com.example;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.hardware.Camera;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.util.AttributeSet;

public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
 private SurfaceHolder holder;
 private Camera camera;
 private Bitmap bitmap;
 private int[] rgb;
 private int width, height;

 /**
  * プレビューコールバック
  *   prepareSavePreviewImageコールバックで登録され、プレビュー画像を取得する
  */
 private final Camera.PreviewCallback _previewCallback =
  new Camera.PreviewCallback() {
  public void onPreviewFrame(byte[] data, Camera camera) {
   decodeYUV420SP(rgb, data, width, height);
   bitmap.setPixels(rgb, 0, width, 0, 0, width, height);

   // 描画
   Canvas canv = holder.lockCanvas();
   canv.drawBitmap(bitmap, 0, 0, null);
   holder.unlockCanvasAndPost(canv);
  }
 };
 
 // コンストラクタ
 public CameraView(Context context) {
  super(context);
  this.initialize();
 }

 // コンストラクタ
 public CameraView(Context context, AttributeSet attrs) {
  super(context, attrs);
  this.initialize();
 }

 // 初期化処理
 private void initialize() {
  // サーフェイスホルダーの生成
  holder=getHolder();
  holder.addCallback(this);

  // サーフェイスホルダーのタイプを設定
  holder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);

  // 画像を読み込んでおく
 }

 // サーフェイス生成イベントの処理
 public void surfaceCreated(SurfaceHolder holder) {
  // カメラの初期化
  try {
   camera=Camera.open();
   camera.setPreviewCallback(_previewCallback);
  } catch (Exception e) {
  }
 }

 // サーフェイス変更イベントの処理
 public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
  // 描画データの準備
  width = w;
  height = h;
  bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
  rgb = new int[w * h];

  // カメラのプレビュー開始
  Camera.Parameters parameters = camera.getParameters();
  parameters.setPreviewSize(w, h);
  camera.setParameters(parameters);
  camera.startPreview();
 }

 //サーフェイス解放イベントの処理
 public void surfaceDestroyed(SurfaceHolder holder) {
  // カメラのプレビュー停止
  camera.stopPreview();
  camera.setPreviewCallback(null);
  camera.release();
  camera = null;
 }

 // YUV420 to BMP
 static public void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {
  final int frameSize = width * height;

  for (int j = 0, yp = 0; j < height; j++) {
   int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
   for (int i = 0; i < width; i++, yp++) {
    int y = (0xff & ((int) yuv420sp[yp])) - 16;
    if (y < 0) y = 0;
    if ((i & 1) == 0) {
     v = (0xff & yuv420sp[uvp++]) - 128;
     u = (0xff & yuv420sp[uvp++]) - 128;
    }

    int y1192 = 1192 * y;
    int r = (y1192 + 1634 * v);
    int g = (y1192 - 833 * v - 400 * u);
    int b = (y1192 + 2066 * u);

    if (r < 0) r = 0; else if (r > 262143) r = 262143;
    if (g < 0) g = 0; else if (g > 262143) g = 262143;
    if (b < 0) b = 0; else if (b > 262143) b = 262143;

    rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
   }
  }
 }
}

少し動かすとOutOfMemoryになってちゃんと動かない。Camera.Parameters#setPreviewFrameRate(1)とかやってやると落ちずに動く。
実機でやるとまた違う結果が出るかしら。

Project2003を使ってみました

線表を作成する必要があったのでMicrosoftのProject2003を使ってみました。初めて使うに当たってまったく初めて使う人のための Project 2003 入門を参考に基本的な使い方を学びました。いくつかポイントを紹介したいと思います。

ビューバーの表示

メニューの「表示」→「ビューバー」を選択するとビューバーが表示されます。ガントチャートやリソースシートを切り替えるのに便利です。

稼働時間の変更

「ツール」→「稼働時間の変更」で稼働時間を変更できます。例えば「土曜は働くよ!」みたいな。


プロジェクトの開始日

「プロジェクト」→「プロジェクト情報」でプロジェクトの開始日を設定できます。これを適切に設定しないでタスクを作成すると、開始日が2003年になってしまいました。7年前か。。。


マイルストーンの設定

タスクの期間を0にするとマイルストーンとなります。


期間の?

新規タスクを追加したときに「期間」の欄に表示される「?」は見積もり期間を表すそうです。これを表示しないようにするには。。。
「ツール」→「オプション」→「スケジュール」→「新しいタスクに見積もり期間を設定する」のチェックを外します。

アウトラインを設定する

「レベル下げ」を利用してタスクのアウトラインを行います。


タスクの依存関係を設定する

タスクを複数選択し、リンクボタンを押すことで依存関係を作成します。


担当者の設定

1.リソースシートを表示します

2.リソース名に名前を入力します


3.ガントチャートに戻って、「ツール」→「リソースの割り当て」でタスクに担当者を設定します