Hatena::ブログ(Diary)

NAT’s Programming Champloo このページをアンテナに追加 RSSフィード

2014-05-06

[]Unity+Vuforia+MMD4Mecanimで初音ミクが踊るAndroidARアプリを作ってみた

UnityARアプリが簡単に作れると知って、ちょっと試してみたら、案外簡単にできた。その作り方を簡単なメモとして記録しておく。

作ったARアプリAndroidアプリARマーカーをカメラで映すと、初音ミクが曲に合わせて踊るというもの。カメラ機能で撮影も可能。CDのジャケットでもARマーカーにできると思う。

f:id:NAT_programming:20140506215347p:image

曲はラマーズPのWAVEFILEで、モーションはhinoさん作成のもの、モデルはコロン式初音ミクをお借りしました。

ARマーカーは、特徴点が抽出できる絵なら何でも良いようなので、ボカロ関連のイベントを集めたサイトVOCALENDARの宣伝用カードを利用(ステルスマーケティング)。

所要日数は、初めてUnityインストールしてからチュートリアルで基礎を勉強する期間も含めて2日間かかった。

続きを読む

2014-01-01

[][]RSSフィードを集約したフィードを生成するWebアプリSinatraで作ってみた

久し振りのプログラミング記事更新。

ボカロ関連のニュース情報を集めたフィードが欲しいと思い、RSSフィードを集約したフィードを生成するWebアプリSinatraで作ってみた。

完成形は、下記のURLより参照できる。

Vocafeeds - ボカロ関連ニュース集約フィード

RSSの解析と生成には、標準のrssライブラリを使用。

GoogleアラートフィードATOM形式でrssライブラリでは解析できないので、REXMLライブラリで解析。

コードは下記のようになった(一部抜粋)。

hatenaメソッドRSSの解析、add_itemメソッドATOMの解析に相当。

require 'rubygems'
require 'sinatra'
require 'date'
require 'open-uri'
require 'rss'
require 'rexml/document'

configure do
  HATENA_URL = 'http://b.hatena.ne.jp/t/VOCALOID?sort=hot&threshold=&mode=rss'
  VOCALOID_GUIDE_URL = 'http://vocaloguide.com/feed'
  GOOGLE_ALERT_NEWS_VOCALOID_URL = 'http://www.google.com/alerts/feeds/11697367392137858374/16433312303441767819'
  GOOGLE_ALERT_NEWS_CHARACTER_URL = 'http://www.google.com/alerts/feeds/11697367392137858374/4844081763401052883'
  GOOGLE_ALERT_VOCALOID_URL = 'http://www.google.com/alerts/feeds/11697367392137858374/12241483289961948968'
  GOOGLE_ALERT_VOCALOID_ENGLISH_URL = 'http://www.google.com/alerts/feeds/11697367392137858374/7009353441646457352'
end

get '/feeds' do
  output = RSS::Maker.make("1.0") do |maker|
    maker.channel.about = "http://vocafeeds.champl.org/feeds"
    maker.channel.title = "Vocafeeds ボカロ関連ニュース集約フィード"
    maker.channel.description = "ボカロ関連ニュースのフィードを集約したフィード。"
    maker.channel.link = "http://vocafeeds.champl.org/"
    maker.items.do_sort = true

    hatena(maker)
    add_item(GOOGLE_ALERT_NEWS_VOCALOID_URL, maker)
    add_item(GOOGLE_ALERT_NEWS_CHARACTER_URL, maker)
    add_item(GOOGLE_ALERT_VOCALOID_URL, maker)
    add_item(GOOGLE_ALERT_VOCALOID_ENGLISH_URL, maker)
    add_item(VOCALOID_GUIDE_URL, maker)
  end
  content_type "application/xml"
  output.to_s  
end

