ばかおもちゃ本店:Youtube twitter:@sashimizakana Amazon.co.jpアソシエイト

2013年11月23日土曜日

まどか☆マギカ新編の特典フィルムをamazonで買った安スキャナで取り込んでみた

※劇場版のネタバレはありませんが特典のフィルムの画像がありますので
 すこしでも見たくないという人は注意してください



まどか☆マギカ新編みてきた!
もちろん特典のフィルムももらった!


分からん。
どこのシーンか分からん。
こっちがわけがわからないよである。

もうちょっと拡大すれば分かるかもしれない。
それならフィルムスキャナで取り込めば良いのでは無いかと思った。

フィルムスキャナというのは普通のスキャナと違って、写真のフィルムをデジタルデータ化するために、後ろから光を当ててその透過光を取り込めるスキャナである。もっとも普通のフラットベッドスキャナでも高級機ならフィルムを読めるやつとかオプションが追加できるようなやつもあるらしい。
これが最近では結構安いやつもあって、amazonで数千円で購入することができる。

もっともそれらは前述の通り、写真を取り込むためのもので映画のフィルムが読めるとはどこにも描いていない。ただ一般的な映画用のフィルムと写真のフィルムは35mmで同じ規格なのだ。それならば読めるはずだ。普通の写真のフィルムとは見た目が違うじゃんと思うかも知れないが、それはネガフィルムという反転しているフィルムだからで、写真のフィルムにはポジフィルムとかリバーサルフィルムという色が反転していないものもあり、フィルムスキャナはそういうのも読めるのである。


つうわけで買った。けっこう大きい。
右側においてあるのがフィルムをスキャンするためにセットするマウントである。右のが普通のフィルムとかの6枚用のやつで、左側のはポジフィルムなんかをスライドにしてもらったときにつかうやつである。


サイズはぴったり。
ただ、映画のフィルムは普通の写真の半分程度のサイズなので、一つ分の窓から二つ見えることになる。ちなみにハーフサイズっていう一本のフィルムで倍とれるっつうカメラがあって私の子供の頃実家にあったカメラがそれだったんだけど、サイズはそれに近いらしい。


で、ぐりっとクチの部分にマウントをねじ込む。このへん手動。
付属のアプリケ-ションでだいたいリアルタイムにプレビューを見ながら取り込める。

実際に取り込んだ画像がこちら。


やはりよく分からん。なんか最後の方な気もする。
輪郭とかすごいボケてる感じがすると思うがこれは絵に光りのエフェクトみたいなものがかかっていて、わざとボカされているんじゃないかと思う。
で、こんなもん見せられてもよく分からないだろうから、参考までに妻が見に行ったときにもらった方のフィルムも取り込んでみた。


あら素敵。映画のワンシーンみたい!

というわけで、こんな風に取り込んであとは壁紙にするも良し、プリントサービスで出力して飾るも良し、色々出来て楽しめそうである。

ちなみに写真の現像屋さんに頼めばプリントをしてくれるところもあるらしい。もっとも断られることも多いらしいし、大量にフィルムを集めてるとか、アニメの特典フィルムを頼んでみるってのも恥ずかしいと思うならこういうスキャナを買ってみるのも良いかも知れない。



Kenko カメラ用アクセサリ フィルムスキャナー 517万画素 KFS-500
ケンコー (2012-04-20)
売り上げランキング: 4,025
画質を追求するならもうちょい良い奴の方がいいかも。

2013年11月8日金曜日

AWSのDynamoDBをJavaScriptから直接操作する

前回の記事のとおり、AWSのSDKがブラウザ用JavaScriptで利用できるようになった。
今回は実際に試して利用できるようになったまでの手順を記す。
ちなみに検索しても日本語の情報はおろか英語の情報すらあまり見つからず、総当り的に試行錯誤ており、またDynamoDBそのものとかGoogleの認証周りは今ひとつわかっていないので、手順には無駄や間違った箇所があるかもしれない。そのあたりは各自で修正していただきたい。(そして出来れば私にも教えてほしい)

