「ピクセル」を含む日記 RSS

はてなキーワード: ピクセルとは

2012-02-05

ニュー速が焼豚に乗っ取られている件

1: ロッテ 藤岡、同級生・唐川と共闘宣言!! (82)

2: 昔は「20円」だったガチャガチャを「300円」にして、実物ない商品で大儲けしてる会社があるらしい (20)

3: 屋久島有料化へ 入島料の徴収を検討 (1)

4: 【速報】FOX神対応によりスクリプト壊滅へ (834)

5: ロッテ 唐川ブルペンに「よかった」 (7)

6: 名無雑談 120204【人間寄っといでー!】 (994)

7: 英王子フォークランド派遣 アルゼンチン征服者の服を着て私たちの土地に入るようなもの」 (4)

8: スレ立て依頼所 キタ─wwヘ√レvv~(゚∀゚)─wwヘ√レvv~─!! (36)

9: カリフォルニア米は美味いから、TPP参加したらコスパ重視でみんな買っちゃうだろうね (18)

10: ν速にbeは必要か? (110)

11: 超低価格車「ナノ」の高級モデルを販売 ハヤブサエンジン搭載で1500万円以上 しかも売れる (1)

12: 【速報】京都市長無所属現職の門川氏が当選確実 (1)

13: 山口って、九州だよね (´・ω・`) (2)

14: 【画像】早食い王 小林尊さん、手羽先でもV (15)

15: 楽天 星野監督赤星氏に現役復帰の勧め (7)

16: ウガンダ硫酸ぶっかけ復讐がブームに (21)

17: 楽天 松井稼頭央が2代目主将に (8)

18: 楽天 「ウッ!!」楽天武藤 シャラポワ投法でローテ名乗り (5)

19: 楽天 楽天に「久米仙」など名産差し入れ (10)

20: コープ挑発ブラウンが打撃で黙らす (2)

21: 楽天 塩見のパーマ「似合ってますか」 (11)

22: 川島、開幕から24試合連続フル出場 (2)

23: 巨人 原監督ホールトンカーブ絶賛 (7)

24: ラツィオ本田資金13億円!公式HPで提示内容公開 (2)

25: 香川「もう、すごい」ダメ押しアシスト”4連勝! (2)

26: 【画像】 かわいいマングースを1匹捕獲 (3)

27: 【血と鉄】 ビスマルクの肉声が発見される 発明王エジソンのお手柄 (4)

28: ■ジュ・・ジュウシマツさんの姿が!? (6)

29: ステマと言われて困っています。- 2ちゃんねる知恵袋 (10)

30: 巨人 ビビらせた!虎・中谷、ぶっ飛び26発 (7)

31: クロツラヘラサギギザライスwww (1)

32: 名無雑談 120205【人間おるかー?】 (9)

33: 野球盤の歴史に新たな魔球が刻まれた。その名は......!? (2)

34: 【原発】 福島で鳥が減少、脳が萎縮、生殖能力低下なども (11)

35: ニューススレが伸びない・ω・`) (53)

36: 【カンボジア新記録】猫自己新だニャー「良く走れた。最高」 (8)

37: 2/2に発売されたPSPソフトフォトカノ」の理想現実がひどすぎるとネット上で話題 (27)

38: NASA、8000×8000ピクセルの“超高解像度地球画像を公開 (18)

39: 【飛び級?】2010年国勢調査宮城県に14歳の高校生が1人いることが判明 (18)

40: コンビニおでん5個で500円は割高と気づけ (70)

41: 【日本は?w】韓国国家ブランド世界15位キタ━━━━━━(゚∀゚)━━━━━━ !! (2)

42: 西村博之氏・FOX氏・その他運営関係者おいで (265)

43: 阪神 “これぐらいは普通金本、初屋外フリーで柵越え10本 (20)

44: 横浜DeNA DeNAオーナー 広島オーナーに“危ない”あいさつ (7)

45: 嫌儲出戻り組歓迎スレッド  おかえりなさい!! (81)

46: 阪神 隼太“プロ1号”飛び出した (8)

47: 巨人 元巨人左腕が6年ぶり社会人復帰「感謝しています」 (6)

48: おむつ外しの良い方法を教えて下さい! (1)

49: 阪神 金本、4日にも本隊合流や (311)

50: 日ハム 佑、2度目のブルペンで45球 (7)

2011-12-22

http://anond.hatelabo.jp/20111222162844

問題は、著作者に金が行かない事だし、俺もこれ絶版から古本で買ったけど印税払いたいくらいだよなーって思う事ある。

そもそも電子書籍化したら「絶版」という概念自体なくなるだろ。



あと俺はマンガとかは電子書籍でいいけど、専門書は無理。

書き込んだりしたいし、電子書籍端末に向かってガチ勉強するのが難しい。

書き込みに関しては、ipadくらいのサイズiphoneのretinaディスプレイピクセル密度があって、1ピクセル単位で書き込みできるスタイラスデバイスがあればOKかも。

2011-10-18

Steve Yegge の Googleプラットフォームに関するぶっちゃけ話を訳した(中編)

前編からの続き

この努力は僕が Google に来る為に Amazonを離れた2005年半ばも続いていた。でももっとずっと進化していたよ。 Bezos が命令を出してから僕が離れるまでの間に、 Amazon は全てにおいてサービスをまず最初に考える企業へと文化的に変化していった。外部の日の目を決して見ることの無いような、スタッフへの内部的なデザインも含めて、今ではそれが全てのデザインというものに対しての基本的なアプローチになっている。

その時点では、彼らはもはや解雇の恐怖からそうしているわけではなかった。つまり、もちろんビビってはいたけれど、ドレッドヘアの海賊 Bezos 様にご奉仕するのは日常生活の一部だからね。そうじゃなく、彼らはそれが正しいことだと理解したから、サービス提供しているんだ。確かに SOAアプローチには長所短所もあるし、短所を書き出してみたら切りが無い。でも全体として、 SOA ドリブンのデザインというものこそが、プラットフォームを可能にする、これは正しいことだ。

これが、 Bezos が彼の指令書で企んだことだった。彼はチームの健康状態なんて興味もなかったし(今もそうかも)、使われている技術もそうだったし、結局の処のどう取りかかるかなんて結果ができあがるまで気にもしていなかった。けれど Bezos は、 Amazon 社員の大多数が理解する前に、 Amazonプラットフォームにならなければならないということを悟っていたんだ。

だって考えてもみてよ。なんで一オンライン書店が、拡張可能な、プログラマブルプラットフォームになる必要がある、なんてことを考える?。そうだろ?

ともかく、 Bezos が気づいた最初の大きなポイントは、本を売り、出荷し、色々とやる仕組みが、素晴らしいコンピューティングプラットフォームに再利用でき得るということだ。だから今、彼らには Amazon Elastic Compute Cloud があるし、 Amazon Elastic MapReduce があるし、 Amazon Relational Database Service があるし、その他たくさんの aws.amazon.com で見つけられるサービスを持っている。しかもこれらのサービスは大成功した企業バックエンドを努めていたりもする。 reddit なんか僕のお気に入りだね。

もう一つ、彼が理解した大きなポイントは、常にいつでも正しい、そんなものを作ることはできないということだ。これは Larry Tesler が、ママがこのくそったれサイトを全く使えないと言ってのけたりでもした時に、 Bezos にピンと来るものがあったんだと思う。誰のママのことを言ったのかははっきりしないし、そんなことは問題じゃ無い。問題は、誰のママだろうとそのウンコサイトを使えないってことだ(訳注アドバイス thx !)。実際、僕自身、そこで5年ほど働いていたわけだけど、あのサイトは胸がザワザワするくらいひどいと思う。でも僕はその気が散るようなサイトに慣れてしまって、トップページのど真ん中あたりの数万ピクセルに集中できるようになったんだからね。

とまあ、実際の処 Bezos がどうやってその理解、一つのプロダクトで、全ての人にとってふさわしいものを作り上げることはできないということに、たどり着いたのかは定かじゃあ無い。でもその方法は問題じゃ無くて、彼は理解してるってことが重要だ。実のところこの現象には正式な名前だってある。そう、それはアクセシビリティと呼ばれるものだ。コンピューティング世界で最も重要ものだ。

最も、重要な、ものだ。

君は思うかも知れないね。「はあ?つまりそれって、目が見えない人や耳が聞こえない人のあれ?あのアクセシビリティ?」ってね。まあ君だけじゃないと思う。とにかく世間には、アクセシビリティってものを正しく理解していない、君みたいな人たちがいっぱいいっぱいいるんだから。ただそこにたどり着いてない人たちがね。だからアクセシビリティを理解していないのは、目の見えない人や耳の聞こえない人や手足が不自由な人やその他障碍のある人の責任じゃないように、君の責任じゃない。ソフトウェアが(この場合アイデアウェアといった方が正しいかもしれない)何らかの理由で誰かにとってアクセシブルでないというとき、それはソフトウェア自身の、あるいはアイデアの伝え方そのもの責任があるんだ。それがアクセシビリティの失敗というやつなんだ。

人生における重要なその他もろもろと一緒でさ、アクセシビリティには邪悪双子がついている。小さいときにパパとママの偏った愛情で見捨てられて、今や同じくらいの力を持つまでに育った宿敵って奴がね(もちろんアクセシビリティには宿敵はたくさんいる)。それはセキュリティだ。一体全体こいつらが仲良くやっていること何てあるかい

でも、僕は主張したい。アクセシビリティは実際の処セキュリティより重要だということを。だってアクセシビリティを0にダイアルするってことは、何のプロダクトも持たないってことさ。セキュリティを0にダイアルしたって、そこそこのプロダクトを持つことはできるだろう? Playstation Network みたいにさ。

まあつまりですね、僕はみんなが分かってくれないんだったら一冊丸々この話題で本を書くことだってできるよ。分厚くて、僕が働いてた会社のありんことピコピコハンマーのエピソードで一杯の面白いやつをね。でも僕がこの話を公開しなかったら、みんなが目にすることも無いだろう。そろそろまとめに入らなきゃ。

Google がうまくやれていない最後の一つは、プラットフォームだ。僕らはプラットフォームを理解していない。僕らはプラットフォーム自分ものにしていない。みんなの中にできている人はいるだろう。でも、そんな君はマイノリティだ。辛いことだけれど、これはこの6年で僕にはっきりと感じられた。僕は競争相手のプレッシャーMicrosoftAmazon最近じゃ Facebook なんかが、僕らを一斉に目覚めさせて、ユニバーサルサービスを始めるのを期待したりもした。アドホックな、中途半端なやり方じゃなくて、多かれ少なかれ Amazon がやったようにだ。一度に全てを。マジで。偽りなしに。今その瞬間から最優先事項として扱うというように。

でも、そうはなっていない。10番やら11めくらいのプライオリティだね。いや15番かも?。知らないけど、とにかく低い。真剣に取り組んでいるチームもいくつかあるけど、多くのチームは考えてもいない。一度もだ。ごく一部の人々がちょっとした規模でやっているだけだ。

