iPhone

2013年10月24日

iPhone 用アプリ「ExifSafe」について

はてなブックマークに登録

先日の記事 「Exif データにアクセスするコードを自作してみる」 では、よく知られた存在でありながらプログラムを書く際にブラックボックスとして扱われがちな Exif の仕様と構造の整理を行い、既存のライブラリへ依存せずに Exif データを操作することを目的に作成したコードを紹介しました。当初はパーサとしての機能がメインでしたが、後日以下の機能を実装しました。

  • 所定の IFD の削除・追加
  • Exif タグフィールドの削除・追加・変更
  • Exif サムネイルデータの取得
ソースコード: GitHub - exif

また、このコードを実際に使って次のような iPhone 向けアプリを試作してみました。
「ExifSafe」という名前をつけています。

  • アルバム上の所定の画像に含まれる Exif データを一覧表示
  • Exif データに GPS 位置情報が含まれる場合はマップで撮影地点を表示可能
  • 画像をメールで送信
    • Exif データを丸ごと削除して添付、またはプライバシーに関わりのあるデータのみ削除して添付、または元のまま添付
    • 画像の添付ファイル名には Exif データから取得した撮影日時情報が反映される
      ※「写真.jpg」のような識別性に乏しいシステム既定の添付名の不便さを補うもの
  • 画像から Exif データを削除したコピーを作成
    • Exif データを丸ごと削除してコピー、またはプライバシーに関わりのあるデータのみ削除してコピー
    • コピーした画像は 専用のアルバムから参照可
次の場所で公開しています。興味のある方はお試し下さい。
iTunes App Store - ExifSafe
ソースコード: GitHub - ExifSafe


(tanabe)
klab_gijutsu2 at 21:00|この記事のURLComments(0)TrackBack(0)
2011年02月24日

ソーシャル携帯電波マップを作ろう

はてなブックマークに登録

先週出張で東京に来ました。いつものように東北新幹線です。

道中2時間半いつも特に何をすると決めている訳ではなく、まあ寝るか、本を読むか、iPhoneを片手にメールやサイトチェックをするか、うーん、大体は寝ているんじゃないでしょうか私。眠いもの。

ただ、今回いつもとは違いめずらしく眠気がなかったので、おもむろにMacBook Airを開いてcodingなんぞやろうかという気になりました。しかしそれがいけなかった。まだ購入してから間もない状態だったので、環境が全く整ってない。それどころか書こうとしていたソースコードパッケージすら入れてないときたもんだ。…いや、まあ、でもこういうときに備えてMobileMeのストレージにスナップショットを置いてあったりしただろ落ち着け俺、とやおらPocketWifiを取り出してダウンロードを始めた。が、落ちて来ない。

そうだった。東京から宇都宮〜那須塩原あたりまでのだだっ広い関東平野goes onならいざ知らず、上り列車乗り込んですぐの盛岡あたりでは移動の途中で圏外になることも多く、なかなか使い物にならないのである。市街地はそこそこにしてすぐに田園と山林風景のど真ん中を行くことになるわけだから、ビジネス用途の強いイーモバイルの電波は届かなくても仕方が無いのだ。こいつはぎゃふんだ。

というわけで、行きの電車内で大いに苦しめられたこの電波状況、キャリアのサービスマップだけでは分からない、「ほんとにほんとのところどうなのよ?」というあたりを調べてみようと思った。言ってみればユーザ実測によるリアルサービスマップ。ソーシャル時代の今ならこれをみんなで寄せ集めて日本全国くまなく調査することだって夢じゃない。そうそう、時代はソーシャル…、と、そんなことを妄想しながらその後ほどなく私がふて寝に入ったのは言うまでもない。

概要はこうだ。新幹線で移動する間中、ずっとGPSで現在位置を把握する。そして並行してPINGを打ち続け、GPSでの位置・PING送信・応答これら3つのイベントを時間軸に沿って記録する。後でこれを地図上にプロットしてみようというわけだ。

手元にあるのはiPhoneとMacBook Air。iPhoneにはGPSがついているので問題ない。PINGの実装はちょっと悩んだが、Cocoaのサンプルコードにちょうど"SimplePing"というそのものズバリなものがあるのを見つけた。Mac用となってはいるが、iOS用にも移植できるんじゃないかと見立て、これを持って来てみた。

http://developer.apple.com/library/mac/#samplecode/SimplePing/Listings/SimplePing_m.html
SimplePing: SimplePing.m

幸いADC(Apple Developer Connection)に登録しているので、iPhoneにアプリケーションを転送して実機でアプリを動かすことはできる。ここまで調べたところで出張が終わり、さあ帰りの新幹線の便となった。