今回やることは、Googleで認証を受けて、その認証トークンを使ってDynamoDBに接続して、データを取得・設定する。利用の想定はGoogleのユーザーIDごとにjsonかなにかの文字列を保存しておく単純なアプリケーションとする。

クライアント側での大まかな流れとしては、Googleでログインしてもらってそこから返されたid_tokenからGoogleのuser_idを取得する。AWSのDynamoDBのキー値はこのuser_idにする。DynamoDBとのアクセス時に一緒にid_tokenを渡すことでAWS側でもuser_idが正しいことが照合され、自分のuser_idがキーのデータのみにアクセスできるようになる。

利用までの手順としては以下のような流れになる。
  1. Googleにアプリケーション登録をする
  2. AWSでDynamoDBにテーブルを作成する
  3. DynamoDBでWeb認証のときのポリシーを作成できるので作ってコピーしておく
  4. AWSでIAMにDynamoDBにアクセスできるRoleを作成する(3のポリシーを使う)
  5. ブラウザ上でDynamoDBに接続するアプリケーションを作成する
ではひとつずつ説明していく。

1.Googleにアプリケーション登録をする

Google APIs Console
Google Cloud Console

上記リンクのどっちでも良い(下の方が新しい)。
これらは本来GoogleのAPI(地図とかカレンダーとか)を利用申請する画面なのだけど、今回はログインを利用するだけなので登録のみでOK。適当に登録するとAPI Accessとかの欄にClient IDがあるのでそれを記録しておく。****.apps.googleusercontent.comみたいなやつ。****.projectというやつは違うので気を付ける。Client Secretは使わない。
ちなみに下の方はGoogle App Engineなんかのプロジェクトとも統合されていて、その設定を行える。
このあたりはたぶんググればどんだけでも情報があるので省略。

2.AWSでDynamoDBにテーブルを作成する

ふつうにCreate Tabelで作成する。
ググれば(略)
スループットを全Table合計でwrite:5/read:10以上に設定すると、時間単価が有料になるので気を付ける(初めて作るならどっちも1にしておけば大丈夫)。

3.DynamoDBでWeb認証のときのポリシーを作成できるので作ってコピーしておく

これ。


Identity ProviderをGoogleにして、権限をあたえる処理にチェックをする。
Allowed Attributesってので列制限もできるみたい。


ここで設定するわけではなくPolicy Documentの欄の設定値をコピーしておく。
ざっくり設定に触れると、dynamodb:LeadingKeysが${accounts.google.com:sub}になっているので、キー値がgoogleのsub(ユーザーID)と一致したときのみ権限が与えられるようになっている。
id_tokenはgoogleのエンドポイントに投げるとユーザーID、アプリケーションID等々が返されるので、正しいアプリケーションであるかどうかとか、正しいユーザーIDであるかどうかが分かるのでAWS側で照合してくれてるっぽい。

4.AWSでIAMにDynamoDBにアクセスできるRoleを作成する(3のポリシーを使う)

IAMのサービスにアクセスしてRoleを作成する。



 適当なRole名をつける。

一番下のを選ぶ。

Googleを選択してAudienceに Client IDを設定する。
これであとで渡すtokenが他のアプリに発行されたものじゃないことが確認される。

確認して次へ。

さっきのポリシーを入れるためにCustom Policyを選択する。

3で作成したポリシーをコピペする。

完了。
あとで使うのでこのRoleのSummaryからRole ARNをメモっておく。
こんな感じのやつ。
arn:aws:iam::(数字):role/(Role名)

5.ブラウザ上でDynamoDBに接続するアプリケーションを作成する