多くのチームに、彼らのデータと処理に対してプログラマティックにアクセスできるような、ちょっとしたサービス提供させるのだって大変だ。彼らのほとんどは、俺達はプロダクトを作っているんだ、って思っているからね。そんでもってそのちょっとしたサービスなんてのはみじめなもんさ。 Amazon の教訓に戻ってリストを見てくれよ。そんで今すぐ使えるサービスを持ってきて見てくれ。僕が知る限りでは、そんなものはない。小ビンってのは便利かもしれないけどさ、そんなの車がいる時だけだろ?(訳注:この人、 Stubby という小瓶のビールと、 stubby という「ちょっとした・不格好な」という形容詞をひっかけてしゃべってます

プラットフォームが無ければ、プロダクトなんて使い物にならない。いやもっと正確に言うならば、プラットフォームの無いプロダクトは、いずれ同等の機能を持ったプラットフォーム化されたプロダクトに、取って代わられる。

Google+ ってのはまったくまさに、エグゼクティブリーダーシップのとても高いレベルから(やあ Larry 、 Sergey 、 Eric 、 Vic 、やあやあ)枝葉の使いっ走りまで(やあ、君だよ)、全くプラットフォームを理解していないっていう良い例だ。そう、僕らはみんな、全く理解できていない。プラットフォームの黄金律ってのは、自分ドッグフードを食えってことだ。 Google+ プラットフォームってのは惨めなまでに後知恵だ。ローンチ時には一つたりとも API が無かった。そんで最後にチェックしたときには、僕らが提供してたのはわずかばかりのほんのちっぽけな API さ。ローンチの時、あるチームのメンバーが行進してきて僕にそれを説明してくれた。だから僕は訊いたんだ「でさ、これはストーカーAPI?」って。彼女はむすっとして、「ええ」ってだけ言った。いやジョークなんだよ…いや…ジョークじゃ無いんだ…僕らが提供する唯一の API は、誰かのストリームを読み出すだけ…。うーん、僕が間違ってたのか?

Microsoft はこの20年間ドッグフードルールで知られてる。この時代の彼らにとっての文化の一つなのさ。デベロッパドッグフードを食わせて、僕らだけ人間のご飯を食べようってわけにはいかない。それは単に短期の成功のために長期のプラットフォーム価値を損なう行為だ。プラットフォームってのはまったく長期的な視点が必要なんだよ。

Google+脊髄反射の代物さ。 Facebook成功したのは、彼らがすばらしいプロダクトを作ったかだって言う、まあ実に近視眼的なもの見方の結果として生まれたものだ。でももちろん彼らが成功したのはそんな理由じゃ無い。 Facebook は他の人たちにも何かをさせてあげられる、プロダクトの美しい集合全体を作り上げたから、成功したんだ。だから Facebook はみんなにとってそれぞれ違うものだ。 Mafia Wars に全ての時間を費やす人もいれば、 Farmville で遊ぶ人もいる。何百の、いや何千の、質の高い、暇つぶしができるってわけさ。つまり、みんなのためにふさわしい何かが必ずあるんだよ。

僕らの Google+ チームは、プロダクトを出した後のマーケットを見てこう思った。「おっとっと、我々もいくつかゲームが必要みたいだな。さっそくどこかと契約して、我々のために作ってもらおう」。これが信じられないくらい間違った考え方だってことが、君にもわかってきたかい?。問題なのは、僕らが、人々がほしい物を予測して、それを提供しようとしているということだ。

そんなことは出来ないんだよ。現実的にはね。確実にやる方法なんてない。もちろんコンピューティング歴史全体を見渡せば、それを確実に信頼性を持ってできる人間ってのがごく数人いることにはいる。 Steve Jobs がそうだろう。でも、僕らの処には Steve Jobs はいない。悪いけど、いないんだよ。

Larry Tesler は、 Bezos が Steve Jobs じゃないってことを口説いたかもしれない。でも Bezos には分かっていた。全ての人にふさわしいプロダクトを提供する為に、彼が Steve Jobs になる必要はないっていうことを。インターフェースワークフローこそが、人々が気に入り、安心感を得るものなんだっていうことを。彼はサードパーティ開発者にそれを可能にするだけで良かった。そうすれば、後の事は自動で進んでいく。

僕の言っていることが、あまりにも明白なことだろって感じているみんな(多かったらいいな)には申し訳ない。とにかくもうびっくりするほど自明なことなんだ。ただ、僕らがそれをやってないってことを除いてはね。僕らはプラットフォームを理解していない。プラットフォームを持っていない。アクセシビリティを理解していない。アクセシビリティを持っていない。これらは基本的には同じことだ。なぜならプラットフォームアクセシビリティを解決するからだ。プラットフォームアクセシビリティなんだよ。

後編に続く

Steve Yegge の Googleプラットフォームに関するぶっちゃけ話を訳した(前編)

Google エンジニアの Steve Yegge 氏、Google+ への懸念を漏らす
http://japan.internet.com/busnews/20111013/8.html

で記事になってたけど、原文とちょっと要旨が変わっちゃってサービスへの警鐘みたいになってしまってたので、全文訳してみた。くそ長い。お暇な方どうぞ。

2011/10/19 08:14)ありがたい誤訳の指摘をいただいたので3カ所修正。



Stevey の Google プラットフォームぶっちゃけ

僕は6年半ばかり Amazon にいて、それから今はそれと同じくらい Google にいる。この二つの会社について強く感じることは(しかもその印象は日々強まるのだけれど)、 Amazon は全てにおいて間違っていて、 Google は全てにおいて正しいということだ。そう、やりすぎな一般化だけど、驚くほど正確だと思う。いやもうとにかくね。百、いや二百のポイントで二つの会社比較することが出来るだろうけど、僕が正しく覚えていれば、 Google はそのうち三つを除いて優れている。実にある一点に関してはスプレッドシートを書いたんだけど、法務部が外に出すなって言うんだ。リクルーティングは惚れ込んだみたいだけどね。

まり、まあ簡単に言えば、 Amazon の人事採用プロセスってのは基本的に欠陥品なんだ。だって、チームがチーム毎に、自分達のために人を採用するんだぜ。だから、色々平均化の努力はしてるみたいだけど、採用基準はチームによって信じられないくらいバラバラさ。そんでもって作業工程ってのも腐ってる。ソフトウェア信頼性工学なんてお呼びじゃないし、エンジニアに何でもやらせようとするんだ。コーディングする時間もないくらい。もちろんこれもチーム毎にバラバラで、要するに、運次第ってところ。施しやら困った人を助けるのやら、コミュニティに貢献するのやら、そんなのはもってのほか。ばかにしに行くんじゃなけりゃ、近寄るべきじゃないね。それにまた施設も染みだらけの壁に囲まれた箱みたいな家畜場で、装飾やらミーティングエリアなんてものには一銭も使ってない。給料やら福利厚生なんてのも最悪だ。まして最近じゃあ Google やら Facebook っていうライバルがいるのにね。社員特典なんてものも見たこと無かったな。採用通知の番号を照合して、ハイ終わり。コードベース悲惨そのものエンジニアリング基準ってものがないんだから。チームによっては個別にがんばっていたくらいかな。

公平に言えば、彼らは良いバージョン管理ライブラリシステムを持っていた。これは僕らもまねるべきだし、僕らのところには同様のものが無い、良い pubsub システムもあった。でも多くの部分で彼らが使っていたのは、ステートマシン情報RDBMS に突っ込んだり読み出したりするだけのくそみたいなツールの塊だった。僕らならただでも欲しくないようなね。

僕が思うにその pubsub システムライブラリ管理システムが、まさに AmazonGoogle より優れている三つのうちの二つだ。

早期にリリースして、狂ったようにイテレートするってのも彼らのうまいところじゃないかって言うかも知れない。けど逆もまたしかり。彼らは早期にリリースすることを何にもまして優先する。品質保持やらエンジニアリング規則、その他長い目で見たら重要になってきそうなものはみんな後回し。そんなだからたとえ市場競争相手よりアドバンテージがあったとしても、結局ちょっとしたことをやるのにも問題を起こしちゃうよね。

でも、一つ、そんな政治的な、思想的な、技術的なへまを補うだけの、彼らが本当に本当にうまくやってることがある。

Jeff Bezos は悪名高きマイクロマネージャーだ。彼は Amazon の小売りサイトの1ピクセルまで管理する。彼は以前 Larry Tesler を雇った。 Apple主任科学者で、たぶん世界で最も有名で尊敬される HCI エキスパートさ。そんでもって、 Jeff は Larry が言ったことを、 Larry が辞めるまで3年間無視し続けた。 Larry は大規模なユーザビリティ研究もやっただろうし、少しの疑いの余地も無く誰もそのひどいサイトを理解できないってことをデモしたに違いない。けれど、 Jeff は1ピクセルたりとも動かさせはしなかった。トップページにぎっちりつまった内容の1ピクセルたりともね。それらはまるで何百万という彼の貴重な子供達なのさ。けれど Larry はそうじゃなかった。

マイクロマネジメントAmazon が僕らよりうまくやっている三つ目ってわけじゃあない。つまり、まあ、彼らはうまくマイクロマネジメントをやっていたと思うけど、それを強みって言いたいわけじゃ無い。まずは何が起こっているかみんなに理解してもらうための文脈を準備しているだけさ。僕らはこれから、公衆の面前で、 Amazon で働きたけりゃ私に金を払えと言ってのける男について話すわけだからね。誰かが彼に反対したときは、彼は彼の名前入りの小さな黄色ポストイットを手渡して、誰が会社を動かしているかを常に忘れさせまいとする。思うに彼は全くの… Steve Jobs なのさ。ファッションデザインセンス抜きのね。 Bezos はとんでもなく頭が切れる。誤解しないで欲しい。彼の前じゃ、普通コントロールフリークなんてヤクが極まったヒッピーみたいなもんだよ。

それである日 Jeff Bezos が指令を出した。まあ彼がいつもやってることなんだけど。その度にみんなはピコピコハンマーで叩かれるありんこみたいに走り回るんだ。でもそのある一度、2002年かそのくらいのことだったと思うけれど、彼は指令を出した。とんでもなく巨大で、目の玉が飛び出るほど重たいやつを。普段の指令が頼んでも無いボーナスに思えるようなやつを。

彼の巨大な指令はこんな感じだった。

1)この時点より、全てのチームはサービスインターフェースを通じて全てのデータ機能を公開すること。

2)各チームは各々そのインターフェースを通じて通信しなければならない。

3)その他の全てのプロセス間通信は許可されない。ダイレクトリンク、他のチームのデータソースから直接データを読むこと、メモリ共有モデルバックドア、全てを禁じる。ネットワーク越しのサービスインターフェースを経由した通信だけが許可される。

4)使用する技術は問わない。 HTTP 、 Corba 、 Pubsub 、 カスタムプロトコル、何でも良い。 Bezos は気にしない。

5)全てのサービスインターフェースは、例外なく、外部に公開可能なようにゼロから設計されなければならない。すなわち、チームは全世界デベロッパに向けてインターフェースを公開することができるよう、設計し、計画しなければならない。例外は無い。

6)そうしない者は解雇される。

7)ありがとう!良い一日を!

ハハ!。ここにいる君たち150人ちょっとの元 Amazon 社員ならもちろんすぐにおわかりの通り、7番は僕が付け加えたジョーク。 Bezos は間違いなく君たちの一日なんかに興味ないからね。

それでも、6番は、本当だった。だからみんな一生懸命会社に行った。 Bezos は、さらに上級のチーフブルドッグであるところの Rick Dalzell に率いられた数人のチーフブルドッグを雇って、成果と進行を監視させた。 Rick は元レンジャーで、陸軍士官学校出身で、元ボクサーで、元 Wal(ごにょごにょ)Mart で拷問のような削減をやってのけた人物で、デカくて愛想の良い、「堅牢なインターフェース」という言葉を連呼する男だった。 Rick は歩き回り、「堅牢なインターフェース」について語り回り、そして言うまでも無く、みんなはいっぱいの進展をし、 Rick にそれを知らせた。

それからの数年間、 Amazon 内部はサービス指向アーキテクチャに姿を変えていった。その変化を形にしている間に、彼らは非常に多くのことを学んだ。 SOA に関する学問論文は当時もいくつかあったけれど、 Amazon のとんでもない規模からすれば、そんなものインディ・ジョーンズに向かって「通りを渡るときは左右をよく見るんだよ」って言うくらいの意味しかない。 Amazon の開発スタッフはその途上でとにかくたくさんの発見をした。そのほんの一部をちょっぴり挙げると、こんな感じだった。

  • ポケベル通知( pager escalation )はどんどん難しくなった。だってチケットの本当の持ち主がわかるのに、20回は往復しないとならなかった。もし一回のあるチームからの応答に15分かかったとしたら、正しいチームがそれを受け取るまでに何時間もかかってしまう。たくさんの前準備と測定としっかりしたレポーティングをやるようになった。

とまあこれらがほんの一例。他にもたくさんの、おそらく何百の、 Amazon が見つけた個別の発見や教訓があった。外部サービスにはおかしなところがいくつもあったけれど、君たちが考えるほどじゃあない。サービスに対して組織するってことは、外部のデベロッパを信用できないのと同じように、お互いを信用することなんてできないんだということを、チームに教えてくれたんだ。

中編に続く

2010-09-20

初音ミクと見せかけの魔法

 海外blog初音ミクについて熱い(長い)文章を書き込んでいるのを見かけたので試しに翻訳してみた。無断翻訳なので匿名で。urlは以下の通り。

http://deliciouscakeproject.wordpress.com/2010/09/20/hatsune-miku-and-the-magic-of-make-believe/