def hatena(maker)  
  open HATENA_URL do |http|
    hatena = RSS::Parser.parse(http.read)
    hatena.items.each do |entry|
      next if entry.link =~ %r{http://www.nicovideo.jp/watch/}
      
      maker.items.new_item do |item|
        item.link = entry.link
        item.title = entry.title
        item.description = entry.description
        item.date = entry.date
      end        
    end
  end
end

def make_rss(about, title, description, link, &block)
  output = RSS::Maker.make("1.0") do |maker|
    maker.channel.about = about
    maker.channel.title = title
    maker.channel.description = description
    maker.channel.link = link
    maker.items.do_sort = true

    block.call(maker)

    if maker.items.empty? then
      logger.info "empty!"
      maker.items.new_item do |item|
        item.link = "http://vocafeeds.champl.org/"
        item.title = "(no entry)"
        item.description = "エントリがありません"
        item.date = Time.now
      end
    end
  end
  content_type "application/xml"
  output.to_s
end

def add_item(url, maker)
  open url do |http|
    doc = REXML::Document.new(http.read)
    REXML::XPath.match(doc,"feed/entry").each do |entry|
      maker.items.new_item do |item|
        item.link = REXML::XPath.first(entry, "link").attributes["href"]
        item.title = REXML::XPath.first(entry, "title").text
        item.description = REXML::XPath.first(entry, "content").text
        item.date = REXML::XPath.first(entry, "updated").text
      end        
    end
  end
end

2011-09-11

[]Androidのカメラの向きに関する覚え書き

Androidでカメラを使ったアプリを作っているんだが、端末本体(カメラ)の向きに合わせて撮影した写真の向きも変えるのが結構面倒。その辺のAndroid API仕様の覚え書き。

Androidでは、カメラの向きに関するポリシーは、以下のどちらかになると思われる。

  1. 端末本体の向きに関係なく、アプリの向きlandscape固定にする
  2. 端末本体の向きに合わせて、アプリの向きや写真の向きを変える

1.が一番簡単。マニフェストファイルの<activity>要素で、android:screenOrientation属性を"landscape"にするだけ。カメラのプレビュー表示も撮影した写真の向きも全部landsacpe(横長)に固定される。

2.が結構面倒。カメラのプレビュー表示と撮影した写真の2つの向きを、それぞれ端末本体の向きに合うように制御する必要がある。

カメラのプレビュー表示の向きを変える

Cameraをopen()したあと、setDisplayOrientation()メソッドプレビュー表示の向きを、端末本体の向きに合わせて変更する。これをしないと、カメラから撮影する対象の向きと、プレビュー表示の向きが合わなくなる。コードは、下記を参考に。

Camera#setDisplayOrientation()のAPI doc

撮影した写真の向きを変える

最初は、Camera.Parameters#setRotation()で変えられると思ったが、Camera.PictureCallbackで渡されるJPEG画像の向きが変わるかどうかは機種依存らしい。少なくとも手元のXPERIA arcでは向きは変わらなかった。

Camera.Parameters#setRotation()のAPI doc

仕方ないので、自分でBitmapを操作して、端末の向きに合わせて写真の向きを変える事にした。例えば、onPictureTaken()メソッドを下記のように実装する。

public void onPictureTaken(byte[] data, Camera camera) {
    int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
    int degrees = 0; //端末の向き(度換算)
    switch (rotation) {
        case Surface.ROTATION_0: degrees = 0; break;
        case Surface.ROTATION_90: degrees = 90; break;
        case Surface.ROTATION_180: degrees = 180; break;
        case Surface.ROTATION_270: degrees = 270; break;
    }
    Matrix m = new Matrix(); //Bitmapの回転用Matrix
    m.setRotate(degrees);
    Bitmap original = BitmapFactory.decodeByteArray(data, 0, data.length);
    Bitmap rotated = Bitmap.createBitmap(
        original, 0, 0, original.getWidth(), original.getHeight(), m, true);
    savePicture(rotated);    	
}

2011-05-05

[] Google Apps Scriptを使ってみた

最近、GoogleスプレッドシートGoogle Apps Scriptという、MS-ExcelでのVisual Basic for Applications(VBA)に相当するスクリプト環境があることを知った。

以下のような特徴を持ち、その気になれば、かなり本格的なアプリケーションが作れる。

このGoogle Apps Scriptを使って色々やってみたので、以下、実際に動かしてみたコード断片を紹介。

続きを読む

2011-05-03

[] GoogleスプレッドシートAPIを使ってみた

GoogleスプレッドシートをWebスクレイピングしてみた - NAT’s Programming Champloo

以前、上記のエントリで、GoogleスプレッドシートをWebスクレイピングしたデータを表示するプログラムを作った。しかしWebスクレイピングには、HTMLの内容が変わるなど、データ取得元サイトの仕様が変わるとデータが取れなくなる弱点がある。つい先日も、GoogleスプレッドシートWebサイトがhttpではなく、httpsで表示するように仕様が変わり、データが取れなくなっていた。この問題は、とりあえずデータ取得URLをhttpからhttpsに変える事で対処できた。

今後も仕様が変わるたびに問題が発生するのが嫌なので、GoogleスプレッドシートAPIを使って、プログラムを作り直すことにした。以下、そのためにやった事の覚え書き。

続きを読む

[]さくらVPSサブドメインを作ってみた

さくらVPSで、Ruby on Railsアプリのためのサブドメインを作った。以下、そのための設定の覚え書き。

続きを読む