Googleから取得する必要があるのは、id_tokenというJWTっていうJSONの情報をまとめて署名してるナニ(よく知らない)と、Googleのuser_idの二つ。
id_tokenはGoogleのエンドポイントに渡すとそのトークンがどのアプリケーションIDに対して発行されたものかとか、どのuser_idに対するものであるとか、有効期限はいつまでだとか分かるのでその辺で有効な認証情報かAWS側で照合するのに利用されてるっぽい。
user_idはDynamoDBに格納するときのキーとして使うことになる。
これまでの手順が間違いなく出来ていたなら、DynamoDBにはこのid_tokenで確認されたuser_id以外のキーを受け入れないようになっている。

id_tokenとuser_idを取得する方法

これには調べた限りふたつの方法があって、楽なんだけど今ひとつ微妙なGoogle+ボタンを使う方と、面倒だけどちゃんと制御できるGoogle APIのJavaScriptライブラリを使う方法がある。多分内部的には同じ手順を踏んでるはず。
どちらの場合も上の手順で取得しておいたClient IDと、ユーザーにどこまでの権限を要求するかということを決めるscopeというものを用意する必要がある。ここではユーザーの基本的な情報(ユーザーIDの番号とアカウント)だけを要求する最低限のものにする。
その場合以下のようなアドレスをscopeに設定する。

https://www.googleapis.com/auth/userinfo.profile

各scopeの要求時に表示される画面なんかは以下のアドレスで確認できる。

OAuth 2.0 Playground

ちなみに上記のサイトはGoogle認証のOAuth2.0の手順を追っかけられるサイトなので、何が起きてるのかとか全く分からないなら色々いじくり回すと良いと思う。

で、話を戻して認証にはGoogle+ボタンを使う場合と直接やる場合とある。ただ調べ方が悪いのか、もともとそういうもんなのか、+ボタンを使う場合、上記のscopeが常にGooge+ API v1のloginを要求する権限が要求されてしまう。Google+を利用したことがないので分からないが、たぶんtwitterで言うと[今何々をプレイしてます!]みたいなものを自動でつぶやかせるために使うような権限だろうと思う。facebookで言うとウォールに載るかどうかみたいなもんだろう(facebookも使ったことがないのでこのたとえが正しいのかも知らない)scopeで言うと、https://www.googleapis.com/auth/plus.loginのやつがそれだ。
+ボタンって言ってるんだし、たぶんもともとそういうもんなんだろう。
上のuserinfo.profileで要求すると、+内でのユーザー情報と、+のサークルに知らせる権限と、Googleの情報とかなるので要求が多くて敬遠されそうな感じがする。あとログイン済みの場合、勝手に画面にトーストを表示させるを消す方法も分からなくて嫌だったので使わなかった。

ただ、Google+のユーザーでその方面で共有して欲しいと思うなら、使い方は簡単なのでおすすめだ。GoogleがホストしてるJavaScriptのファイルをロードして、spanに決まったクラスやdata属性でアプリケーション情報なんかを設定するだけでid_tokenを含んだデータがcallbackに帰ってくる。

以下に日本語で公式ドキュメントがあるので読めばすぐに使える。

Google Platform — Google Developers

user_idに関しては、手順が共通なのでライブラリを直接操作してid_tokenを取得する方法のあとに書く。

Google+ボタンを使わない方法

というわけでライブラリの使い方。ぱちぱち。
ちなみに+ボタンを使わないときでも、Google+ボタンガイドラインみたいなものがあって、それに準拠しなきゃならないのか悩むところだけど、何度か読み返してもこれはGoogle+の連携アプリとして作成するときはっつう話っぽいので多分大丈夫だと思う。+の権限を使うなら遵守すべき。
で本題。

Google JavaScript API - Google Platform — Google Developers
JavaScript Client Library Reference - Google APIs Client Library for JavaScript (Beta) — Google Developers

このあたりのリファレンス読めば分かる(おわり)。