=====以下翻訳=====

 初音ミクと見せかけの魔法

 初音ミク歴史は18世紀のヘタリアイタリアに始まる。

 そこにはバルトロメオクリストフォリって名前のすげえヤツがいた。こいつの得意技は楽器を作ることだった。何でも作ったわけじゃない。当時はひどく弱々しいちっこいもので、しょぼい羽柄が並んだ弦を引っかいて金属的なチャリチャリした音を出すもの、つまり鍵盤楽器を作っていた。いわゆる「バロックミュージック」ってヤツだ。クリストフォリが音楽技師として、また機械技師としてやったのは、弦を異なる強さで叩くハンマーを使った仕組みづくりで、それによって演奏家は小さい音(ピアノ)や大きな音(フォルテ)で演奏できるようになった。だもんで皆それをイタリア語ピアノフォルテと呼んだ。もちろん、今ではお前も俺もそして誰もがクリストフォリの発明品をピアノと呼んでいる。

 イタリアピアノ発明することによって、日本初音ミク発明するための扉を開いた。

  ***

 俺は今、ここサン・フランシスコの150席しかない小さな映画館で、秋のアイドル公演を待っている。チケット完売した「39[ミク][[Sankyu!]] Giving Day」コンサートの上演を見るために、愚かな時間無駄遣いをする連中が集まっている。コンサートじゃ電子的に創造されたポップアイドルつまり緑の髪をした女神が、ゼップ東京コンサート会場で生演奏するバンドにあわせて踊り歌っている様子がスクリーンに映し出されている。それはまるで、一部はライブなんだが、本当はそうではなく、「本物」のボーカロイドコンサートでお目にかかれるのに近いものだった。言ってみればゴリラズを見に行くのとそれほど違いはない。伴奏は本物のミュージシャンが作り出しているが、客が見ているのはいわば巧妙なごまかしの表層であり、音楽に命を持たせるために使われる動くペルソナだ。これがミクの魔法である。それは見せかけの魔法だ。

  ***

 クリストフォリがピアノ発明した頃、J・S・バッハ平均律クラヴィーア曲集を書いた。そこでは要するに鍵盤楽器の各音程間で一通り数学的な調整をすれば、突然どのような調号でも十分演奏できるようになるということが言われている。言い換えれば、何か妙なことをしようとした際にいつも調子はずれの音を出すのではなく、初心者から中級までのピアノの生徒がやらかす糞を抑えるような5フラットとか7シャープとかそういったことが完全にできるようになる。これによって18世紀の鍵盤楽器は初めて、いちいちくそったれな調律をしなおすことなく新しい楽想を試すことができる原始的なワークステーションとなった。

 数十年後、ようやくピアノ価格が下がり十分なほど生産できるようになったことで、それは非常識なほどの大金持ちだけの特別な楽器ではなくなった。代わりにそれは有名な王族たちのような常識的な程度の金持ちが購入できるものとなり、彼らは好んで地元作曲家を雇い自分たち(とその客)を楽しませるために音楽を書かせた。こうした作曲家の一人があのヴォルフガング・A・モーツァルトであり、彼の特別な才能は主に下ネタ女性音楽生徒に対する性欲の面で発揮された。もちろん鍵盤楽器からふざけた音を引き出す才能もあり、その短い人生の間にモーツァルトは最も好きな楽器ピアノに決定した。彼が書いた27のピアノ協奏曲(本当に素晴らしいのは最後の10曲ほど。アニメシリーズのようにモーツァルトレパートリーは後半になるほど良くなった)は、単に協奏曲形態にとって画期的な礎石となっただけでなく、ピアノ音楽の基礎を築いた。モーツァルト協奏曲はこう言っているようなものだ。「これこそピアノにできることだ! ピアノだけでなく、オーケストラと一緒でもいい! まさか今更ハープシコードに戻ろうってんじゃなかろうな?!」

 モーツァルトより後の時代の人間は皆彼に同意した。ひとたび音量の大小を調整できる鍵盤楽器を手に入れてしまえば、弱々しいチャリチャリした機械になぞ戻れっこない。これが230年ほど前の出来事だ。ミクへの道は一日にして成らず。

  ***

 ミクの公演にやって来たファンの男女はいろんな連中の寄せ集めだ。彼らの5分の1ほどは当然ながらボーカロイドコスプレをしている。何人かはケミカルライトまで持ち込んでいる。コンサート全長1080ピクセルの巨大なスクリーンで始まり、全劇場サウンド・システムが炸裂し、観衆は最初はためらいがちに見ていたが、最初のいくつかの歌の後は雰囲気が盛り上がってきた。彼らはスクリーンの中の群衆と一緒にリズムに合わせてケミカルライトを振り、曲が変わると歓声を上げ、各ナンバーが終わると拍手をした。単なる録音と録画じゃねえか、などというたわ言は知ったこっちゃない。理論的にはゼップ東京の群衆だって同じように録画を見ていたんだ。本当に「ライブ」で演奏される音楽など、現代においてはクラシックオーケストラ民族音楽演奏くらいしかないし、それにシンフォニーホールですら今日ではマイクが使われている。誰もが電子的な助けを借りて音楽を聴いている。ひとたび電子機器楽器として受け入れることを覚えてしまえば、ミクを愛するのは簡単だ。彼女モーツァルト魔笛アリアを歌っている動画を聞いてみよう。

http://www.youtube.com/watch?v=gr9fbQzNpqA

  ***

 19世紀欧州で、もしお前がピアノ演奏ができない作曲家だったとしたら、お前は存在していなかっただろう。それはもはや単に大小の音量で演奏できる楽器にとどまらず、巨大な和音構造物であり、多音パッセージワークであり、一人の演奏家の手で「あらゆる音符を見ることができる」ものとなっていた。もしピアノがなければきっと「2人のバイオリニストビオラ及びチェロ奏者各1人をかき集めて旋律が上手く行くかどうか調べにゃならん」てなことが起きていただろう。そしてもちろんチェリストは、ある音符について「どぅんどぅんどぅんどぅんどぅんどぅんどぅんどぅん」と演奏するようお前が何度も何度も何度もお願いするのにうんざりして1時間後にはそこを立ち去ったことだろう。

 少なくともピアノがあれば、お前の小さな指以外に迷惑をかけることなく「どぅんどぅんどぅんどぅんどぅんどぅんどぅんどぅん」とやることができる。

 かくして1800年代においてピアノは中心的な作曲道具となった。そして同時に社会中産階級が暇と屑な時間を持つところまで進化し、そしてもし彼らがスポーツゲーム発明しなければ、彼らは音楽その他を演奏したいと望み、そんでもって家に持ち込むためピアノを注文できるようになった。欧州だけでなく日本でも、少なくともウィリアムペリーが彼らを開国して西洋化が始まった後には、同じことが生じた。基本的にピアノ文明化の証と見なされ、そして有名な山葉寅楠ってヤツがイケてる連中のため日本製ピアノを作り始めた。

 19世紀末20世紀音楽制作にとって黄金時代だった。楽譜を買って他人の歌を演奏する方法で「音楽を作る」こともできたし、あるいは作曲理論について十分に学び自分の曲を創造するというやり方で「音楽を作る」こともできた。そうした取り組みの多くはピアノの周辺で起きた。ピアニストが力を得た。鍵盤があれば、お前はスターになることができた。

 そして、とんでもないことが起きた。

  ***

 ミクだけじゃない。巡音ルカとリンとレンも公演に出てきたぜ! 全ボーカロイドパーティだ。彼らの異なる声質と、ミクと組む様々なやり方は、見事な音の見本集になっている。他のキャラクターが登場するのを見た観客たちは熱狂している。異なるシンセサイザープログラムマスコットに過ぎないにもかかわらず、彼らはまるで我々の友であり家族であるかのようだ。ようつべニコ動を使って彼らを我が家へ招待しよう。彼らの声を我らの生活のサントラにしよう。電子的に作られたアニメキャラが本当のミュージシャンになれるのかって? おk、ならお前に聞いてみよう。魂のない箱がお前の周囲の空気を震わせているけど、それは本当の音楽なのかい?

  ***

 それこそが実際に起きたとんでもないことだ。録音された音楽。録音された音楽こそ、音楽史の中で起きた最悪の出来事だ。

 ひとたび蓄音機を、ラジオを、レコードプレイヤーを、カセットプレイヤーを、CDプレイヤーを持ってしまえば、音楽を楽しむのに「音楽を作る」必要はない。コンサートホールチケットを手に入れる必要もない。単に座って、電気を使った箱にお前を楽しませればいい。ピアノ専門家のための道具に成り下がった。それは淑女が結婚に必要な才能を覚えるためのものに、あるいは子供が(1)それを憎んでいることに気づく(2)両親が子供に才能があることに気づいてプレッシャーを積み上げ始める――まで稽古を受けるものとなった。もし(2)の現象が起きたなら、最後にはピアノを本当の演奏楽器あるいは作曲用の道具として使うようになるだろう。しかしそれはもはや「音楽制作」の中心にはない。

 さらに悪いことにロックギターをポピュラーにしてしまった。ギターが人気になり、ピアノは役立たずとなった。お前が鍵盤楽器を学ぶのは、ビートルズにしてくれるものを持てずバッハベートーベンにしがみつくしかないある種の意気地なしだからだ。誰が決めたルールか知らねえが最低だ。10代のころ、俺はピアノを使ってランキング上位40の曲を弾けたおかげで女の子たちに「いくらか」いい印象を与えられた。けど、結局はクラスの野郎どものうちその曲をギターで弾けるヤツがいつも勝ちやがった。くそったれ。

 だがここで思い出してくれ。俺は、イタリアピアノ発明したことが日本初音ミク発明への扉を開いたと言ってきただろ? ピアノ21世紀に飛び込むときに今一度変革に見舞われたんだ。

http://www.youtube.com/watch?v=-7EAQJStWso

  ***

 もし音楽を生み出す小さな電気の箱が「本物」であるなら、録音済みのコンサートに向かって「アンコール! アンコール! アンコール!」と叫ぶのは極めて正常だ。その音楽はお前を感動させたんじゃないのか? もっと聞きたいと思わないのか? というわけで映画館の観衆はもっともっとと叫び、そして彼らはアンコールを聞けることが分かっていた。なぜならそういう風に録音されていたから。ミクが公演を終わらせるため最後舞台に出てきた時、もう一度鑑賞力のある人々から歓声が上がった。それは人工的なものだが、とことん楽しむため我々はそれを本物だと見なした。まるでドン・コッブが[ネタバレ注意!!]インセプションラストで回転するコマから歩み去るかのように。ミクは夢のような存在だ。サウンド・エンジニアCGアーティスト音楽家が作り上げた美しい夢であり、決して卒業することも年を取ることもスキャンダルを起こすことも業界から追放されることも惑星上から姿を消すこともない完璧アイドルだ。彼女は実際、いくつもの「映像」を持っている。我々は皆、この音楽的見せかけの共犯者だ。過去の聴衆がモーツァルトオペラを、ガーシュウィンミュージカルを、あるいはかのすさまじいレ・ミゼラブルを本物であると信じたように。我々は十分深く信じられるようになるまで偽りの世界を本物だと信じるふりをする。その世界を感じるまで、見せかけの魔法を感じられるようになるまで。

  ***

 ピアノ最後の変革とは、もちろん電子化のことだ。

 真空管からトランジスタを経て迷宮のような電子回路まで。もしピアノの鍵盤が「あらゆる音符を見る」ことのできるインターフェイスだとしたら、それは作曲家に最も未来を感じさせるインターフェイスだ。そして我々にはシンセサイザーキーボードとMIDIコントローラーワークステーション世界が与えられており、そこでは遂にピアノが単なる「楽想を試す場所」から超越した。ちょっとした波形の調整によって、ハンマーと弦の機構に制限されることなくこれらの楽想を正確に響かせることができる。新しい音を作り上げることもできる。楽想の断片を記録し、他の楽想をその上に並べて電子キーボードを個人的な架空オーケストラに仕立てることもできる。ピアノピアノを超えた。それは作曲家の手の延長どころか、作曲家の心の延長となったのだ。

 一つだけ欠けているものがあった。声だ。

 そして、ご存知の通り、日本日本であり、彼らはやってのけた。彼らは人工物を誰よりも巧みに操った。彼らは本物の料理だと見栄えが悪くなるからという理由でプラスチック製の小さな食品サンプルを作った。本物の労働者は間違いを犯しがちだから製造ライン用のロボットを作った。本物の音楽家を家に入れるのは大変だから編曲家のために電子キーボードを作った。そして、人間の声を合成する技術が十分に発達した時、そしてそれが人工音声のためのペルソナ創造するというアイデアと衝突した時、ミクが見せかけの音楽における21世紀スーパースターになるのは当然のことだった。

 中にはボーカロイドというアイデア音楽家の全てを破壊するという人もいるだろう。全ての仕事ソフトウエアがやってくれるのに、誰が人間を必要とするんだ? 俺が思うに、ボーカロイドってのは偉大なる民主化の旗手であり、音楽家のために沢山の扉を開いてくれるカギなんだ。過去において、もしお前が作曲家編曲家あるいはプロデューサーなりたければ、まず自分の曲を書いてそれから演奏家を探し見つけ出すしかなかった。何しろお前の傑作に生命を吹き込みたければ、5人編成のバンド、20人編成のオーケストラ、そして3オクターブ半の音域を持つ歌い手がいないとどうしようもなかったのだから。マジ悲惨。だがミクがいれば誰もが作曲家になれる。誰もが自宅のスタジオで曲を作り、正しい機材があれば、電子機器を使った完全なポピュラーソングを生み出せる。ボーカロイド音楽家仕事を奪うわけじゃない。それまでミュージシャンには決してなれないと思っていた人々の中からミュージシャンを作り出すんだ。動画投稿サイトで毎日そうしたことが起こっているし、こうしたコンサートではそれまで決して聞いたことのないような人々が突然電子王国の宮廷音楽家になれる。非常識なほどの大金持ちだった王家の人々の手にあった手製の楽器から、平民たちの手に握られた緑の髪の女神へ。それがこの大きな3世紀の違いだ。

 何であれ多くの人々が音楽を作ることは、単に大人しく聞いているだけよりもいいことだと俺は信じる。俺は魔法を、ボーカロイドを、ミクを信じている。