帰りの新幹線。シートに座ってMacBook Airを開いて作業を開始。列車も東京駅を出発。途中小山駅を過ぎたあたりで空腹が勝りすぎて弁当を食さずにはいられなくなるなどアクシデントに遭いつつも、白石蔵王を通り過ぎ仙台駅にさしかかったあたりまでで一通りのものが出来た。

やった内容は大まかにこう。

  • まず、Xcode上でFile > New > New Projectのメニューを選び、iOS Applicationから新規アプリケーションを作成する。"Navigation-based"でも、"Tab bar"でも何でも良い。名前も何でも良い。
  • SimplePingから、SimplePing.{h,m}ファイルを持ってくる。また、SimplePingがPING応答の際にコールバックするdelegateクラスがmain.m中にあるので、それを持ってくる。
  • 上記のdelegateクラスを今回新規作成したアプリケーションにおけるNSApplicationのdelegateクラスに対するカテゴリ(Mix-in)として実装に追加する。
  • アプリケーション起動時に呼び出されるコールバックメソッド"application:didFinishLaunchingWithOptions:"において、GPSおよびPING送信を開始するためのコードを追加。
  • さらに、GPS出力およびPING送受信の結果を記録するデバッグログを追加。
  • ↑の情報は、作業工程圧縮のためiPhone上でのデータ書き込み機能を実装せず、とりあえずXcodeデバッガの出力に任せる。iPhoneはMacにUSB接続したまま動かす。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    // Add the navigation controller's view to the window and display.
    self.window.rootViewController = self.navigationController;
    [self.window makeKeyAndVisible];
    // ↑ここまでテンプレート

    // ここからGPS準備
    _locationManager = [[CLLocationManager alloc] init];    
    _locationManager.delegate = self;
    [_locationManager startUpdatingLocation];

    // ここからPING準備    
    self.pinger = [SimplePing simplePingWithHostName:@"www.klab.jp"];
    self.pinger.delegate = self;
    [self.pinger start];
       
    return YES;
}

ざっとこのくらい。これで一応デバッグログにPING送受信とGPSの結果がタイムスタンプとともに吐き出されるので、最低限のデータが取れる。本来ならMapKitと組み合わせてリアルタイムに地図表示まで持っていきたかったところだが、敢えなく時間切れ。

さて仙台を抜け、多くの客が降りだいぶ客席にも余裕ができた頃、最初の試行を開始。しかしそのときちょうどトンネルに入ったらしく、あっけなく問題が発生。上記コード例から分かるように"www.klab.jp"へのPING送信のため名前解決をしているのだが、起動時にしくじるとリトライをしない実装になっているため、トンネルを抜けるまで始められないというバグにぶちあたった。

そうなのだ。仙台から北はまさに行きで悩まされた難受信地域。一足遅かったか…と一瞬天を仰ぐも、気をとりなおしてトンネルを抜けてアンテナが立つと共にリトライ。その後も途中何度も圏外になり、細かいデバッグや調整を繰り返しながら、何とかデータを取ることができた。

データを時間軸で残すようにしたのは大正解だった。作業時間の圧縮のため、デバッグログNSLog()関数での出力にせざるを得なかったが、デフォルトでタイムスタンプ込みの出力をしてくれるため大変助かった。

何しろ、PINGの送信時点と応答受信時点のタイムスタンプを計算すればRound Trip Timeが計れるが、そのくらいアプリケーション内で計算できれば本当はよいものの、デバッグログに逃がすことでその計算も後回しにすることができたのだから。お尻の時間が決まっている場合は、「イカにして必要な作業に集中して手間と時間を投入するか」が重要になってくるということじゃなイカ?

さて、この次にデータをいよいよ地図上に表示する作業に移るわけだが、ここまできてはたと気がついた。Macでネットワークがつながらず往生したのはPocketWifiでだったが、今回iPhoneはそのまま3G回線、すなわちソフトバンク経由でPING送っていたということに…。

まあ、そんなこともありますよね。えへ。

(こうら ひろのぶ)

klab_gijutsu2 at 20:49|この記事のURLComments(0)TrackBack(0)
Blog内検索
Archives
このブログについて
DSASとは、KLab が構築し運用しているコンテンツサービス用のLinuxベースのインフラです。現在5ヶ所のデータセンタにて構築し、運用していますが、我々はDSASをより使いやすく、より安全に、そしてより省力で運用できることを目指して、日々改良に勤しんでいます。
このブログでは、そんな DSAS で使っている技術の紹介や、実験してみた結果の報告、トラブルに巻き込まれた時の経験談など、広く深く、色々な話題を織りまぜて紹介していきたいと思います。
最新コメント