なのだけど、一応ひっかかるポイントもあるのでサンプル。
gapi.auth.authorize({
    client_id:"******.apps.googleusercontent.com"
    ,immediate:true 
    ,response_type:"token id_token" 
    ,scope:"https://www.googleapis.com/auth/userinfo.profile"
},function(response){
    if(response && response.access_token){
        //ログインできたときの処理
    }else{
        //ログインできなかったときの処理
    }
});
上記の引数で一番重要なのはresponse_typeに"token id_token"という風にid_tokenとtokenのどっちも指定すること。tokenはあとでuser_idを問い合わせるときに使う(たぶんid_tokenで問い合わせることも出来ると思うんだけど調べてない)。ちなみに指定しないとtokenになるみたいでid_tokenが取得できず悩んだ。

immediateは連携許可の画面を出すか否かというフラグで、falseの場合、連携の有無に関係なく連携許可の画面がポップアップする。ただ既に連携の許可があった場合、ポップアップはちらりと見えてすぐ消える。そして上記のログインできたときの処理が流れる。許可が無ければ、あるいはログインしていなければその画面内でログイン|承認を受けられればログインできたときの処理が流れる。

trueの場合、連携の有無に関係なく、ポップアップは表示されない。連携がありログインしていれば問答無用でログイン処理に移行し、そうでなければできなかったときの処理が行われる。一長一短である。

つまりログインの処理をまっとうにやろうとすると、gapi.auth.authorizeはimmediateフラグをtrueで流したのち、ログインできなかったらfalseで流し直すか、ログインボタンを表示して押されたらfalseで実行するような形にすべきなのだと思う。
そうすると認証済みユーザーはシームレスに、新規ユーザーは承認画面に移行できる。

user_idを取得する

で、上記のどちらかの方法でid_tokenとaccess_tokenを取得できたはずだ。
そもそもこのtokenって何のtokenかというと連携許可を受けたデータにアクセスするためのtokenなので、このtokenを自分が許可を受けた権限で要求可能なエンドポイントに投げてやれば必要な情報が手に入る(必要な操作を行える)という寸法である。

これも上記のリファレンスに載っているのだけど、サンプルはこんな感じ。
var request = gapi.client.request({
    'path':'/oauth2/v2/userinfo'
    ,'params': {key:/*取得したaccess_token*/}
});

request.execute(function(userinfo){
    /*user_idを利用した処理*/
});
#callbackばっかりでネストが深くなりそうならdeferを使おう(jQueryだとDeferred)

やっとAWS SDK for JavaScriptをさわる

AWS SDK for JavaScript in the Browser

ざっと読めばだいたい大丈夫。
まずhttps://sdk.amazonaws.com/js/aws-sdk-2.0.0-rc1.min.jsがsdkなのでscriptタグでロードしてやる。
そいでサンプルはこんな感じ。
AWS.config.credentials = new AWS.WebIdentityCredentials({
    RoleArn: "arn:aws:iam::*******:role/TestRole"
    ,WebIdentityToken: id_token
});
AWS.config.region = "ap-northeast-1";
var DB = new AWS.DynamoDB();

//値を入れる
DB.putItem({
    TableName:"TestTable"
    ,Item:{user_id:{S:user_id},data:{S:"TEST"}}
},function(response){
    //エラーがあればresponseに入る
});

//値を取り出す
DB.getItem({
    TableName:"TestTable"
    ,Key:{user_id:{S:user_id}}
},function(response,data){
    //データに取り出した値が入る
});
AWS.configに設定しておくとS3とかDynamoDBとかで共通のリージョンとか認証情報が使える感じ。RoleArnにRoleを作ったときにメモっておいたArnを入れて、id_tokenを渡して、regionを設定すればあとはテーブルを操作するだけ。

ItemとかKeyでDynamoDB側に値を渡しているときのSとかいう名前のプロパティはその値の型名でSはString、NはNumberとかそんな感じ。
やったーEC2なしでDynamoDBにアクセスできた!