=====以上翻訳終了=====

 誤訳は当然あると思う。でも面倒なので修正はしない。

2010-01-29

http://anond.hatelabo.jp/20100129113052

はじめからWEB意識してデザインしてくれたらコーダーは楽なんだけどね。

ピクセル概念もないような紙とか広告出身のおっさん達がいまだに多いから困る。

ま、「ユーザーが見るのは最終的に完成したビジュアルなんだから文句言わずに再現しろ」ってのも正論なんだけどさ。

2009-06-20

Windows7ウェブサイトは狭くなるか

ウェブサイトの横幅は何ピクセルが良いか、というのは今まで幾度となく話題になっている。今まではディスプレイとその解像度の増加に合わせて、最適なウェブサイトの幅というのは拡大を続けてきた。


最近では

http://www.kotono8.com/2009/01/14yokohaba.html

http://www.web-20.net/2007/12/1000px.html

のように900ピクセルだとか1000ピクセルなんて話になっている。


それはそれで良いのだが、今後どうなるかという話だが、Windows7の登場によって今度のトレンドは縮小するのではないかと考えた。Windows7の新機能の一つがAero Snap。簡単にいえば左右に並べて表示が極めて簡単に即時にできる機能。つまりWindows7の普及は左右に並べて表示の使用頻度を格段にあげると想像できる。


そうなるとウェブサイトもそれに合わせて変化するのではないか。つまり大きなディスプレイのある環境ではウィンドウを2枚並べて作業する機会が格段に増えるのではないか。

ならばその状態を念頭に置いた横幅でウェブサイトを構築しなければいけない。


ではそれは何ピクセルなのかと言えば850ピクセルくらいなんじゃないかと。今後増えるであろう1680ピクセルやフルHDの1920ピクセルで2枚並べで見ることを考え、既存の1280ピクセル程度の解像度の場合は今まで通り全画面で見ることを前提にする。また今あるウェブデザイン自由度を保つことを考えると850ピクセルくらいが落とし所なんじゃないかと。


こんないい加減な予測が当たると面白いな。

2009-04-21

はてなダイアリー有料オプションを入れるか悩んでる

はてなダイアリー有料オプションを申し込むかどうか悩んでます。

大きい写真が使えます:300ピクセルって今どきで言うと小さい。でも画像主体のブログじゃないしそもそも。

アフィリエイトできます:元を取れるほどではないかもしれないけどちょっと楽しみが増えそう。

ヘッダーが消えます。余計なリンクが消えます。:これはうれしい。

アクセス解析機能付きます:楽しいか落ち込むか。

2009-03-19

http://anond.hatelabo.jp/20090319114740

