はてなキーワード: ピクセルとは
2: 昔は「20円」だったガチャガチャを「300円」にして、実物ない商品で大儲けしてる会社があるらしい (20)
4: 【速報】FOXの神対応によりスクリプト壊滅へ (834)
6: 名無し雑談 120204【人間寄っといでー!】 (994)
7: 英王子、フォークランドに派遣 アルゼンチン「征服者の服を着て私たちの土地に入るようなもの」 (4)
8: スレ立て依頼所 キタ─wwヘ√レvv~(゚∀゚)─wwヘ√レvv~─!! (36)
9: カリフォルニア米は美味いから、TPP参加したらコスパ重視でみんな買っちゃうだろうね (18)
11: 超低価格車「ナノ」の高級モデルを販売 ハヤブサのエンジン搭載で1500万円以上 しかも売れる (1)
12: 【速報】京都市長選 無所属現職の門川氏が当選確実 (1)
14: 【画像】早食い王 小林尊さん、手羽先でもV (15)
18: 楽天 「ウッ!!」楽天・武藤 シャラポワ投法でローテ名乗り (5)
24: ラツィオ、本田資金13億円!公式HPで提示内容公開 (2)
25: 香川「もう、すごい」ダメ押し“アシスト”4連勝! (2)
27: 【血と鉄】 ビスマルクの肉声が発見される 発明王エジソンのお手柄 (4)
29: ステマと言われて困っています。- 2ちゃんねる知恵袋 (10)
33: 野球盤の歴史に新たな魔球が刻まれた。その名は......!? (2)
34: 【原発】 福島で鳥が減少、脳が萎縮、生殖能力低下なども (11)
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)
この努力は僕が 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年で僕にはっきりと感じられた。僕は競争相手のプレッシャー、 Microsoft や Amazon や最近じゃ 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 になる必要はないっていうことを。インターフェースとワークフローこそが、人々が気に入り、安心感を得るものなんだっていうことを。彼はサードパーティの開発者にそれを可能にするだけで良かった。そうすれば、後の事は自動で進んでいく。
僕の言っていることが、あまりにも明白なことだろって感じているみんな(多かったらいいな)には申し訳ない。とにかくもうびっくりするほど自明なことなんだ。ただ、僕らがそれをやってないってことを除いてはね。僕らはプラットフォームを理解していない。プラットフォームを持っていない。アクセシビリティを理解していない。アクセシビリティを持っていない。これらは基本的には同じことだ。なぜならプラットフォームがアクセシビリティを解決するからだ。プラットフォームがアクセシビリティなんだよ。
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 システムとライブラリ管理システムが、まさに Amazon が Google より優れている三つのうちの二つだ。
早期にリリースして、狂ったようにイテレートするってのも彼らのうまいところじゃないかって言うかも知れない。けど逆もまたしかり。彼らは早期にリリースすることを何にもまして優先する。品質保持やらエンジニアリング規則、その他長い目で見たら重要になってきそうなものはみんな後回し。そんなだからたとえ市場で競争相手よりアドバンテージがあったとしても、結局ちょっとしたことをやるのにも問題を起こしちゃうよね。
でも、一つ、そんな政治的な、思想的な、技術的なへまを補うだけの、彼らが本当に本当にうまくやってることがある。
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 の開発スタッフはその途上でとにかくたくさんの発見をした。そのほんの一部をちょっぴり挙げると、こんな感じだった。
とまあこれらがほんの一例。他にもたくさんの、おそらく何百の、 Amazon が見つけた個別の発見や教訓があった。外部サービスにはおかしなところがいくつもあったけれど、君たちが考えるほどじゃあない。サービスに対して組織するってことは、外部のデベロッパを信用できないのと同じように、お互いを信用することなんてできないんだということを、チームに教えてくれたんだ。
海外のblogで初音ミクについて熱い(長い)文章を書き込んでいるのを見かけたので試しに翻訳してみた。無断翻訳なので匿名で。urlは以下の通り。
http://deliciouscakeproject.wordpress.com/2010/09/20/hatsune-miku-and-the-magic-of-make-believe/
=====以下翻訳=====
そこにはバルトロメオ・クリストフォリって名前のすげえヤツがいた。こいつの得意技は楽器を作ることだった。何でも作ったわけじゃない。当時はひどく弱々しいちっこいもので、しょぼい羽柄が並んだ弦を引っかいて金属的なチャリチャリした音を出すもの、つまり鍵盤楽器を作っていた。いわゆる「バロック・ミュージック」ってヤツだ。クリストフォリが音楽技師として、また機械技師としてやったのは、弦を異なる強さで叩くハンマーを使った仕組みづくりで、それによって演奏家は小さい音(ピアノ)や大きな音(フォルテ)で演奏できるようになった。だもんで皆それをイタリア語でピアノフォルテと呼んだ。もちろん、今ではお前も俺もそして誰もがクリストフォリの発明品をピアノと呼んでいる。
イタリアはピアノを発明することによって、日本が初音ミクを発明するための扉を開いた。
***
俺は今、ここサン・フランシスコの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世紀の違いだ。
何であれ多くの人々が音楽を作ることは、単に大人しく聞いているだけよりもいいことだと俺は信じる。俺は魔法を、ボーカロイドを、ミクを信じている。
=====以上翻訳終了=====
誤訳は当然あると思う。でも面倒なので修正はしない。
ウェブサイトの横幅は何ピクセルが良いか、というのは今まで幾度となく話題になっている。今まではディスプレイとその解像度の増加に合わせて、最適なウェブサイトの幅というのは拡大を続けてきた。
最近では
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ピクセルくらいが落とし所なんじゃないかと。
こんないい加減な予測が当たると面白いな。
しだれ柳を幽霊と勘違いする人がいるように、人間じゃないものを人間と勘違いさせることはポイントさえ抑えれば結構簡単なんですよ。この前だって仲良くしていたtwitter友達がbotだった(以下略)
ともかく。人物の記号化に関することなら、らきすたに限らずとももっともっと旧い段階の漫画のほうが余程顕著だぜ。
例えばらきすたの直系のご先祖様である「少年アシベ」なんてデフォルメの塊で、冷静に見たらアシベ少年は人間ではなくナスそのものだ。
問題は、そんなところじゃないだろ? おまいさんが人間を人間と認識するプロセスは、常識的な3Dの人間との近似率からはじき出されるものか? 違うね。
人間が認識するオブジェクトってのは、瞳に映像されたピクセルじゃないんだよ。もっとこう、コンテクストから導き出される推論エンジンで補完された、ユークリッド空間に拠らないイメージなんだよ。言語化できないけど。
そんな当たり前のこともわからないわけ?
http://anond.hatelabo.jp/20090308152436
さっきamazonのDVDランキングを見たが、本当に唖然とした。
俺は断言するが、あのハリウッドのCGの映像を見て感動してDVDを買う奴は馬鹿だ。これは100%断言できる。
何であれがいいと思うの? なんであれのDVD買うの? 本当に分からない。あれCGじゃん。レンダリングされたピクセルだよ? 誰だってあれ見てCGだって言うのは一瞬で分かる。それで感動するって本気で馬鹿なんじゃない?
あれがいいっていうのは、頭がおかしいとしか言いようがない、というか、脳が退化してるんだよ。それしか説明がつかない。つまり、現実の演技とバーチャルが区別つかなくなってるんだよ。だからいいと思って買う。これは馬鹿としか言い様がないだろう。日本の将来は大丈夫か?
前にもちょっとマトリックスのDVDが出た時、ニコニコ動画(こんなもの見たくなかったが)で見たが、なんであんな人気あるんだろう。あとついでにそのマトリックスのCGシーンを仮装大賞で人間がパロッて卓球してるのも見た。これならまあ100歩譲って納得できなくもないが、ただ当然プロのスタントとは比べるのも失礼な程だし、無料ならまあ一回見てもいいかな、という程度だ。何回も見るほどではない。ただコメントは絶賛の嵐。アホか。本物を知らないニートばっかなのかあそこは。ろくなもんじゃないな。
俺ははっきり言うが、もっと人間が本気で演技してるDVDを買うべきなんだよ。じゃないとおかしい。プロの役者が毎日どれだけ苦労してるか知ってるか? ボイトレ、筋トレ、喉や体調の管理、食事管理、書けばきりがない。大好きな酒、タバコも我慢して頑張ってる人もたくさんいるし、サラリーマンみたく安定した職じゃないから毎日不安と戦ってる。そういう方が心を込めて出演してるDVDを買わずに、ピ○サーのCG映画を買う。ほんと死にたくなるね。どうしてあの機械の演技を買うかね。わからない。世の中不思議だらけだ。
モーリー: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
YourFileHostのCAPTCHA画像をなんとかするの続き。
その後、適当にいじったら、手元環境で1枚あたり25秒くらい→だいたい2.5秒くらいで判別できるようになった。このくらいなら使えるかな。
速度向上に一番効いたのは、Token#importで画像を比較しているところの修正。他は細かい手直し。
使い方は前のやつと変わってません。
あと、テストに100枚くらいCAPTCHA画像食わせてみたけど、とりあえず全部正しく判定できた。
カレントディレクトリ以下にある*.gifなCAPTCHA画像ファイルを適当に判別するスクリプト。動作確認用にどうぞ。
後述の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
#!/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__
本気でがんばるとぎりぎり倒せるように絶妙のバランス調節がされた敵(困難)。
単純作業じゃ効率が悪いけど、工夫次第でどんどん効率を上げられる経験値システム(スキル)。
リセット不可の緊張感。でもシレンとかよりずっと死ににくいからあんま気にする必要なし。
全てのキャラが深い人間性と歴史を持って登場する、圧倒的リアリティ。
グラフィックが綺麗すぎ。多分、無限×無限ピクセルで、毎秒無限フレームで動いてる。
BGMの種類がほぼ無限。選曲も自由。自分で作った曲を流すこともできる。
人間が作ったとは思えない、とんでもなく複雑で洗練されたシナリオ。
リアル出産システム採用。自分と、自分よりも大切に思える相手の遺伝子を半分ずつ受け継いだ、
奇跡のようなキャラを生み出して、そいつに自由に色々教えて育てることができる。
すごく嬉しいし、ちょー楽しい。
ネコっつー生き物が登場するんだけど、これがちょーかわいい。
食いきれねーほどの種類の料理があって、超うまいものが時々食える。
説明書が無く、仕様が明かされてないから、自分でデータとって仕様を推測するしかない。
これがまたとんでもなく高度に洗練された仕様になってるっぽくて、なかなか正確には分からん。
だから、とりあえず大雑把に推定し、それに基づいて行動して、
これがまた楽しい。徐々に明らかになっていく世界観。未だに明らかになってない謎が山盛り。
友達と一緒に協力して遊べる。無料。本気で自分を愛してくれるキャラがいたりする。
ゲーム内で別なゲームやったりアニメ見たり出来る。登場キャラと本当に心を通わせることが出来る。
こんなとてつもない神ゲーを糞ゲーとか言ってる奴は、本気でこのゲームをやったことがない奴だけ。
まあ、一切がんばらずにクリアできるようなヌルゲーばかりやってる奴には、
そんなわけで、みんな大好きなYourFileHostだけども、最近みてみたら、なんかCAPTCHA認証がついているわけじゃないですか。
でもこれってさーCAPTCHAといっても見るからに危ういというか、見れば見るほど簡単に破れてしまいそうな気がして、どうにもむずがゆいアンニュイな気分になってしまうわけです。
そんで、このたび適当にいじってみたところ、それなりに推測できるコードが書けたので、ここに張ってみますね。
やってることは単純で、こんな感じ
使い方は、こんな感じで
require 'decaptcha.rb' captcha_string = DeCAPTCHA.decode(filename) if !captcha_string.nil? then # 判別成功時の処理 else # 判別失敗時の処理。失敗することもあるのでよしなに。 end
あ、Ruby/GD2入れといてね。sudo gem install gd2とかで入ります。多分。
判別率はそこそこ良い感じになったんだけども、富豪プログラミングがたたってか、いかんせん遅いです。
手元だと1枚判別するのに20秒くらいかかることもある。
そんなわけで誰かチューニングしてくれるとうれしい。
実行速度を上げた改良版はこっちにうpしました。以下のコードは参考程度に。
#!/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__
http://anond.hatelabo.jp/20080920224443
フルハイビジョンパネルの大きな液晶テレビでも、横1300ピクセル程度の26インチ液晶テレビでも、同じようにエッジにノイズが見えるんです。
それ多分MPEG特有のブロックノイズだよ。放送局がビットレートをケチるからそういう発生しているだけだと思う。DVD並みのビットレートで解像度が実質縦横1.5倍になってるから、放送局や番組の内容によっては相当なノイズが走る事もある。量販店ではデモンストレーション代わりにNHKの海外ドキュメンタリーとか流してる所多いが、小川の流水やヘリコプターから撮影した森林のシーンになると、ブロックノイズ出まくりで目も当てられない事もしばしば。
純粋にパネルの性能を見たいのならBDを再生している台を探してみるといい。DVDは小さい解像度を引き延ばしているので余り参考にはならないかも知れない。たとえば俺の近所の某YMD電機は、同じテレビを二台並べて、同じ映像作品で一方をDVD版、もう一方をBD版にして同時に再生し、画質を比べさせるというデモをやってる。
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よりも綺麗(なはず)。
http://anond.hatelabo.jp/20080416212318
なんの作品かは知らないけど、それはアポロ陰謀論者のパロディなんじゃないの?
その発話者が電波くんであるか、もしくは、その架空世界は本当にそういう設定で、その設定自体がアポロ陰謀論者を揶揄しているのかもしれない。
もしそうだとしたら、フライングスパゲッティモンスター教に非科学的だとマジギレしてるようなもんで、アホ丸出しだぞ。
http://anond.hatelabo.jp/20080416231512
これなんかは、モニタ上でRGBの画素で画像が構成されることを指して言ってるんじゃないの。つまり、それがゲーム世界の「リアリティ」、所詮モニタの中の作り事、全部ピクセルで出来てんだよ、ということを示したジョーク。
リアル成長システム採用。自分と、自分よりも大切に思える相手の遺伝子を半分ずつ受け継いだ、奇跡のようなキャラに自由に色々教えて育てることができる。
すごく嬉しいし、ちょー楽しい。
本気でがんばるとぎりぎりクリアできるように絶妙のバランス調節がされたイベント。単純作業じゃ効率が悪いけど、工夫次第でどんどん効率を上げられる経験値システム。
リセット不可の緊張感。でもシレンとかよりずっと死ににくいからあんま気にする必要なし。つーか普通のゲームでもリセットなんて邪道じゃん。
全てのキャラが深い人間性と歴史を持って登場する、圧倒的リアリティ。
グラフィックが綺麗すぎ。多分、無限×無限ピクセルで、毎秒無限フレームで動いてる。色も多分無限色使える。「保育園でパパ描いたのー、見てー」とかマジありえねー美しさ。
BGMの種類がほぼ無限。選曲も自由。自分で作った曲を流すこともできる。人間が作ったとは思えない、とんでもなく複雑で洗練されたシナリオ。
ネコっつー生き物が登場するんだけど、これがちょーかわいい。
食いきれねーほどの種類の料理があって、超うまいものを食わせてやれる。自分で作ってもいい。
説明書が無く、仕様が明かされてないから、自分でデータとって仕様を推測するしかない。これがまたとんでもなく高度に洗練された仕様になってるっぽくて、なかなか正確には分からん。
だから、とりあえず大雑把に推定し、それに基づいて行動して、データを取りつつ徐々に予測値を修正していく必要がある。
未だに明らかになってない謎が山盛り。
友達と一緒に協力して遊べる。
無料。
本気で自分を愛してくれるキャラがいたりする。
登場キャラと本当に心を 通わせることが出来る。
信じがたいほど深い感動を味わえるイベントが結構ある。もちろん本気でやらないとフラグを無駄にするだけだが。
こんなとてつもない神ゲーを糞ゲーとか言ってる奴は、本気でこのゲームをやったことがない奴だけ。
まあ、一切がんばらずにクリアできるようなヌルゲーばかりやってる奴には、このゲームはちょいとハードかもしれんがな。でも一端ハマった奴はみんな、このゲームを辞めたくないって言ってるぜ
俺しがないWEB屋なんだけど、とあるWEBアプリケーションを頼まれで作ったときの話。
何でもやるIT土方なので、本当はデザインからシステムまで全部こっちで引き受けたいところなんだけど、発注側(代理店)が最初から勝手に「このイメージでいく」とクライアントに提出してて引っ込みつかなかったらしく、デザインに関しては別のWEB制作業者を入れ込んできた。
CMYKなのは許すとして、単位が全てmm。しかも整数になってないので手で適当に置いたのがバレバレ。
もしかしてpxに変換すると整数になるのかもしれないと期待してみたが、案の定、もっと酷い状況に。
大きさも配置も小数が混じるので、画面に書き起こしたときに同じ要素でも幅も高さも位置も2-3px程度ばらける破目に。
何べん言っても改善してくれない。
ピクセルとかアンチエイリアスとかすら理解してくれないので「じゃあ書き出すときアンチエイリアスを切ればいいじゃないですか」とか言われるし。れっきとした株式会社が自社のサイトの事業にWEBデザインもやりますとか書いてあるのに。
わかってもらえないようなので、言いがかりと捕らえられない様、丁寧に説明してるんだがそれでも聞く耳を持たない。
最終的には「あなたの言ってることがわからない。そんなに気になるんであればそちらで対応すれば」という一方的な態度に出られた。
仕方なく、もらった「素材」をもとに、全てこちらで作り直した。
それでも先方はしっかり「WEBデザイン」として予算の全額を持っていきやがった。
もちろん、代理店に説明しても理解されなかった。
最初にしっかり納品物の用件定義をしなかった俺を含めて、
WEB屋の底辺ってこんなもの。
ノートPCでデュアルディスプレイをするのってのはいろいろ制約があるんだな。
今は中古で1万で買ったXGA(1024x768)のモニタをセカンドモニタとして使っていたけど、解像度が高い&ワイドのが欲しいと思い物色。
ゼミの研究室にあるSXGA(1280x1024)のモニタでデュアルディスプレイが行けたからそれよりはピクセル数が少ないWXGA+(1440x900)のモニタがいけると思ったがサポートしているとは書いてない・・・
webサイトには”アナログVGAでの出力”は1600×1200、1360×768、1280×1024、1280×768、1024×768、800×600としか書かれておらず。
しかもこれにはノートPC内蔵のXGA液晶とあわせての表示とは書かれていないし・・・・。
何ではっきり書いてくれないのかなぁ。