今年も行ってきました。
2014年2月10日月曜日
2014年2月7日金曜日
Android の Intent が宝の持ち腐れ
ちょっ、Android の開発に関して、ぼやきます。
Intent を介してアプリケーションが連帯する仕組みが整っているのに、ファイル選択ダイアログといった単純なパーツさえ、自分でエクスプローラのアプリケーションを作成する勢いで書かないと、存在しない。
例えば、zip ファイルを選択させたいと思ったら、既存の枠組みでは、
そうすると無料の広告付きアプリを入れてくるか、android-file-dialog(広告付きのオープンソース:改造可)を用意するか、とにかくイケてない。
ま、検索すれば AlertDialog.Builder ベースのファイル選択ダイアログというパーツも見つかるのだが、アクセス権限のないディレクトリに触った瞬間落ちるし、なんか、いけてない。Google さんも、Android の UIガイドと啓蒙みたいな部分に力を入れるよりも、こういった連帯ベース部分に力を入れたほうが、よほどエコなんじゃないでしょうか?
private static final int REQUEST_CHOOSE_ZIP = 1;
...
private void selectZip() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
// MIME/Type が微妙だが置いといて
intent.setType("application/zip");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, REQUEST_CHOOSE_ZIP );
}
と、呼び出してやれば済む話なのであるが、Androidに付属している標準のエクスプローラ・アプリは、得てして、この仕様に対応していない。そうすると無料の広告付きアプリを入れてくるか、android-file-dialog(広告付きのオープンソース:改造可)を用意するか、とにかくイケてない。
ま、検索すれば AlertDialog.Builder ベースのファイル選択ダイアログというパーツも見つかるのだが、アクセス権限のないディレクトリに触った瞬間落ちるし、なんか、いけてない。Google さんも、Android の UIガイドと啓蒙みたいな部分に力を入れるよりも、こういった連帯ベース部分に力を入れたほうが、よほどエコなんじゃないでしょうか?
2014年1月6日月曜日
SD-1 merrill を買いました
皆さん、明けましておめでとうございます。
ファインダーのついてるカメラが欲しくなったのと、NEX-5Rのクオリティでは我慢できなくなってきたので、カメラを買い替えました。Sigma の SD-1 merrill で、foveon センサという、ちょっとユニークなカメラです。撮れる画像は、はまった時には超一流、だけど、その他の部分は、色々と酷評されている面から考えてもユニークなカメラです。
最近、目が肥えてきて、フルサイズのセンサーで撮影された写真が、なんとなくわかるようになってきました。なので、フルサイズにも惹かれてて、価格的にD610やEOS6Dも圏内でした。NIKON のカメラで撮影されたRAWデータを触らせてもらった事があるのですが、ダイナミック・レンジが半端なく広く感動していた事もあり、D610が有力だったんですが、レンズまで含めると、フルサイズのカメラは、価格的に、かなりしんどい。どうせD610行くならD800Eぐらいのが欲しいというのも頭をかすめました。
PENTAXのK-3も気になってはいたんですが、K-5IIsと比べて、画質は落ちるんじゃないかという部分と、APS-Cサイズな点で、結局SD-1 merrill を選択しちゃいました。
まだ少ししか触ってないんですが、早くも難しいカメラを選んでしまったというのが率直な感想です。ベイヤー方式と異なるカメラなので、RAWデータを弄る感覚が、今までと全く違う。実際どうなのかは、わかりませんが、ダイナミック・レンジは狭いんじゃないかな?という気がしてます。もしくは、現像ソフトで引き出せるダイナミック・レンジが狭いのか?12bit階調しかない NEX-5RのRAWデータでさえ、暗い部分を持ち上げて明るい部分を抑える芸当が、そこそこ効くのに、SD-1 merrill のRAWデータは、どれかを動かすと全体的に追従してきてしまう。しかも、白飛びした部分の潰れ方が極端で、ベタっとします。
手応えとしては、SD-1 merrill こそ HDR 向きなのではないかと感じている次第です。
rsync 備忘録
3台のマシンがあって、入り口のマシンは1台。いちいちコピーしてたら日が暮れるので、ファイル転送部分だけは定型化しておく事にした。
MenteMachine 上に
/home/foo/to_main
/home/foo/to_sub
MainMacihne 上に
/home/foo/to_mente
SubMacihne 上に
/home/foo/to_mente
と、こんな感じディレクトリを構築しておく
MenteMachine 上に、データを収集するためのシェル
- MenteMachine
- MainMachine
- SubMachine
MenteMachine 上に
/home/foo/to_main
/home/foo/to_sub
MainMacihne 上に
/home/foo/to_mente
SubMacihne 上に
/home/foo/to_mente
と、こんな感じディレクトリを構築しておく
MenteMachine 上に、データを収集するためのシェル
#!/bin/bash rsync -av --delete -e 'ssh -c arcfour' foo@MainMachine:/home/foo/to_mente/ /home/foo/to_main/ rsync -av --delete -e 'ssh -c arcfour' foo@SubMachine:/home/foo/to_mente/ /home/foo/to_sub/MenteMachine 上のデータを配送するためのシェル
#!/bin/bash rsync -av --delete -e 'ssh -c arcfour' /home/foo/to_main/ foo@MainMachine:/home/foo/to_mente/ rsync -av --delete -e 'ssh -c arcfour' /home/foo/to_sub/ foo@SubMachine:/home/foo/to_mente/
2013年12月20日金曜日
mac osx 環境変数 忘備録
関連ファイル
/etc/profile
/etc/bashrc
ターミナルを開く毎に実行
~/.bashrc
ログイン時に実行
~/.profile
~/.bash_profile
自分は、~/.profile に記述してるよ
## # Cinder part ## # export CINDER_HOME=/usr/local/src/cinder_0.8.2_mac ## # Cuda SDK part ## export PATH=/usr/local/cuda/bin:$PATH export DYLD_LIBRARY_PATH=/usr/local/cuda/lib:$DYLD_LIBRARY_PATH export GPU_INCDIR="/Developer/GPU Computing/C/common/inc" export C_INCLUDE_PATH=$GPU_INCDIR:$C_INCLUDE_PATH export CPLUS_INCLUDE_PATH=$GPU_INCDIR:$CPLUS_INCLUDE_PATH ## # Android NDK part ## export ANDROID_NDK=/opt/android-ndk-r8d export PATH=$ANDROID_NDK:$PATH export ANDROID_TOOLCHAIN_CMAKE=$ANDROID_NDK/toolchains/android.toolchain.cmake alias android-cmake='cmake -DCMAKE_TOOLCHAIN_FILE=$ANDTOOLCHAIN ' ## # Your previous /Users/okimiyuki/.profile file was backed up as /Users/okimiyuki/.profile.macports-saved_2012-06-03_at_22:46:38 ## # MacPorts Installer addition on 2012-06-03_at_22:46:38: adding an appropriate PATH variable for use with MacPorts. export PATH=/opt/local/bin:/opt/local/sbin:$PATH # Finished adapting your PATH environment variable for use with MacPorts.
2013年11月14日木曜日
postgresql から json
php で postgresql からデータを取り出して JSON に加工して返すとか、めんどくさいなぁと思って調べてみました。社員に、どうやって実装してたん?て聞いたら、データ取り出して加工してたという事でした。うんうん、やっぱそうだよなー、面倒くせぇwwwwて思ってたんですが、ラッキーな事に、version 9.2 から row_to_json という関数がサポートされたようです。
まずは、データ準備
create table hoge (id integer primary key, name text); insert into hoge (id,name) values (1, 'fuga'); insert into hoge (id,name) values (2, 'moge');ほんで、取り出し
select array_to_json( array_agg( row_to_json(foo) ) ) from (select id, name from hoge) foo;結果
[{"id":1,"name":"fuga"},{"id":2,"name":"moge"}]
いやー、素晴らしいですね!
参考:Faster JSON Generation with PostgreSQL
2013年10月31日木曜日
CakePHP データ型による input 項目の決定方法
CakePHPのバージョンが 1.x の時も調べたような気がするのだけども、忘れたので備忘録として 2.x の仕組みをさぐる。
正直、ここら辺の実装の仕方は、気に入らない部分なんですよね。
まず、label タグと、input タグが混ざってコード中に隠蔽されていて、デザインの介在する余地が無い。1.x 時よりは、だいぶ良くなっている気がするけど、それでもダーティで、とてもDRYの原則に沿った修正ができるような代物ではない。改造しようと思ったら、ここら辺の仕組みを、ほぼ書き直ししないといけない。もしくは個別に何度も同じ作業を手作業で繰り返しながら個別に指定するかだ。
FormHelper::input( $field, $options );
で呼び出される $options は、テンプレート・ベースでは、通常 null だ。
その場合、FormHelper::_magicOptions($options) により、デフォルトのオプションが構築される。
そして、ここで input タグが text なのか select なのか checkbox なのか・・・と決定されるのである。
やるなら、_magicOptions をラップした public な magicOptions 関数を作成して、テンプレートの Form::input 呼びだし直前で options を取得し、その options の値を元に、デザインを細かく変更できるようにリファクタリングが、一番の近道だろうか?
FormHelper::input( $field, $options );
で呼び出される $options は、テンプレート・ベースでは、通常 null だ。
その場合、FormHelper::_magicOptions($options) により、デフォルトのオプションが構築される。
そして、ここで input タグが text なのか select なのか checkbox なのか・・・と決定されるのである。
やるなら、_magicOptions をラップした public な magicOptions 関数を作成して、テンプレートの Form::input 呼びだし直前で options を取得し、その options の値を元に、デザインを細かく変更できるようにリファクタリングが、一番の近道だろうか?
protected function _magicOptions($options) {
$modelKey = $this->model();
$fieldKey = $this->field();
$options['type'] = 'text';
if (isset($options['options'])) {
$options['type'] = 'select';
} elseif (in_array($fieldKey, array('psword', 'passwd', 'password'))) {
$options['type'] = 'password';
} elseif (in_array($fieldKey, array('tel', 'telephone', 'phone'))) {
$options['type'] = 'tel';
} elseif ($fieldKey === 'email') {
$options['type'] = 'email';
} elseif (isset($options['checked'])) {
$options['type'] = 'checkbox';
} elseif ($fieldDef = $this->_introspectModel($modelKey, 'fields', $fieldKey)) {
$type = $fieldDef['type'];
$primaryKey = $this->fieldset[$modelKey]['key'];
$map = array(
'string' => 'text', 'datetime' => 'datetime',
'boolean' => 'checkbox', 'timestamp' => 'datetime',
'text' => 'textarea', 'time' => 'time',
'date' => 'date', 'float' => 'number',
'integer' => 'number'
);
if (isset($this->map[$type])) {
$options['type'] = $this->map[$type];
} elseif (isset($map[$type])) {
$options['type'] = $map[$type];
}
if ($fieldKey == $primaryKey) {
$options['type'] = 'hidden';
}
if (
$options['type'] === 'number' &&
$type === 'float' &&
!isset($options['step'])
) {
$options['step'] = 'any';
}
}
if (preg_match('/_id$/', $fieldKey) && $options['type'] !== 'hidden') {
$options['type'] = 'select';
}
if ($modelKey === $fieldKey) {
$options['type'] = 'select';
if (!isset($options['multiple'])) {
$options['multiple'] = 'multiple';
}
}
if (in_array($options['type'], array('text', 'number'))) {
$options = $this->_optionsOptions($options);
}
if ($options['type'] === 'select' && array_key_exists('step', $options)) {
unset($options['step']);
}
$options = $this->_maxLength($options);
return $options;
}
登録:
投稿 (Atom)