しだれ柳を幽霊勘違いする人がいるように、人間じゃないものを人間勘違いさせることはポイントさえ抑えれば結構簡単なんですよ。この前だって仲良くしていたtwitter友達がbotだった(以下略

ともかく。人物の記号化に関することなら、らきすたに限らずとももっともっと旧い段階の漫画のほうが余程顕著だぜ。

例えばらきすたの直系のご先祖様である「少年アシベ」なんてデフォルメの塊で、冷静に見たらアシベ少年人間ではなくナスそのものだ。

問題は、そんなところじゃないだろ? おまいさんが人間人間認識するプロセスは、常識的な3Dの人間との近似率からはじき出されるものか? 違うね。

人間認識するオブジェクトってのは、瞳に映像されたピクセルじゃないんだよ。もっとこう、コンテクストから導き出される推論エンジンで補完された、ユークリッド空間に拠らないイメージなんだよ。言語化できないけど。

そんな当たり前のこともわからないわけ?

2009-03-11

さっきamazonDVDランキングを見たが、本当に唖然とした

http://anond.hatelabo.jp/20090308152436

さっきamazonDVDランキングを見たが、本当に唖然とした。

俺は断言するが、あのハリウッドCG映像を見て感動してDVDを買う奴は馬鹿だ。これは100%断言できる。

何であれがいいと思うの? なんであれのDVD買うの? 本当に分からない。あれCGじゃん。レンダリングされたピクセルだよ? 誰だってあれ見てCGだって言うのは一瞬で分かる。それで感動するって本気で馬鹿なんじゃない? 

あれがいいっていうのは、頭がおかしいとしか言いようがない、というか、脳が退化してるんだよ。それしか説明がつかない。つまり、現実演技バーチャルが区別つかなくなってるんだよ。だからいいと思って買う。これは馬鹿としか言い様がないだろう。日本の将来は大丈夫か?

前にもちょっとマトリックスDVDが出た時、ニコニコ動画(こんなもの見たくなかったが)で見たが、なんであんな人気あるんだろう。あとついでにそのマトリックスCGシーンを仮装大賞人間がパロッて卓球してるのも見た。これならまあ100歩譲って納得できなくもないが、ただ当然プロスタントとは比べるのも失礼な程だし、無料ならまあ一回見てもいいかな、という程度だ。何回も見るほどではない。ただコメントは絶賛の嵐。アホか。本物を知らないニートばっかなのかあそこは。ろくなもんじゃないな。

俺ははっきり言うが、もっと人間が本気で演技してるDVDを買うべきなんだよ。じゃないとおかしい。プロの役者が毎日どれだけ苦労してるか知ってるか? ボイトレ筋トレ、喉や体調の管理、食事管理、書けばきりがない。大好きな酒、タバコも我慢して頑張ってる人もたくさんいるし、サラリーマンみたく安定した職じゃないから毎日不安と戦ってる。そういう方が心を込めて出演してるDVDを買わずに、ピ○サーのCG映画を買う。ほんと死にたくなるね。どうしてあの機械演技を買うかね。わからない。世の中不思議だらけだ。

本当におまえら頭冷やして考え直せよ。おまえらは馬鹿か、またはブームに乗せられてるだけだ。まあそれを馬鹿と言うんだがな。

2009-01-19

津田大介氏にインタビュー 著作権現在について(1)

モーリー:i-morley今日は久しぶりにジャーナリスト津田大介さんにお話を伺おうと思います。よろしくお願いします。

津田大介:よろしくお願いします。

モーリー:最後にインタビューさせていただいてから、かなり著作権世界とかネットカルチャーがまた激変している感じなんですけれど。

津田大介:そうですね。変りましたね。いちばん変えているのは、ボク自身二年とか三年ぐらい審議会に参加して思ったことなんですけれど、実際審議会で、インターネットでこのような問題、著作権の問題が起きているので対応しましょうと審議会で二年とか話すわけですよね、話して問題が出てきましたと、こういう問題が生じていますよということがおきて問題確認で終るという審議会もかなり多くて、じゃあ次は来年以降の検討課題ですねみたいに終るのも多くて、そうじゃなくてこれをこうしましょうということが決まったとしても実際に法律施行されるのはその翌年の国会に提出されて、国会で決まりましたと、その次になります、と。やっぱり三年とか四年のタイムラグがあるんですよね。

モーリー:うーん!

津田大介:だから、いまネットで起きてるそういう問題と言うものに対して、なにかしらの対応策と言うものを考えましたといって実際に法律が動き出すのに、三年後とか四年後とかだったら、モーリーさん逆に四年後のインターネットってわかります?って言ったらまったくわかんないじゃないですか。そういうのが実際に法律を作る現場とか審議会で行われているということが、すごいこのギャップはひどいなあと思いましたね。

モーリー:どんなに早くやっても三年後にしか法律は変らなくって、その頃には状況が全然違っている。

津田大介:ほんとに最短で二年、三年後とかですから。だから例えば今回ぼくが参加していた審議会で違法コンテンツダウンロードダウンロードすることを自体を違法にしましょうというのがほぼ決まりそうなんですけれど、決まりそうといっても今年のいま開かれている通常国会で法案が提出されて、それが施工されるのが来年1月とかですから、来年1月にようやく法律が変るみたいな世界ですから。それにいま政治情勢が非常に不透明じゃないですか。そうすると法案を普通に提出するような三月とか四月の時期にもし選挙があってその辺が混乱とかしたら、もう本来提出されるはずの著作権の改正案というのはとんじゃうんですね。とんじゃって今年の九月の臨時国会に行くか、もしくは来年まで国会までとばされてしまってあと一年法律施行が遅れるということがあって。

モーリー:もう一年さらに現状とのギャップが広がるということですよね。

津田大介政治状況でそういうことが平気で行われてしまうというのが、政策ができていく過程なので、それはぼくらの専門的な分野の知財とか著作権ってあんまり政治の争点にならないんですよね。民主党自民党とそんなに大差があるわけじゃないので、そういう意味では提出されればだいたい通るんです。提出されれば官僚が文を書いて通して、そのまますんなり国会を通過して変るんですけど、でも逆に言うとそういう政治的な争点にならない法案というのは後回しにされちゃうんです。政治だからいまみたいに非常に混乱している状態だと、特にいまは衆参がねじれちゃってますから、そうすると法案が非常に通りにくくなってしまうので、そうすると予算とかが一番重要な法案で、あとは特措法の問題とか、そういう重要な問題があるとそっちが紛糾しちゃうんでそっちに時間をかけてしまうので、そうすると著作権みたいにある種国全体からみたいら優先度が低いというかどうでもいい問題は後回しにされるんですね。後回しにされて、官僚のほうにもいまはほんとに政治が混乱しているから重要で無い法案は提出するな、どうせ否決されてしまうだけだからみたいなかたちになってしまうので、そういう状況も法律ができるのを遅くするのに拍車をかけているということがある。

モーリー:津田さん、私がやってるポッドキャストなんですけど、最近かなり人が増えてまして、そろそろ累計登録人数が50万いきそうなんですね。

津田大介:ほー。すごいですね。

モーリー:ということは、かなり著作権とか、かなりディレクトリの奥の奥にあるような話を原点から知らない人が多いんですよ。いま一番津田さんがやばいと思っている、あるいは一番つらいと思っているトレンドをまず解説していただけると。

津田大介:ぼくは最近著作権関連でインパクトがあったのは、ユーチューブなんですよね。去年の11月ぐらいにユーチューブが横長になったのってご存知でしょうか。

モーリー:ああ、なんか長くなったような気がする。

津田大介:いままで4:3で画面が小さかったんです。320ピクセルと240ぐらいで、ある意味ユーチューブのいままでのいいわけみたいになっていたんですけれど、ユーチューブってネット動画とかテレビ番組とか、売り物が全部勝手コピーされる違法行為の温床になっていたんですけれど、ところが突然横長になってさらに画質が滅茶苦茶良くなったんですね。

モーリー:ふーん。

津田大介:H264という非常に、実際にブルーレイとかでも使われている高圧縮のコーデックに対応して、いまユーチューブはフル画面で見てもかなりきれいに見れるようになってるんですよ。走査線のもともとのファイルが良ければ地デジ並の画質でユーチューブフルスクリーンで見れるみたいになってきてて、それが去年の11月リニューアル

モーリー:マイナーコンテンツばかり見ているせいかぜんぜん良くなったという印象が無いので。(笑) もとが悪いものばかり見ているから。

津田大介:そうなんです。そういうところが結構ユーチューブが変り始めていて、それまでやっぱりユーチューブが質が悪いから見逃してもいいじゃんみたいなある種言い訳が成立していたのが、今は成立しなくなりますよね、そうなると。よくコンテンツホルダーとかが許したなあと、怒んないのかなあとかそういうのがあるんですけれど。ぼく自身は結構ユーチューブ著作権問題ってこれからあまりたいした問題にならないんじゃないかなあというフェーズに入ったと思っていて。

モーリー:ユーチューブにとって?

津田大介:そうですね。

モーリー:ああ。

津田大介:というのは、去年から、ユーチューブ最近よく見るんですけど、ユーチューブ最近広告が入ってるんですね、動画とか見てるときに。

モーリー:うざいです。

津田大介:うざいんですけど、あれがやっぱりすごく著作権問題を解決する切り札になっているところがあって、実際に権利者の人が権利者用にちゃんとIDを発行していて、「もし権利者が違法行為を止めたいんだったらおまえらがオフィシャル動画を提供しろ」ということを言い出したんですね、去年から。それでフィンガープリントという技術を使って公式の本物の動画をきみらがアップしてくれれば、その本物の動画を一部切り出したりとか、音声とか動画のコマとかををぜんぶ照らし合わせてコピーを全部判別します、という技術が去年ぐらいからどんどんそれが進化していて、実際にその権利者の人のIDでログインしていたところを見ていたところがあるんですけれど、それで自分コンテンツを違法なものを探すってところをワンクリックでガーッって50とか10とか出てくるんです。それで権利者がそこで、昔だったらじゃあこういうものは認めませんよ削除しますって、全部にチェックを入れて、

モーリー:ユーチューブ勝手削除してくれる…

津田大介ユーチューブメールブラウザ上で、権利者用のツールが裏側に用意されていて、削除すると全部落とすことができたんですけれど。

モーリー:へー。

津田大介:ただ、それが二年ぐらい前の話なんですけれど、去年の春ぐらいから状況が変ってきて、もしこれで、落とすこともできるけれど、べつに黙認してもいいじゃん、その方がプロモーションになるってものもあるのでそういうものは黙認してもいいよっていうオプションと、あと最近広告を入れてその広告から得られる収入をユーチューブとあなたがた権利者でシェアしましょうよというオプションが去年の春ぐらいからできているんですね。それが結局功を奏しているみたいな感じ。そうするといままでだったら違法で全部落とすんだったのが、それが違法な動画だけど広告つけちゃってお金にかえるということが権利者が主体的に選択できるようになったので、それを日本コンテンツフォルダーの角川とかやっていて、このまえの報道だと自分たち角川が認めた違法動画広告をつけて合法化することで月間で一千万円の収入が入ってきたという話しだったんで、そういう意味で言うと、向こう側からして見たら権利の上手い転がしみたいのが自動で出来るようになるんですね。逆の言い方をすると、ユーチューブジャスラックみたいに著作権の処理を行う場所になっているという。そうすると角川がそういう態度を、角川が著作権を持っている著作権コンテンツユーチューブにアップするというのは、いままでは違法行為だったんですけど、角川はデキがいいものだったり、角川にリスペクトがあるようなMAD動画とかだったらそういうんであれば認めるらしいぞという方針を出していると、作る側も逮捕されたりするリスクが無くなるわけですよね。

モーリー:あの、逮捕ってまだあるんですか?

津田大介逮捕はありますよやっぱり。

モーリー:ええっ? 著作権で? 

津田大介著作権逮捕はいっぱいありますよ。

モーリー:たとえば、売り物になっているのをそのまんまなんら変らない状態で安く転売しているっていうんだったら海賊版だから逮捕っていうのはわかるんだけど、ただ乗せただけで逮捕っていうのはあるんですか? 

津田大介:一番最初にそれが日本であったのが、動画投稿サイトだと多分2005年だったかな。ファイナルファンタジーアドベントチルドレンっていうCG映画があったんですけど、スクエアエニックスに。あれがユーチューブが買う前のグーグルビデオという似たようなサービスをやっていて、あそこでDVDからリッピングしたデータをそのまんまあげてた日本人ユーザーがいたんですね。そしたらそれでスクエアエニックス側がそういう売り物が全部見れるようになったのはとんでもないっていうんでユーザーをつきとめて、逮捕寸前まで行ったんですけど、ユーザー反省しているということで罰金を払うことで和解をしたっていう事件があったんですけれど。

モーリー:民事ならわかるんですけどね、損害賠償だったら、それだけでもキツイと思うンだけど、刑事ですか?

津田大介:そういうんで逮捕されてるケースもありますね。

モーリー:はあー。

津田大介MAD動画みたいなもので逮捕というのはなかなか無いですけれど、実際に売り物をネットにあげているということで逮捕と。

モーリー:そのまんま頭からお尻まで買わなくて済むような目的だけという感じの?

津田大介:そうです。そういうのはありますね。ただ、実際に逮捕までいくケースは二種類なんですね。逮捕する前に、いきなり逮捕というのは結構少なくて、プロバイダーとかのいろんな開示請求とかをして、ユーザーに警告がいくんです。警告をした時に意図的にそれを無視するような悪質なユーザーか、もしくは匿名プロバイダーをどんどんいろいろ使って逃げ回っているような悪質性の高いユーザーは、GOサインが出て逮捕されるっていうケースがあるので、だいたいどっちかなんです。だから無邪気にとりあえずアップロードしていてそれでいきなり逮捕というケースはまあ少ないです。

モーリー:ふーん。階層別っていうか、道路の車が早く走るレーンと遅く走るレーンみたいにすごくスピード差みたいのを感じてまして、今日もまたウィニーで大変だったみたいで記事をネットで読んだんですけど、いまだにウィニーってまだ使っている人がいるというか

津田大介ウィニーネットワーク逮捕者が出ると一時的にトラフィックが減ったりするんですけど、ファイル交換ソフトって昔っからそうで、逮捕者が出ると一気にガッて減るんですけど、ほとぼりが冷めるとどんどんみんな使い出して増えていくというのが。で、ウィニーネットワークはまだまだ動いていますし、ウィニーと似たようなシェアというソフトがあって、あれもやっぱり利用者がいますからね。だからそういう人が、実際ウィニーとか使っていると非常に情報漏えいウィルス感染する可能性も高いし、あとセキュリティー的にもあぶないところもあるんですけど、それでもタダで音楽とかエロ動画とかを含めたいろんなソフトとかをそこが魅力で使いつづける人はまだいっぱいいますよね。


Posted by i-morley : 2009年01月16日 17:46

http://i-morley.com/blog/2009/01/post_166.html

http://www.tibetronica.com/i-morley/090116.zenhan.mp3

2008-10-17

http://anond.hatelabo.jp/20081006220009

YourFileHostのCAPTCHA画像をなんとかするの続き。

その後、適当にいじったら、手元環境で1枚あたり25秒くらい→だいたい2.5秒くらいで判別できるようになった。このくらいなら使えるかな。

速度向上に一番効いたのは、Token#importで画像を比較しているところの修正。他は細かい手直し。

使い方は前のやつと変わってません。

あと、テストに100枚くらいCAPTCHA画像食わせてみたけど、とりあえず全部正しく判定できた。

動作確認用のスクリプト (run.rb)

カレントディレクトリ以下にある*.gifCAPTCHA画像ファイル適当に判別するスクリプト。動作確認用にどうぞ。

後述のdecaptcha.rbと同じディレクトリ適当に置いてchmod +xしてね。

#!/usr/local/bin/ruby
$LOAD_PATH << File::dirname(File::expand_path($0))
require 'decaptcha'

STDOUT.sync = true

Dir.glob('*.gif').sort.each do |file|
  correct = File::basename(file, '.*')
  puts "Processing file: #{file}"
  start_time = Time.now
  ret = DeCAPTCHA.decode(file)
  elapsed = Time.now - start_time

  puts "  Result: #{ret} (=> #{(correct == ret) ? "Ok" : "Fail"})"
  puts "  Elapsed time: #{elapsed}"
  puts
end

コード (decaptcha.rb)

#!/usr/local/bin/ruby
require 'rubygems'
require 'gd2'
require 'pp'

#
#= CAPTCHA画像解析モジュール
# CAPTCHA画像ファイルを食わすとあら不思議Stringが出てくるよ。
# YourFileHostのやつに対応。
#
#== Usage
# decoded_str = DeCAPTCHA.decode("some_captcha_image.gif")  #=> String
# 失敗したらnilが返る。
#
module DeCAPTCHA
  DEBUG = false

  #=== CAPTCHA画像デコード
  # file::    画像ファイル名のパス
  # method::  未指定でよい。男は細かい事を気にするな。
  # returns:: CAPTCHA画像解析結果(String) or nil (デコード失敗時)
  def self.decode(file, method = DeCAPTCHA::Site::YourFileHost)
    return method.new(file).decode
  end



  #= CAPTCHA画像デコードクラス
  # このクラスサブクラスはimport, tokenize, stream_parseメソッドの
  # 実装を含む必要がある。
  class Site
    def initialize(file = nil)
      @pix = nil
      self.import(file) unless file.nil?
    end
    def decode
      return stream_parse(tokenize())
    end
  end

  #= YourFileHostのCAPTCHA画像を解析するクラス
  class Site::YourFileHost < Site
    def import(file)
      @pix = PixelMatrix.new.import(file)
      return self
    end

    # importしたイメージ(PixelMatrix)から、文字と思わしきパターンを
    # 抽出して上下マージンを切り取ってArrayにして返す。
    # returns:: Array of PixelMatrix
    def tokenize
      ret = []
      state = :initial
      for x in 0...@pix.width
        case state
        when :initial
          if !@pix.vline_blank?(x) then
            state = :tokenize
            pixel = PixelMatrix.new(0, 0, true)
            ret << pixel
            redo
          end
        when :tokenize
          if @pix.vline_blank?(x) then
            state = :initial
            next
          end
          x0 = pixel.width
          for y in 0...@pix.height
            pixel[x0, y] = @pix[x, y]
          end
        else
          raise 'NOTREACHED'
        end
      end

      ret.map! {|token| Token.new.import(token.cutoff_vmargin!) }
    end


    # PixelMatrixのArrayを受け取り、数字を判別。
    # tokens:: Array of PixelMatrix
    # returns:: String (判別結果)
    def stream_parse(tokens)
      rs = tokens.map {|x| x.guess.to_s }.join('')
      if rs.length != 4 then
        rs = nil
        if DEBUG then
          puts '- guess failed. dumping guess result of each token:'
          tokens.each_index do |i|
            print "##{i}:#{tokens[i].guess} "
            pp tokens[i].candidate
          end
          puts
        end
      end
      return rs
    end

    class Token
      @@digits = nil
      attr_accessor :candidate

      def initialize
        if @@digits.nil? then
          # 文字画像サンプルを作っておく
          @@digits = DIGITS_ASSOC.map {|digit|
            PixelMatrix.new(0, 0, true).import_array(digit) }
        end

        @candidate = Hash.new
      end

      # PixelMatrixを受け取り、文字画像サンプルと比較して
      # 一致率を計算しておく。
      # pixel:: PixelMatrix
      # returns:: self
      def import(pixel)
        @@digits.each_index do |i|
          digit = @@digits[i]

          if (digit.width - pixel.width).abs   > 4 or
             (digit.height - pixel.height).abs > 4 then
            @candidate[i] = -1  # サイズが違いすぎな場合、一致させない
            next
          end

          correct_bits = 0
          enlarged_width  = [digit.width,  pixel.width ].max
          enlarged_height = [digit.height, pixel.height].max
          for y in 0...enlarged_height
            dy = (y.to_f / digit.height * enlarged_height).to_i
            py = (y.to_f / pixel.height * enlarged_height).to_i
            for x in 0...enlarged_width
              dx = (x.to_f / digit.width * enlarged_width).to_i
              px = (x.to_f / pixel.width * enlarged_width).to_i
              correct_bits += 1 if digit[dx, dy] == pixel[px, py]
            end
          end

          @candidate[i] = correct_bits * 100 /
                          (enlarged_width * enlarged_height)
        end

        return self
      end

      # importのときの比較結果をもとに文字を推測
      # returns:: Fixnum or nil(失敗時)
      def guess
        digit, ratio = @candidate.sort {|a, b| a.last <=> b.last}.last
        digit = nil if ratio < 0 or ratio < 65
        return digit
      end
    end
  end


  #= 画素マトリックスクラス
  # 画像ファイルを食わせると、各ピクセル(画素)を2値(black(1) or white(0))に
  # 変換して、内部で保持する。
  # 以後、Matrixクラスのような感じで個々の画素アクセスできる。
  class PixelMatrix
    BLACK = 1
    WHITE = 0

    attr_accessor :width
    attr_accessor :height

    # width::  幅
    # height:: 高さ
    # is_flexible:: 自動的に伸張するか
    def initialize(width = 0, height = 0, is_flexible = false)
      @matrix = Hash.new {|hash, key| hash[key] = Hash.new(WHITE)}
      @width, @height, @flexible = width, height, is_flexible
    end

    # file:: 画像ファイル名のパス
    # brightness_threshold:: 画素を黒とみなす閾値 (0 - 255, default: 0x40)
    # returns:: self (DeCAPTCHA::PixelMatrix)
    def import(file, brightness_threshold = 0x40)
      gd = GD2::Image.import(file)
      @width, @height = gd.width, gd.height

      self.each_with_axis do |x, y|
        color = gd[x, y]
        greyscale = (color.red + color.green + color.blue) / 3
        self[x, y] = (greyscale > brightness_threshold) ?
          WHITE :
          BLACK
      end
      return self
    end

    def import_array(array)
      array.each_with_index do |str, y|
        str.split('').each_with_index do |c, x|
          self[x, y] = c.to_i
        end
      end
      return self
    end

    # PixelMatrixを画像ファイルとしてexport
    # file:: 新たに作る画像ファイル名のパス
    def export(file)
      gd = GD2::Image::IndexedColor.new(@width, @height)
      gd.palette << GD2::Color::WHITE
      gd.palette << GD2::Color::BLACK
      self.each_with_axis do |x, y|
        gd[x, y] = {
          WHITE => GD2::Color::WHITE,
          BLACK => GD2::Color::BLACK,
        }[self[x, y]]
      end
      gd.export(file)
      return self
    end

    # 指定された位置の画素を返す。
    # returns:: PixelMatrix::BLACK(1) or WHITE(0)
    def [](x, y)
      if !@flexible and !in_range?(x, y) then
        raise RangeError
      end
      return WHITE if !@matrix.has_key?(y)  # XXX: for optimize
      return @matrix[y][x]
    end

    # 画素に値を設定。
    # returns:: PixelMatrix::BLACK(1) or WHITE(0)
    def []=(x, y, val)
      unless in_range?(x, y) then
        raise RangeError unless @flexible
        @width  = (x >= @width)  ? x + 1 : @width
        @height = (y >= @height) ? y + 1 : @height
      end

      @matrix[y][x] = val
    end

    def in_range?(x, y)
      ((0...@width) === x and (0...@height) === y)
    end

    # 指定された軸をもとに画素を走査し、Arrayに変換。
    # 例えば、to_a(:vertical, 10) とすると、x == 10 な列を取り出して
    # Arrayにして返す。
    #
    # axis:: 軸を指定 (:vertical または :horizontal)
    # pos:: 位置を指定。_axis_で指定した軸と直交する軸における位置を指定。
    def to_a(axis, pos)
      {:vertical => lambda {
        (0...@height).map {|y| self[pos, y]}
       },
       :horizontal => lambda {
        (0...@width).map  {|x| self[x, pos]}
       },
      }[axis].call
    end

    # returns:: Array
    def hline(y)
      self.to_a(:horizontal, y)
    end

    # returns:: Array
    def vline(x)
      self.to_a(:vertical, x)
    end

    # X軸方向に画素を走査。
    # y:: どの位置で走査するか
    # returns:: 指定された軸の上にドットが存在: false, 無い: true
    def hline_blank?(y)
      return true if @matrix.has_key?(y) == false # XXX: for optimize
      for x in 0...@width
        return false if self[x, y] == BLACK
      end
      return true
    end

    # Y軸方向に画素を走査。
    # x:: どの位置で走査するか
    # returns:: 指定された軸の上にドットが存在: false, 無い: true
    def vline_blank?(x)
      for y in 0...@height
        return false if self[x, y] == BLACK
      end
      return true
    end

    # 上下のマージン削除した新しいPixelMatrixを返す。
    # returns:: PixelMatrix
    def cutoff_vmargin
      pixel = PixelMatrix.new(0, 0, true)
      head = 0
      tail = self.height - 1

      head.upto(tail) do |y|
        if !self.hline_blank?(y) then
          head = y
          break
        end
      end
      tail.downto(head) do |y|
        if !self.hline_blank?(y) then
          tail = y
          break
        end
      end

      head.upto(tail) do |y|
        0.upto(self.width - 1) do |x|
          pixel[x, y - head] = self[x, y]
        end
      end

      return pixel
    end
    
    # 自身の上下のマージン削除する。cutoff_vmarginの破壊版。
    # 速度稼ぎのために直接@matrixを触ったり、すこしずるをしている。
    # 効率は、ほんの少しだけ速くなったような誤差の範囲のような感じ。
    # returns:: self (PixelMatrix)
    def cutoff_vmargin!
      head = 0
      tail = self.height - 1

      head.upto(tail) do |y|
        if !self.hline_blank?(y) then
          head = y
          break
        end
      end
      tail.downto(head) do |y|
        if !self.hline_blank?(y) then
          tail = y
          break
        end
        @matrix.delete(y) if @matrix.has_key?(y)  # XXX
      end

      if head > 0 then
        head.upto(tail) do |y|
          next if !@matrix.has_key?(y)            # XXX
          @matrix[y - head] = @matrix.delete(y)   # XXX
        end
      end
      self.height = tail - head + 1

      return self
    end
    
    def each_with_axis
      for x in 0...@width
        for y in 0...@height
          yield(x, y)
        end
      end
    end
  end
end

class DeCAPTCHA::Site::YourFileHost::Token
DIGITS_ASSOC = [
  # 0
  ["00000000011111110000000000",
   "00000001111111111110000000",
   "00000011111000001111000000",
   "00001111111100010011110000",
   "00011111100000110000111000",
   "00111111000000100001111000",
   "00111111110001000001111100",
   "01111111000010000011111110",
   "01111100000110000111111110",
   "01111111000100000111111110",
   "11111100001000001111111111",
   "11100000001000011111111111",
   "11111000010000011111111111",
   "11111000110000111111111111",
   "10000000100001111111111111",
   "01100001000001111111111110",
   "01100010000011111111111110",
   "01100010000111111111111110",
   "00111100000111111111111100",
   "00011100001111111111111000",
   "00001100011111111111111000",
   "00001111111111111111100000",
   "00000011111111111111000000",
   "00000000111111111100000000"],
  # 1
  ["00001",
   "00111",
   "11111",
   "11111",
   "10001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001"],
  # 2
  ["0000011111111110000000",
   "0001111111111111000000",
   "0011110000000010000000",
   "0110000000000100000000",
   "1100000000001100011110",
   "1000000000001000001111",
   "1000000000010000000111",
   "1000000000110001111111",
   "1000000000100001111111",
   "1000000001000000011111",
   "0100000011000001111111",
   "0011000010000111111110",
   "0011000110000001111110",
   "0000001100000111111100",
   "0000001000011111110000",
   "0000011000000111100000",
   "0000110000000000000000",
   "0000111111111111111111",
   "0001111111111111111110",
   "0011111111111111111100",
   "0011111111111111111100",
   "0111111111111111111000",
   "0111111111111111110000"],
  # 3
  ["000000011111111110000000",
   "000001111111111111100000",
   "000011100000011111111000",
   "000111000000111111111000",
   "000110000001111111111100",
   "000100000001111111111100",
   "000100000011111111111100",
   "000110000111111111111000",
   "000010000111111111111000",
   "000000001111111111100000",
   "000000011111111111000000",
   "000000011111111110000000",
   "000000000000001100000000",
   "000000000000011100011100",
   "000000000000111000111110",
   "000000000000110000001110",
   "000000000001110001111111",
   "110000000011100011111111",
   "111000000111000000111110",
   "011100000110001111111100",
   "001111001110000111111000",
   "000011111100000011100000",
   "000000011000111000000000"],
  # 4
  ["0000000000011",
   "0000000000011",
   "0000000000111",
   "0000000001111",
   "0000000001111",
   "0000000011111",
   "0000000111111",
   "0000000110111",
   "0000001100111",
   "0000011100111",
   "0000011000111",
   "0000110000111",
   "0001110000111",
   "0001100000111",
   "0011000000111",
   "0111000000111",
   "0111111111111",
   "1111111111111",
   "0000000000111",
   "0000000000111",
   "0000000000111",
   "0000000000111",
   "0000000000111"],
  # 5
  ["000000001111111111111110",
   "000000011111111111111100",
   "000000111111111111111100",
   "000000111111111111111000",
   "000001111111111111110000",
   "000011100000000000000000",
   "000011011111111110000000",
   "000111111111111111000000",
   "001111100000000111000000",
   "001110000000000110001100",
   "000000000000000100011110",
   "000000000000001100000110",
   "000000000000011000011111",
   "000000000000011001111111",
   "000000000000110000011111",
   "000000000001100000111111",
   "110000000001100111111110",
   "011000000011000001111110",
   "011100000110000011111100",
   "001111000110011111111000",
   "000111111100001111110000",
   "000001111100000011000000",
   "000000001000011000000000"],
  # 6
  ["000000000000000110000000",
   "000000010001111111111000",
   "000001110000011100111100",
   "000011100000011000001000",
   "000111000011111000000000",
   "001111000001110000000000",
   "001110000000111100000000",
   "011110001111111111100000",
   "011100000111000011110000",
   "011000000010000001111000",
   "011000011110000011111100",
   "010000111100000111111110",
   "100000001000000111111110",
   "100001111000001111111111",
   "000011110000011111111111",
   "000000100000011111111111",
   "000011100000111111111111",
   "001111000001111111111110",
   "000010000001111111111110",
   "001110000011111111111100",
   "000111000111111111111000",
   "000011111111111111110000",
   "000000111111111111000000",
   "000000000111111000000000"],
  # 7
  ["0011111111111110001111",
   "0011111111111100000011",
   "0111111111111000000110",
   "1111111111111000111100",
   "1111111111110000001100",
   "0000000000000000011000",
   "0000000000000011111000",
   "0000000011000000110000",
   "0000001110000011100000",
   "0000011110001111100000",
   "0000111100000011000000",
   "0001111000000110000000",
   "0001111000111110000000",
   "0011110000001100000000",
   "0011110000001000000000",
   "0011100011111000000000",
   "0011000001110000000000",
   "0001000000110000000000",
   "0000000111100000000000",
   "0000000111000000000000",
   "0000000011000000000000",
   "0000001110000000000000",
   "0000001100000000000000"],
  # 8
  ["0000000111111111110000000",
   "0000011111111111111100000",
   "0000001111100000011110000",
   "0000000001110000000111000",
   "0011000011111000000011100",
   "0011100001111100000011100",
   "0011110000001110000011100",
   "0001111000011111000111000",
   "0000111100000111101110000",
   "0000011110000001111100000",
   "0000001111000011111110000",
   "0000111111110000011111000",
   "0011110011111000001111100",
   "0111100001111100011111100",
   "0111000000111110000111110",
   "1111000000011111000000111",
   "1111000000001111100011111",
   "1111000000000011111000010",
   "0111100000000001111100000",
   "0011110000000000111110000",
   "0001111110000001111110000",
   "0000011111111111111000000",
   "0000000011111110000000000"],
  # 9
  ["000000111111111110000000",
   "000001111111111111100000",
   "000111111111111001111000",
   "001111111111110000010000",
   "011111111111110000010000",
   "011111111111100000100000",
   "011111111111000001100000",
   "111111111110000001000111",
   "111111111110000010000001",
   "111111111100000110000111",
   "011111111000000100011111",
   "011111111000001000001111",
   "001111110000011000011111",
   "001111100000010001111110",
   "000111110000100000011110",
   "000001111111100000111110",
   "000000011111000111111100",
   "000000000010000001111100",
   "000000000110000001111000",
   "000100001100011111110000",
   "000111001100001111100000",
   "000011111000001111000000",
   "000000010000110000000000"],
]
end
__END__

2008-10-12

人生というゲームを笑うものは人生というゲームに泣く

本気でがんばるとぎりぎり倒せるように絶妙のバランス調節がされた敵(困難)。

単純作業じゃ効率が悪いけど、工夫次第でどんどん効率を上げられる経験システムスキル)。