2013年11月3日日曜日

JavaScriptからAWSのSDKを使って格安ブラウザゲー運用を目論む

ブラウザからAWSのサービスが使えたらどうなの?

先日、ブラウザのJavaScriptに対応したAWSのSDKのプレビューが公開された。
JavaScriptではこれまでもNode.js版は用意されていたがこっちはブラウザ用である点が違う。現在のところS3、DynamoDB、SQS、SNSが対応している。公式ドキュメントはNode.jsと共通なのでぱっと見ほかも使えそうに見えるが、ブラウザ版を利用したときはクラスが存在せず使えない。

で、これが何に使えるのかっていうと、EC2を使わないでもデータやファイルの保存なんかが出来るっていうことだ。それができれば、個人でやるような小規模なプロジェクトならかなり安く運用できる可能性が出てくる。たとえば艦隊くりっかーはクッキーに保存しているので破損しやすく、容量もそう増やすわけにはいかないけど、もしかするとこれをさほどのコストをかけずに安定した大容量のセーブに対応させられるかもしれない。さらにログインに対応させて、複数の機器や、出先でもセーブデータを共有するようなことだって可能だろう。

それって今までだって出来たんじゃね?

もちろんこれまでだって、EC2を使えば同じことは達成できた。
しかしAWSではEC2を使うとすぐに課金額が大きくなってしまう上、時間で課金されるのでなかなかその部分を圧縮するのは難しい。収益が見込めるような事業で使うならEC2は便利でコストメリットもある程度あるし、一時的に大量のサーバーが必要なんて用途にはばっちりくる。だが個人が24時間落とさないで稼動させる用途で使おうと思うと、驚くほど安いとかそういう感じではなくなる。

たとえば個人でブラウザゲームを作って、それを安定稼動させようとすると一台では障害時に安定稼動しないし、かといって複数台構成にしてELB使うなんてことになるとさらにに金も手間もかかってしまう。一番小さなマイクロインスタンス一台だけでも月1,000円近くかかる。
思いつきでアホなゲームを公開するのに月に3,000円も4,000円も継続的にかかっていては寛容な我が家の大蔵省だってあまりいい気はしないだろう。しかもこれは稼動させている限りずっとかかる。

艦隊くりっかーはどうしているのか、というとあれはサーバーサイドとの通信がまったくないのでS3についているホスティングサービスを使っている。これはファイルさえ置いておけばホスティングをしてくれるというもので、1GBあたり月10円支払っておけばあとは転送料分だけ支払えばよい。これの何がいいのかというと、ウケなくて誰も使わなければお金がかからないという部分だ。これが上記みたいにEC2を動かしたりすると、誰もやっちゃいないのに月に何千円も支払うことになる。こんなに悲しいことはない。
そのあたりは以前詳しく書いた。

AWS S3で安くて頑丈なWebサーバーを立てる/艦くりのバックボーン - ばかおもちゃ製作所

これがEC2抜きで、たとえばファイルならS3、データならDynamoDBに直接アクセスして利用できるようになれば管理の手間もコストもぐっと下がる。もちろんそれぞれのサービスに利用するための費用は必要だがS3はもともとかなり安いし、DynamoDBは人気がなければ予約帯域みたいなもんを無料枠まで引き下げればタダで使うことができる。

DynamoDBってなんなん?

高速なNoSQLでつまりセーブデータを保存するような用途に結構向く感じのサービス。
課金はデータの保存量と一秒間にどれくらい書き込み・読み込みできるかという性能で決まる。一秒間に5KB(5ユニット)の書き込みと10KB(10ユニット)の読み込みまでは無料。書き込みは10、読み込みは50増やすごとに月600円弱くらいかかるっぽい。
それで実際どれくらい動かせるのかは、正直やってみないとわからない。
艦隊くりっかーの多かった時期で同時アクセス400弱くらいだったので、まあ昔ながらのRPGみたいな10分に一回くらい保存するものなら、400人が6000秒に一回保存するわけで、1セーブデータを1KBに納められたなら無料枠で大丈夫じゃないかという気がする。