リセット不可の緊張感。でもシレンとかよりずっと死ににくいからあんま気にする必要なし。

つーか普通ゲームでもリセットなんて邪道じゃん。

全てのキャラが深い人間性と歴史を持って登場する、圧倒的リアリティ。

グラフィックが綺麗すぎ。多分、無限×無限ピクセルで、毎秒無限フレームで動いてる。

色も多分無限色使える。夕焼けとかマジありえねー美しさ。

BGMの種類がほぼ無限。選曲も自由。自分で作った曲を流すこともできる。

人間が作ったとは思えない、とんでもなく複雑で洗練されたシナリオ

リアル出産システム採用。自分と、自分よりも大切に思える相手の遺伝子を半分ずつ受け継いだ、

奇跡のようなキャラを生み出して、そいつに自由に色々教えて育てることができる。

すごく嬉しいし、ちょー楽しい

ネコっつー生き物が登場するんだけど、これがちょーかわいい。

食いきれねーほどの種類の料理があって、超うまいものが時々食える。

説明書が無く、仕様が明かされてないから、自分でデータとって仕様を推測するしかない。

これがまたとんでもなく高度に洗練された仕様になってるっぽくて、なかなか正確には分からん。

だから、とりあえず大雑把に推定し、それに基づいて行動して

データを取りつつ徐々に予測値を修正していく必要がある。

これがまた楽しい。徐々に明らかになっていく世界観。未だに明らかになってない謎が山盛り。

友達と一緒に協力して遊べる。無料。本気で自分を愛してくれるキャラがいたりする。

ゲーム内で別なゲームやったりアニメ見たり出来る。登場キャラと本当に心を通わせることが出来る。

信じがたいほど深い感動を味わえるイベントが結構ある。

もちろん本気でやらないとフラグ無駄にするだけだが。

こんなとてつもない神ゲーを糞ゲーとか言ってる奴は、本気でこのゲームをやったことがない奴だけ。

まあ、一切がんばらずにクリアできるようなヌルゲーばかりやってる奴には、

このゲームはちょいとハードかもしれんがな。


出典: 2ちゃんねるコピペ

タイトルホッテントリメーカー

2008-10-09

Photoshopのどこに10万円の価値があるか

はてブで定期的に紹介が注目URLに挙がってくるような、WebPhotoshop並!とかよく言ってる無料サービス案内があるのでちょっと気になってな。

CMYK画像がちゃんと扱えるとか、カラープロファイル処理がきちんとできるとか、外部から操作できるとかもあるけど、一番は「10億ピクセルくらいある画像をまともに扱える唯一の一般入手可能ソフト」というところですよ! Gimpだと超巨大画像を実用的な速度で扱えない。まあでも家庭でデジカメ画像処理お絵かきに使う限りではGimpで十分です。

同様にOOoは数千標本点のグラフをまともに書けないのでやっぱりExcelに勝てなかったりする。

2008-10-06

YourFileHostのCAPTCHA画像をなんとかする

破ろうぜ!CAPTCHA画像♪(うっうーん)

そんなわけで、みんな大好きなYourFileHostだけども、最近みてみたら、なんかCAPTCHA認証がついているわけじゃないですか。

でもこれってさーCAPTCHAといっても見るからに危ういというか、見れば見るほど簡単に破れてしまいそうな気がして、どうにもむずがゆいアンニュイな気分になってしまうわけです。

そんで、このたび適当にいじってみたところ、それなりに推測できるコードが書けたので、ここに張ってみますね。

やってることは単純で、こんな感じ

  1. CAPTCHA画像ファイルをよみこむ
  2. ピクセルごとにグレイスケールにして、それで2値にする
  3. この時点でじゃまな背景が消えて、文字の形がわかってしまうわけです
  4. 縦軸に点がないところで切って、文字ごとにばらばらにする
  5. 文字画像のサンプルと比較して、一致率が高いものを採用

使い方は、こんな感じで

require 'decaptcha.rb'
captcha_string = DeCAPTCHA.decode(filename)
if !captcha_string.nil? then
  # 判別成功時の処理
else
  # 判別失敗時の処理。失敗することもあるのでよしなに。
end

あ、Ruby/GD2入れといてね。sudo gem install gd2とかで入ります。多分。

判別率はそこそこ良い感じになったんだけども、富豪プログラミングがたたってか、いかんせん遅いです。

手元だと1枚判別するのに20秒くらいかかることもある。

そんなわけで誰かチューニングしてくれるとうれしい。

追記

実行速度を上げた改良版はこっちにうpしました。以下のコードは参考程度に。

コード (decaptcha.rb)

#!/usr/local/bin/ruby
require 'rubygems'
require 'gd2'
require 'pp'

#
#= CAPTCHA画像解析モジュール
# CAPTCHA画像ファイルを食わすとあら不思議Stringが出てくるよ。
# YourFileHostのやつに対応。
#
#== Usage
# decoded_str = DeCAPTCHA.decode("some_captcha_image.gif")  #=> String
# 失敗したらnilが返る。
#
module DeCAPTCHA
  DEBUG = false

  #=== CAPTCHA画像デコード
  # file::    画像ファイル名のパス
  # method::  未指定でよい。男は細かい事を気にするな。
  # returns:: CAPTCHA画像解析結果(String) or nil (デコード失敗時)
  def self.decode(file, method = DeCAPTCHA::Site::YourFileHost)
    return method.new(file).decode
  end



  #= CAPTCHA画像デコードクラス
  # このクラスサブクラスはimport, tokenize, stream_parseメソッドの
  # 実装を含む必要がある。
  class Site
    def initialize(file = nil)
      @pix = nil
      self.import(file) unless file.nil?
    end
    def decode
      return stream_parse(tokenize())
    end
  end

  #= YourFileHostのCAPTCHA画像を解析するクラス
  class Site::YourFileHost < Site
    def import(file)
      @pix = PixelMatrix.new.import(file)
      return self
    end

    # importしたイメージ(PixelMatrix)から、文字と思わしきパターンを
    # 抽出して上下マージンを切り取ってArrayにして返す。
    # returns:: Array of PixelMatrix
    def tokenize
      getter, tokenizer = lambda {|queue|
        [ lambda { return queue },
          lambda {|x, pixel|
            if pixel.nil? then
              x, pixel = tokenizer.call(x, PixelMatrix.new(0, 0, true))
              queue << pixel
              return x
            end
  
            if !@pix.in_range?(x, 0) or @pix.vline_blank?(x) then
              return [x, pixel]
            end
            x0 = pixel.width
            @pix.vline(x).inject(0) do |y, color|
              pixel[x0, y] = color
              y + 1
            end
            return tokenizer.call(x + 1, pixel)
          }
        ]
      }.call([])

      x = 0
      while (x < @pix.width)
        x = @pix.vline_blank?(x) ?
          x + 1 :
          tokenizer.call(x, nil)
      end

      getter.call.map do |token|
        # Token.new.import(token.cutoff_vmargin.shrink)
        Token.new.import(token.cutoff_vmargin)
      end
    end

    # PixelMatrixのArrayを受け取り、数字を判別。
    # tokens:: Array of PixelMatrix
    # returns:: String (判別結果)
    def stream_parse(tokens)
      r = []
      tokens.inject(nil) do |prev, cur|
        r << cur.guess
      end

      rs = r.map {|x| x.to_s}.join('')
      if rs.length != 4 then
        if DEBUG then
          puts '- guess failed. dumping guess result of each token:'
          tokens.each_index do |i|
            print "##{i}: "
            pp tokens[i].candidate
          end
          puts
        end
        return nil
      end
      return rs
    end

    class Token
      @@digits = nil
      attr_accessor :candidate

      def initialize
        if @@digits.nil? then
          # 文字画像サンプルを作っておく
          @@digits = DIGITS_ASSOC.map {|assoc|
            PixelMatrix.new(0, 0, true).import_assoc(assoc) }
        end

        @candidate = Hash.new
      end

      # PixelMatrixを受け取り、文字画像サンプルと比較して
      # 一致率を計算しておく。
      # pixel:: PixelMatrix
      # returns:: self
      def import(pixel)
        gcd = lambda {|a, b|
          a, b = [b, a] if a < b
          return a if b == 0
          r = a % b
          return gcd.call(b, r)
        }
        lcm = lambda {|a, b| a * b / gcd.call(a, b) }
        mul_to_lcm = lambda {|a, b|
          g = gcd.call(a, b)
          [b / g, a / g]
        }

        0.upto(@@digits.size - 1) do |i|
          if (@@digits[i].width - pixel.width).abs   > 4 or
             (@@digits[i].height - pixel.height).abs > 4 then
            @candidate[i] = -1  # 比較対象とサイズが違いすぎ
            next
          end

          mul_ax, mul_bx = mul_to_lcm.call(@@digits[i].width,  pixel.width)
          mul_ay, mul_by = mul_to_lcm.call(@@digits[i].height, pixel.height)
          enlarged_width  = @@digits[i].width  * mul_ax
          enlarged_height = @@digits[i].height * mul_ay

          # 文字画像サンプルと比較対象画像のサイズをあわせる
          # 幅・高さをそれぞれ適当整数倍して、最小公倍数に合わせて比較
          # (めんどうだから)
          correct_bits = 0
          (0...enlarged_width).each do |x|
            (0...enlarged_height).each do |y|
              if @@digits[i][x/mul_ax, y/mul_ay] ==
                 pixel[x/mul_bx, y/mul_by] then
                correct_bits += 1
              end
            end
          end
          
          @candidate[i] = correct_bits * 100 /
                          (enlarged_width * enlarged_height)
        end

        return self
      end

      # importのときの比較結果をもとに文字を推測
      # returns:: Fixnum or nil(失敗時)
      def guess
        digit, ratio = @candidate.sort {|a, b| a.last <=> b.last}.last
        digit = nil if ratio < 0 or ratio < 80
        return digit
      end
    end
  end


  #= 画素マトリックスクラス
  # 画像ファイルを食わせると、各ピクセル(画素)を2値(black(1) or white(0))に
  # 変換して、内部で保持する。
  # 以後、Matrixクラスのような感じで個々の画素アクセスできる。
  class PixelMatrix
    BLACK = 1
    WHITE = 0

    attr_accessor :width
    attr_accessor :height

    # width::  幅
    # height:: 高さ
    # is_flexible:: 自動的に伸張するか
    def initialize(width = 0, height = 0, is_flexible = false)
      @matrix = Hash.new {|hash, key| hash[key] = Hash.new(WHITE)}
      @width, @height, @flexible = width, height, is_flexible
    end

    # file:: 画像ファイル名のパス
    # brightness_threshold:: 画素を黒とみなす閾値 (0 - 255, default: 0x40)
    # returns:: self (DeCAPTCHA::PixelMatrix)
    def import(file, brightness_threshold = 0x40)
      gd = GD2::Image.import(file)
      @width, @height = gd.width, gd.height

      self.each_with_axis do |x, y|
        color = gd[x, y]
        greyscale = (color.red + color.green + color.blue) / 3
        self[x, y] = (greyscale > brightness_threshold) ?
          WHITE :
          BLACK
      end
      return self
    end

    # reverse function of to_assoc
    def import_assoc(assoc)
      assoc.inject(0) do |y, columns|
        columns.inject(0) do |x, color|
          self[x, y] = color
          x + 1
        end
        y + 1
      end
      return self
    end

    # PixelMatrixを画像ファイルとしてexport
    # file:: 新たに作る画像ファイル名のパス
    def export(file)
      gd = GD2::Image::IndexedColor.new(@width, @height)
      gd.palette << GD2::Color::WHITE
      gd.palette << GD2::Color::BLACK
      self.each_with_axis do |x, y|
        gd[x, y] = {
          WHITE => GD2::Color::WHITE,
          BLACK => GD2::Color::BLACK,
        }[self[x, y]]
      end
      gd.export(file)
      return self
    end

    def to_assoc
      (0...@height).map do |y|
        (0...@width).map do |x|
          self[x, y]
        end
      end
    end

    # 指定された位置の画素を返す。
    # returns:: PixelMatrix::BLACK(1) or WHITE(0)
    def [](x, y)
      if !@flexible and !in_range?(x, y) then
        raise RangeError
      end
      return @matrix[y][x]
    end

    # 画素に値を設定。
    # returns:: PixelMatrix::BLACK(1) or WHITE(0)
    def []=(x, y, val)
      unless in_range?(x, y) then
        raise RangeError unless @flexible
        @width  = (x >= @width)  ? x + 1 : @width
        @height = (y >= @height) ? y + 1 : @height
      end

      @matrix[y][x] = val
    end

    def in_range?(x, y)
      ((0...@width) === x and (0...@height) === y)
    end

    # 指定された軸をもとに画素を走査し、Arrayに変換。
    # 例えば、to_a(:vertical, 10) とすると、x == 10 な列を取り出して
    # Arrayにして返す。
    #
    # axis:: 軸を指定 (:vertical または :horizontal)
    # pos:: 位置を指定。_axis_で指定した軸と直交する軸における位置を指定。
    def to_a(axis, pos)
      {:vertical => lambda {
        (0...@height).map {|y| self[pos, y]}
       },
       :horizontal => lambda {
        (0...@width).map  {|x| self[x, pos]}
       },
      }[axis].call
    end

    # returns:: Array
    def hline(y)
      self.to_a(:horizontal, y)
    end

    # returns:: Array
    def vline(x)
      self.to_a(:vertical, x)
    end

    # X軸方向に画素を走査。
    # y:: どの位置で走査するか
    # returns:: 指定された軸の上にドットが存在: false, 無い: true
    def hline_blank?(y)
      hline(y).find {|color| color == BLACK }.nil? ?
        true : false
    end

    # Y軸方向に画素を走査。
    # x:: どの位置で走査するか
    # returns:: 指定された軸の上にドットが存在: false, 無い: true
    def vline_blank?(x)
      vline(x).find {|color| color == BLACK }.nil? ?
        true : false
    end

    # 上下のマージン削除した新しいPixelMatrixを返す。
    # returns:: PixelMatrix
    def cutoff_vmargin
      pixel = PixelMatrix.new(0, 0, true)
      head = 0.upto(self.height - 1) do |y|
        break(y) if !self.hline_blank?(y)
      end
      tail = (self.height - 1).downto(0) do |y|
        break(y) if !self.hline_blank?(y)
      end

      head.upto(tail) do |y|
        y0 = pixel.height
        self.hline(y).inject(0) do |x, color|
          pixel[x, y0] = color
          x + 1
        end
      end

      return pixel
    end
    
    def each_with_axis
      (0...@width).each {|x|
        (0...@height).each {|y|
          yield(x, y)}}
    end
  end