ブラウザから直接アクセスって危なくないのん?

そこが今回の発表で一番大事なところ。
というか私が今回知っただけで実際には今回の発表より以前にAWSはIAMという権限管理のシステムで、facebook、Amazon(たぶんアメリカのアカウントのみ)、Googleの認証情報でログインできるという拡張を行っていた。見たことがあると思うが、ツイッターアカウントでログインするとか、そういう感じのやつのことだ。これを設定しておいて、各サービスの認証画面を呼び出し、承認後帰ってきたトークンをAWSに渡せばあらかじめ付与しておいた権限が与えられる。つまりAWSへのアクセス権限のある鍵をブラウザ上から送る必要はなくなり、鍵が流出してS3を誰かのエロ画像の保管庫にされたり、テロリストの情報交換用の掲示板を作られたりする心配をしなくていい。
さらに各サービスで認証IDに紐付いた権限を設定できるようになっているので、正規アクセス権のある人がDynamoDBへのリクエストを書き換えてほかの人のゲームデータを横取りしようとしても、それは出来ないようにすることができる。これはS3でも同様だ。パスの一部にアカウントIDを含めて、その認証アカウントじゃない場合はアクセスできないようにすることができる。

具体的にどうやんの?

次回書く。というか一日かけてやっとある程度わかったので前置きだけですごい長くなっちゃった。

2013年11月1日金曜日

塗装用品あれこれ2

前のエントリで書いたとおり筆塗りなんかをやっている。
うまくいかないなーってことをこねくりまわしていると、いつかはそう悪くないかもって思える形になっていくのが楽しい。特に塗装は時間をかけてじっくりやると、割とかけた時間に応じて良くなる感じがする。

で、いつもどおり何かをはじめると嬉しくなってつい色々買ってしまう。
買ったのは、塗料入れ用のダンボール製棚と、保持具、ペイントステーション。あとついでにキムワイプ。



保持具は塗装する対象を持っておくためのクリップつきの棒。
GSIクレオスからだと、ねこの手なんていう台座つきのやつとか、ペッタンゴムなんていう塗装対象を粘着させるやつなんかもあるんだけど、これはオーソドックスなクリップのやつ。


はさむ力もそこそこあって安いし塗装以外でも持ってていいかもという気もする。
これまでは割り箸を発泡スチロールに突き刺して使っていたのだけどやはり専用のものは使いやすい。
また発泡スチロール部分の変わりに買ったのがペイントステーション。


ひとつ上の写真ですでに写ってるけど、ダンボールを横にして敷き詰めてるようなもんで、穴の間に棒を差して使う。軽いし不安定かなとも思っていたのだけど特にそんなこともなく安定している。4つ入り。


塗料入れの棚はボール紙製で組み立て時にちょっと曲げ損なって角が壊れたりしたけど、それなりにしっかりしてるし収納数も多い。¥1,000弱だしもう一個買うつもり。


あといまさらではあるけど、キムワイプは繊維がくっつかないティッシュみたいなものでティッシュで拭いたら傷がつくとか、繊維がつくっていうようなときに使うもので、とにかく便利。六個入り買った。

もっとうまく塗れるようになるといいなー。



ペインティングクリップII (PTC2)
ハイキューパーツ
売り上げランキング: 303
20本入り。

Mr.ペイントステーション GT68
ジーエスアイ クレオス (2010-08-04)
売り上げランキング: 790
4つ入り。

Mr.カラー&水性ホビーカラー収納BOX
ジーエスアイ クレオス (2011-09-07)
売り上げランキング: 8,877
4引き出しつき。

日本製紙クレシア キムワイプ S-200 6個入り
日本製紙クレシア (2013-09-02)
売り上げランキング: 30
6つ入り。