end

class DeCAPTCHA::Site::YourFileHost::Token
DIGITS_ASSOC = [
# 0
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
 [0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]
],
# 1
[[0, 0, 0, 0, 1],
 [0, 0, 1, 1, 1],
 [1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1],
 [1, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1]],
# 2
[[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
 [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
 [0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
 [0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0]],
# 3
[[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
 [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0],
 [0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
# 4
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1],
 [0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1],
 [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1],
 [0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1],
 [0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1],
 [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1],
 [0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1]],
# 5
[[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1],
 [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0],
 [0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
# 6
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
 [0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
# 7
[[0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1],
 [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
# 8
[[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0],
 [0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
 [0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
 [0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0],
 [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1],
 [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0],
 [0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
# 9
[[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1],
 [0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1],
 [0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0],
 [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
]
end


__END__
Dir.glob('*.gif').each do |file|
  puts "Processing file: #{file}"
  p DeCAPTCHA.decode(file)
end

__END__

2008-09-21

http://anond.hatelabo.jp/20080920224443

http://anond.hatelabo.jp/20080920224443

フルハイビジョンパネルの大きな液晶テレビでも、横1300ピクセル程度の26インチ液晶テレビでも、同じようにエッジにノイズが見えるんです。

それ多分MPEG特有のブロックノイズだよ。放送局ビットレートケチるからそういう発生しているだけだと思う。DVD並みのビットレートで解像度が実質縦横1.5倍になってるから、放送局番組の内容によっては相当なノイズが走る事もある。量販店ではデモンストレーション代わりにNHK海外ドキュメンタリーとか流してる所多いが、小川の流水やヘリコプターから撮影した森林のシーンになると、ブロックノイズまくりで目も当てられない事もしばしば。

純粋パネルの性能を見たいのならBD再生している台を探してみるといい。DVDは小さい解像度を引き延ばしているので余り参考にはならないかも知れない。たとえば俺の近所の某YMD電機は、同じテレビを二台並べて、同じ映像作品で一方をDVD版、もう一方をBD版にして同時に再生し、画質を比べさせるというデモをやってる。

2008-09-20

http://anond.hatelabo.jp/20080920154619

元増田です。

フルハイビジョンパネルの大きな液晶テレビでも、横1300ピクセル程度の26インチ液晶テレビでも、同じようにエッジにノイズが見えるんです。だから液晶テレビであるがゆえの悪目立ちなんじゃないかなあと思った次第です。

有機ELテレビとは贅沢な選択ですね!一度画面を見てみます。ただあの画面サイズ/お値段では今の家庭経済事情にもとづき供出できないと思います。11インチで20万円!

2008-09-10

はてなダイアリーはてな

別の場所にblogがあるんやけど、広告が目障りに感じるようになったため、引越しを考えてblog巡りをしてたんやけど。

はてなダイアリーって、無料でも有料でも広告が無いのはなんで?

無料のほうに広告表示しなくて大丈夫なんかな?

見て回った感じでは登録情報の欄に「有料オプション利用中」って書いてる人は少なかった。

はてなって…どうやってお金をかせいでるんやろう…

はてなへ引越すにあたって不安なのが画像の大きさ(150ピクセルに縮小されること)と枚数(1日1枚)なんやけど、これは"はてなフォトライフ"を使えば解決する問題なのかな?と思っていて。


はてなダイアリーって欠点ないのかな。

2008-06-23

http://anond.hatelabo.jp/20080623004418

同じだけのデータサイズに収録できる情報量は、どういうサンプリングの仕方をしたって同じでしょ

24bit96kHzと16bit44.1kHzではデータサイズが違う。画像で言えば解像度の違いってところか。

そんで、同じ形式の生データならともかく、圧縮するのであれば、アルゴリズムによって同じデータサイズでも情報量は変わるでしょ。可逆圧縮の例の方が解り易いけど、zipよりもbz2の方が圧縮率は高くて、1MBのzipと1MBのbz2を解凍したら後者の方が大きいものが入ってる(だろう)。

10MBの画像データ(tiff)があって、それを2.5MBに収めようと思った時に、tiffのまま解像度を半分にする(ピクセル数を1/4にする)か、JPEG2000で圧縮するか。後者の方がたぶん綺麗だよね?

2.5MBに成るように解像度を下げたファイルをさらにJPEGで圧縮したら、2.5MB tiffよりも画質が悪いのは当然だけど、10MB tiffを2.5MBにJPEG圧縮したなら、そっちの方が2.5MBtiffよりも綺麗(なはず)。

2008-04-18

現実と虚構の区別(ry

http://anond.hatelabo.jp/20080416212318

なんの作品かは知らないけど、それはアポロ陰謀論者のパロディなんじゃないの?

その発話者が電波くんであるか、もしくは、その架空世界は本当にそういう設定で、その設定自体がアポロ陰謀論者を揶揄しているのかもしれない。

もしそうだとしたら、フライングスパゲッティモンスター教に非科学的だとマジギレしてるようなもんで、アホ丸出しだぞ。

http://anond.hatelabo.jp/20080416231512

これなんかは、モニタ上でRGB画素画像が構成されることを指して言ってるんじゃないの。つまり、それがゲーム世界の「リアリティ」、所詮モニタの中の作り事、全部ピクセルで出来てんだよ、ということを示したジョーク

2008-03-19

http://anond.hatelabo.jp/20080319164130

育児神ゲーだ。

リアル成長システム採用。自分と、自分よりも大切に思える相手の遺伝子を半分ずつ受け継いだ、奇跡のようなキャラに自由に色々教えて育てることができる。

すごく嬉しいし、ちょー楽しい

本気でがんばるとぎりぎりクリアできるように絶妙のバランス調節がされたイベント。単純作業じゃ効率が悪いけど、工夫次第でどんどん効率を上げられる経験値システム

リセット不可の緊張感。でもシレンとかよりずっと死ににくいからあんま気にする必要なし。つーか普通ゲームでもリセットなんて邪道じゃん。

全てのキャラが深い人間性と歴史を持って登場する、圧倒的リアリティ。

グラフィックが綺麗すぎ。多分、無限×無限ピクセルで、毎秒無限フレームで動いてる。色も多分無限色使える。「保育園パパ描いたのー、見てー」とかマジありえねー美しさ。

BGMの種類がほぼ無限。選曲も自由。自分で作った曲を流すこともできる。人間が作ったとは思えない、とんでもなく複雑で洗練されたシナリオ

ネコっつー生き物が登場するんだけど、これがちょーかわいい。

食いきれねーほどの種類の料理があって、超うまいものを食わせてやれる。自分で作ってもいい。

説明書が無く、仕様が明かされてないから、自分でデータとって仕様を推測するしかない。これがまたとんでもなく高度に洗練された仕様になってるっぽくて、なかなか正確には分からん。

だから、とりあえず大雑把に推定し、それに基づいて行動して、データを取りつつ徐々に予測値を修正していく必要がある。

これがまた楽しい。徐々に明らかになっていく世界観

未だに明らかになってない謎が山盛り。

友達と一緒に協力して遊べる。

無料

本気で自分を愛してくれるキャラがいたりする。

ゲーム内で別なゲームやったりアニメ見たり出来る。

登場キャラと本当に心を 通わせることが出来る。

信じがたいほど深い感動を味わえるイベントが結構ある。もちろん本気でやらないとフラグ無駄にするだけだが。

こんなとてつもない神ゲーを糞ゲーとか言ってる奴は、本気でこのゲームをやったことがない奴だけ。

まあ、一切がんばらずにクリアできるようなヌルゲーばかりやってる奴には、このゲームはちょいとハードかもしれんがな。でも一端ハマった奴はみんな、このゲームを辞めたくないって言ってるぜ

2008-03-05

WEB屋底辺の品格

俺しがないWEB屋なんだけど、とあるWEBアプリケーションを頼まれで作ったときの話。

何でもやるIT土方なので、本当はデザインからシステムまで全部こっちで引き受けたいところなんだけど、発注側(代理店)が最初から勝手に「このイメージでいく」とクライアントに提出してて引っ込みつかなかったらしく、デザインに関しては別のWEB制作業者を入れ込んできた。


早速デザインイラレであがってきたのだがこれがひどい。

CMYKなのは許すとして、単位が全てmm。しかも整数になってないので手で適当に置いたのがバレバレ。

もしかしてpxに変換すると整数になるのかもしれないと期待してみたが、案の定、もっと酷い状況に。

大きさも配置も小数が混じるので、画面に書き起こしたときに同じ要素でも幅も高さも位置も2-3px程度ばらける破目に。


何べん言っても改善してくれない。

ピクセルとかアンチエイリアスとかすら理解してくれないので「じゃあ書き出すときアンチエイリアスを切ればいいじゃないですか」とか言われるし。れっきとした株式会社が自社のサイトの事業にWEBデザインもやりますとか書いてあるのに。

わかってもらえないようなので、言いがかりと捕らえられない様、丁寧に説明してるんだがそれでも聞く耳を持たない。

最終的には「あなたの言ってることがわからない。そんなに気になるんであればそちらで対応すれば」という一方的な態度に出られた。

仕方なく、もらった「素材」をもとに、全てこちらで作り直した。


それでも先方はしっかり「WEBデザイン」として予算の全額を持っていきやがった。

もちろん、代理店に説明しても理解されなかった。

最初にしっかり納品物の用件定義をしなかった俺を含めて、

WEB屋の底辺ってこんなもの。

2008-02-19

ノートPCでのデュアルディスプレイ

ノートPCデュアルディスプレイをするのってのはいろいろ制約があるんだな。

今は中古で1万で買ったXGA(1024x768)のモニタをセカンドモニタとして使っていたけど、解像度が高い&ワイドのが欲しいと思い物色。

ゼミ研究室にあるSXGA(1280x1024)のモニタデュアルディスプレイが行けたからそれよりはピクセル数が少ないWXGA+(1440x900)のモニタがいけると思ったがサポートしているとは書いてない・・・

webサイトには”アナログVGAでの出力”は1600×1200、1360×768、1280×1024、1280×768、1024×768、800×600としか書かれておらず。

しかもこれにはノートPC内蔵のXGA液晶とあわせての表示とは書かれていないし・・・・。

何ではっきり書いてくれないのかなぁ。

グラフィックアクセラレータIntel GMA 950なのでしょぼしょぼなのは分かるけどはっきりして欲しいなぁ。

2008-02-06

まちがい

http://anond.hatelabo.jp/20080206033709

XPまでのWindowsも描画はグラフィックスカードハードウェアで行っているよ。CPUレンダリングなどしていない。

Windows3.1の頃からずっと。


あと、GPUに回せば負荷が軽くなるからってGPUをぶん回すと消費電力が上がるので、ミニノートには向かない。切ったほうがいい。体感速度は上がるけど、視覚効果を切ってもピクセルシェーダで描画するのは電力の無駄遣い。GDI経由で書くのが分相応ってやつだ

- 転職ならen
- 派遣ならen
2ページ中1ページ目を表示(合計:41件)