Twitter 画像エンコーディングチャレンジ [終了] 質問する

Twitter 画像エンコーディングチャレンジ [終了] 質問する

写真が 1000 語に相当するとしたら、140 文字にどれだけの写真を収めることができるでしょうか?

: 皆さん、これで終わりです! 懸賞の締め切りが迫っており、厳しい検討の末、私はブージャムのエントリーかろうじて勝ち抜いたサム・ホセバーの書き終えたら、より詳しいメモを投稿します。もちろん、皆さんは引き続き自由にソリューションを提出し、投票できるようにソリューションを改善してください。エントリーを提出してくださった皆さんに感謝します。私はすべてのエントリーを楽しみました。このコンテストは私にとってとても楽しいものでした。エントリー者と観客の両方にとって楽しいものであったことを願っています。

私は遭遇しましたこの興味深い投稿Twitterのコメントに画像を圧縮しようとした件について、そのスレッドの多くの人々(そしてRedditのスレッド) には、さまざまな方法についての提案がありました。そこで、これは良いコーディング チャレンジになると思います。つまり、口先だけでなく実際に行動に移してもらい、限られたスペースでエンコーディングに関するアイデアがどのようにより詳細な情報につながるかを示すのです。

画像を 140 文字の Twitter メッセージにエンコードし、それを再び画像にデコードする汎用システムを考案してみませんか。Unicode 文字を使用すれば、1 文字あたり 8 ビット以上になります。ただし、Unicode 文字を考慮しても、画像を非常に小さなスペースに圧縮する必要があります。これは間違いなく非可逆圧縮であるため、結果の見栄えの良さについては主観的な判断が必要になります。

原著者が出した結論は次の通り。カジモンド、彼のエンコーディングから取得(画像はライセンスの下でクリエイティブ・コモンズ 表示-非営利ライセンス):モナリザ

もっと上手くできますか?

ルール

  1. プログラムには、エンコードデコードの2 つのモードが必要です。
  2. エンコードする場合:
    1. プログラムは、任意の適切なラスターグラフィック形式のグラフィックを入力として受け取る必要があります。イメージマジック合理的であるとみなされます。
    2. プログラムは、140以下のUnicodeコードポイントで表現できるメッセージを出力する必要があります。140のコードポイントは、非文字(、、nn ( nは16進数の-で範囲は- )とサロゲートコードポイント(- )を除き、範囲U+0000-です。出力は、任意の適切なエンコーディングで行うことができます。U+10FFFFU+FFFEU+FFFFU+FFFEU+FFFF110U+FDD0U+FDEFU+D800U+DFFFGNUiconv妥当であると考えられ、プラットフォームのネイティブ エンコーディングまたはロケール エンコーディングが適切な選択となる可能性があります。詳細については、以下のUnicode に関する注記を参照してください。
  3. デコード時:
    1. プログラムは、エンコードモードの出力を入力として受け取る必要があります。
    2. プログラムは、上で定義したように、任意の適切な形式でイメージを出力する必要がありますが、出力にはベクター形式も使用できます。
    3. 画像出力は入力画像に近いものになるはずです。入力画像に近づけるほど、より良い結果が得られます。
    4. デコード プロセスは、上記で指定した出力以外のエンコード プロセスの他の出力にはアクセスできない可能性があります。つまり、画像をどこかにアップロードして、デコード プロセスがダウンロードするための URL を出力するなど、そのようなばかげたことはできません。
  4. ユーザー インターフェイスの一貫性を保つために、プログラムは次のように動作する必要があります。

    1. プログラムは、適切なインタープリタを備えたプラットフォーム上で実行可能に設定できるスクリプト、または実行可能ファイルにコンパイルできるプログラムである必要があります。
    2. モードを設定するには、プログラムの最初の引数として またはencodeのいずれかを取る必要があります。decode
    3. プログラムは、以下の 1 つ以上の方法で入力を受け取る必要があります (ファイル名を受け取る方法を実装する場合、ファイル名が欠落している場合は、stdin と stdout から読み書きすることもできます)。

      1. 標準入力から入力を受け取り、標準出力に出力を生成します。

        my-program encode <input.png >output.txt
        my-program decode <output.txt >output.png
        
      2. 2 番目の引数で指定されたファイルから入力を受け取り、3 番目の引数で指定されたファイルに出力を生成します。

        my-program encode input.png output.txt
        my-program decode output.txt output.png
        
  5. 解決策については、以下を投稿してください:
    1. コード全体、および/または他の場所でホストされているコードへのリンク (コードが非常に長い場合や、コンパイルに多くのファイルが必要な場合など)。
    2. コードからすぐには動作がわからない場合や、コードが長くて概要に興味があると思われる場合は、動作の仕組みを説明します。
    3. 元の画像、圧縮後のテキスト、デコードされた画像を含むサンプル画像。
    4. 他の人のアイデアを基に構築する場合は、そのアイデアの出典を明記してください。他の人のアイデアを改良することは問題ありませんが、出典を明記する必要があります

ガイドライン

これらは基本的に、破られる可能性のあるルール、提案、または採点基準です。

  1. 美学は重要です。私は以下の基準に基づいて審査し、他の人にも審査するよう提案します。
    1. 出力画像の見栄えの良さ、そしてオリジナル画像とどれだけ似ているか。
    2. テキストの見栄えがいいですね。圧縮方式が本当に巧妙であれば、完全にランダムな意味不明な言葉でも問題ありませんが、画像を多言語の詩に変えるなど、何か巧妙な答えも見たいです。元の解答の作成者は、見た目がよいという理由で、中国語の文字だけを使うことにしたことに注意してください。
    3. 興味深いコードと巧妙なアルゴリズムは常に良いものです。私は短くて要点が明確でわかりやすいコードが好きですが、良い結果を生み出す限り、本当に巧妙で複雑なアルゴリズムでも問題ありません。
  2. 速度も重要ですが、画像をどれだけうまく圧縮できるかほど重要ではありません。遺伝的アルゴリズムを何日も続けて実行するプログラムよりも、10分の1秒で画像を変換できるプログラムのほうが良いと思います。
  3. 品質が同等であれば、長い解決策よりも短い解決策を好みます。簡潔さは美徳です。
  4. あなたのプログラムは、Mac OS X、Linux、またはWindowsで自由に利用できる実装がある言語で実装されている必要があります。プログラムを実行できるようにしたいのですが、マテリアライズドまたは何か、それは結構です。
  5. プログラムはできる限り汎用的である必要があります。できるだけ多くの異なる画像で動作する必要がありますが、一部の画像では他の画像よりも良い結果が得られる場合があります。具体的には、次のようになります。
    1. プログラムにいくつかの画像を組み込み、それを一致させて参照を書き込み、デコード時に一致する画像を生成するというのは、かなり不十分で、数個の画像しかカバーしません。
    2. 単純で平坦な幾何学的形状の画像を取得して、それを何らかのベクトル プリミティブに分解できるプログラムは非常に便利ですが、一定の複雑さを超える画像で失敗する場合は、汎用性が不十分である可能性があります。
    3. 特定の固定アスペクト比の画像しか撮影できないが、その画像を適切に処理できるプログラムも問題ありませんが、理想的ではありません。
    4. 白黒画像の方が、カラー画像よりも小さなスペースに多くの情報を盛り込めることがわかるかもしれません。その一方で、白黒画像が適用できる画像の種類が制限される可能性があります。顔は白黒でもきれいに表示されますが、抽象的なデザインはうまく表示されない可能性があります。
    5. 出力画像が入力画像より小さくても、ほぼ同じ比率であれば問題ありません。元の画像と比較するために画像を拡大する必要がある場合でも問題ありません。重要なのは、どのように見えるかです。
  6. プログラムは、実際に Twitter を通過しても問題なく出力される出力を生成する必要があります。サポートされている文字の正確なセットに関するドキュメントが見つからなかったため、これはルールではなくガイドラインにすぎませんが、制御文字、奇妙な非表示の結合文字、私用文字などは避けたほうがよいでしょう。

採点基準

承認されたソリューションを選択する際にソリューションをランク付けする方法の一般的なガイドとして、ソリューションを 25 点満点で評価するとします (これは非常に大まかなもので、直接スコアを付けるのではなく、これを基本的なガイドラインとして使用するだけです)。

  • エンコード方式が幅広い入力画像をどれだけうまく再現できるかについて 15点。これは主観的な美的判断です。
    • 0は、まったく機能しない、毎回同じ画像が返される、などを意味します。
    • 5は、いくつかの画像をエンコードできることを意味しますが、デコードされたバージョンは見栄えが悪く、より複雑な画像ではまったく機能しない可能性があります。
    • 10は、幅広い画像に適応し、時には区別がつかないような見栄えの良い画像を生成することを意味します。
    • 15 は、一部の画像の完全な複製を作成し、より大きく複雑な画像であっても認識できるものを生成することを意味します。または、完全に認識できる画像は作成しないかもしれませんが、明らかにオリジナルから派生した美しい画像を生成します。
  • Unicode 文字セットの巧みな使用に対して 3 ポイント
    • 許可された文字セット全体を使用した場合は0ポイント
    • Twitter 経由やさまざまな状況で安全に転送できる限定された文字セットを使用すると 1 ポイント
    • 漢字のみ、または右から左に書く文字のみなど、テーマに沿った文字のサブセットを使用する場合は 2 ポイント
    • 読みやすいテキストを生成したり、問題の画像に似た文字を使用したりといった、本当に素晴らしいことをした場合は 3 ポイント
  • 巧妙なアルゴリズムアプローチとコードスタイルに 3ポイント
    • 画像を縮小し、1ピクセルあたり1ビットとして扱い、それをbase64でエンコードするだけの1000行のコードには0点です。
    • 標準的なエンコード技術を使用し、簡潔かつ簡潔に書かれたものには1ポイント
    • 比較的新しいエンコード技術を紹介しているもの、または驚くほど短くてきれいなものに2ポイント
    • 実際に良い結果を生み出すワンライナー、またはグラフィックス エンコーディングの新境地を拓くものには 3 ポイント (新境地を拓くものとしてはポイント数が少ないと思われるかもしれませんが、これほど良い結果は見た目の点数も高くなる可能性が高いことを覚えておいてください)
  • スピードは2点。他の条件が同じであれば、速い方が良いですが、上記の基準はすべてスピードよりも重要です。
  • フリー(オープンソース)ソフトウェアで実行する場合は1 ポイント。フリーソフトウェアを好むためです(C# は Mono で実行されている限りこのポイントの対象となります。同様に MATLAB コードは GNU Octave で実行されている場合は対象となります)。
  • 実際にすべてのルールに従っている場合は1 ポイント。これらのルールはやや大きく複雑になっているため、細かい点が 1 つ間違っているものの、それ以外は良い回答であれば受け入れますが、実際にすべてのルールに従っているソリューションには追加ポイントを付与します。

参考画像

参考画像を求める方もいらっしゃいます。以下に参考画像をいくつか示します。小さいバージョンがここに埋め込まれており、必要な場合は画像の大きいバージョンにリンクされています。

レナ モナリザ コーネルボックス StackOverflow ロゴ

上記の基準に基づいて、私が最も気に入ったソリューションに対して、 500 の Rep 報奨金(および StackOverflow から付与される 50)を提供します。もちろん、他の皆さんにも、ここでお気に入りのソリューションに投票していただくようお願いします。

締め切りに関する注意事項

このコンテストは、賞金がなくなる 5 月 30 日土曜日の午後 6 時頃まで開催されます。終了時間を正確にお伝えすることはできませんが、午後 5 時から 7 時の間になるかもしれません。午後 2 時までに提出されたすべてのエントリーを確認することを保証し、午後 4 時までに提出されたすべてのエントリーを確認するよう最善を尽くします。それ以降にソリューションが提出された場合、決定を下す前に公平に確認する機会がない可能性があります。また、提出が早ければ早いほど、投票して最適なソリューションを選ぶ機会が増えるため、締め切り間際ではなく、早めに提出するようにしてください。

ユニコードノート

また、どの Unicode 文字が許可されているかについても混乱が生じています。Unicode コード ポイントの可能な範囲は から です。U+0000オープンU+10FFFFなデータ交換で Unicode 文字として使用できないコード ポイントがいくつかあります。これらは非文字サロゲート コード ポイントです。非文字は で定義されています。Unidode 標準 5.1.0 セクション 16.7U+FFFE、、nn (U+FFFF n16進数、範囲は)の値として表されます。これらの値はアプリケーション固有の内部使用のために意図されており、準拠するアプリケーションは、処理するテキストからこれらの文字を削除できます。U+FFFEU+FFFF110U+FDD0U+FDEFUnicode 標準 5.1.0 セクション 3.8U+D800–などのU+DFFF文字は、UTF-16 の基本多言語面を超える文字をエンコードするために使用されます。したがって、これらのコード ポイントを UTF-16 エンコードで直接表現することは不可能であり、他のエンコードでエンコードすることは無効です。したがって、このコンテストでは、上記で定義したすべての非文字とサロゲート ペアを除いた、 U+0000–の範囲の 140 個以下の Unicode コード ポイントのシーケンスに画像をエンコードするプログラムをU+10FFFF許可します。

私は割り当てられた文字だけを使用するソリューションを好みますが、割り当てられた文字の巧妙なサブセットを使用したり、使用する文字セットで何か面白いことをしたりするソリューションの方がさらに良いでしょう。割り当てられた文字のリストについては、Unicode 文字データベース; 一部の文字は直接リストされているが、一部は範囲の開始と終了としてのみリストされていることに注意してください。また、サロゲートコードポイントはデータベースにリストされていますが、前述のように禁止されています。出力するテキストをより面白くするために文字の特定のプロパティを利用したい場合、文字情報のさまざまなデータベース利用可能なもの、例えば名前付きコードブロックのリストそしてさまざまな文字プロパティ

Twitterはサポートする文字セットを正確に指定していないため、特定の文字が余分にカウントされたり、特定の文字が削除されたりしてTwitterで実際に機能しないソリューションについては寛容になります。エンコードされたすべての出力がTwitterまたは他のマイクロブログサービス(例:identi.caTwitter は <、>、& をエンティティエンコードし、それぞれ 4、4、5 文字としてカウントするというドキュメントを見たことがありますが、自分でテストしたわけではなく、JavaScript 文字カウンターではそのようにカウントされないようです。

ヒントとリンク

  • ルール内の有効な Unicode 文字の定義は少し複雑です。CJK 統合表意文字 (U+4E00–U+9FCF) などの単一の文字ブロックを選択する方が簡単な場合があります。
  • 既存の画像ライブラリを使用することもできます。イメージマジックまたはPython イメージング ライブラリ画像の操作には、 を使用します。
  • Unicode文字セットとそのさまざまなエンコードを理解するために助けが必要な場合は、このクイックガイドまたはLinuxとUnixにおけるUTF-8に関する詳細なFAQ
  • 解決策を早く提出すればするほど、私 (および他の投票者) がそれを検討する時間が増えます。解決策を改善したい場合は編集できます。私は解決策を最後に確認した時点で、最新バージョンに基づいて報奨金を決定します。
  • 簡単に解析して書き込める画像フォーマットが欲しい場合(既存のフォーマットを使いたくない場合)、PPM形式テキストベースのフォーマットなので扱いやすく、イメージマジックそれを変換したり、そこから変換したりします。

ベストアンサー1

画像ファイルとPythonソース(バージョン1と2)

バージョン 1これは私の最初の試みです。 進捗に応じて更新します。

私は SO ロゴをほぼロスレスで 300 文字に短縮しました。私のテクニックは SVG ベクター アートへの変換を使用するため、ライン アートに最適です。これは実際には SVG 圧縮器ですが、元のアートをベクター化段階に通す必要があります。

最初の試みでは、オンラインサービスPNGトレースについては、この部分を処理できる無料および有料のツールが多数あります。ポトレース(オープンソース)。

結果は次のとおりです

オリジナル SO ロゴ http://www.warriorhut.org/graphics/svg_to_unicode/so-logo.pngオリジナルデコードされた SO ロゴ http://www.warriorhut.org/graphics/svg_to_unicode/so-logo-decoded.pngエンコードとデコード後

文字数: 300

時間: 測定されていませんが、実質的には瞬時です (ベクトル化/ラスタライズのステップは含みません)

次の段階では、Unicode 文字ごとに 4 つのシンボル (SVG パス ポイントとコマンド) を埋め込みます。現時点では、私の Python ビルドには UCS4 のワイド文字サポートがないため、文字ごとの解像度が制限されます。また、最大範囲を Unicode 予約範囲の下限 0xD800 に制限しましたが、許可された文字のリストとそれらを回避するフィルターを作成すれば、理論的には上記のロゴに必要な文字数を 70 ~ 100 まで減らすことができます。

現時点でこの方法の制限は、出力サイズが固定されていないことです。出力サイズは、ベクター化後のベクター ノード/ポイントの数に依存します。この制限を自動化するには、画像をピクセル化するか (ベクターの主な利点が失われます)、または、必要なノード数に達するまでパスを単純化ステージで繰り返し実行する必要があります (現在、Inkscape で手動で実行しています)。

バージョン2

更新: v2 が競技に参加できるようになりました。変更点:

  • コマンドライン制御の入出力とデバッグ
  • 正規表現の代わりにXMLパーサー(lxml)を使用してSVGを処理します
  • ユニコードシンボルごとに2つのパスセグメントをパックします
  • ドキュメントとクリーンアップ
  • style="fill:color" および fill="color" をサポートします
  • 文書の幅と高さを1文字にまとめる
  • パスの色を1文字にまとめる
  • 色圧縮は、色ごとに 4 ビットの色データを破棄し、それを 16 進変換によって文字にパックすることによって実現されます。

文字数: 133

時間:数秒

v2 デコード済み http://www.warriorhut.org/graphics/svg_to_unicode/so-logo-decoded-v2.pngエンコードとデコード後(バージョン2)

ご覧のとおり、今回はアーティファクトがいくつか発生しています。これは方法の制限ではなく、変換のどこかでミスが発生したためです。アーティファクトは、ポイントが 0.0 - 127.0 の範囲外になると発生し、ポイントを制限しようと試みましたが、成功と失敗が混在していました。解決策は、単に画像を縮小することですが、アートボードやグループ マトリックスではなく実際のポイントを拡大縮小するのが難しく、今では気にするほど疲れています。つまり、ポイントがサポートされている範囲内であれば、通常は機能します。

中央の折れ曲がりは、ハンドルがリンクされているハンドルの反対側に移動したことが原因だと思います。基本的に、ポイントがそもそも近すぎます。圧縮する前にソース イメージに簡素化フィルターを実行すると、この問題は修正され、不要な文字がいくつか削除されます。

更新:この方法は単純なオブジェクトには適しているので、複雑なパスを単純化してノイズを減らす方法が必要でした。インクスケープこのタスクでは、Inkscape を使用して不要なパスを整理することに成功しましたが、自動化を試す時間はありませんでした。パスの数を減らすために、Inkscape の「単純化」機能を使用してサンプル SVG をいくつか作成しました。

簡略化は問題なく動作しますが、パスが多数あると遅くなる可能性があります。

オートトレースの例 http://www.warriorhut.org/graphics/svg_to_unicode/autotrace_16_color_manual_reduction.png コーネル ボックス http://www.warriorhut.com/graphics/svg_to_unicode/cornell_box_simplified.png レナ http://www.warriorhut.com/graphics/svg_to_unicode/lena_std_washed_autotrace.png

サムネイルをトレース http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_autotrace.png

超低解像度のショットをいくつか紹介します。これらは 140 文字の制限に近くなりますが、巧妙なパス圧縮も必要になるかもしれません。

手入れされた http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_groomed.png簡素化され、斑点が除去されました。

三角形 http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_triangulated.png簡素化され、斑点が除去され、三角形に分割されました。

autotrace --output-format svg --output-file cornell_box.svg --despeckle-level 20 --color-count 64 cornell_box.png

上: 単純化されたパスオートトレース

残念ながら、私のパーサーは autotrace 出力を処理できないため、使用されているポイントの数や、どの程度簡略化すればよいかがわかりません。残念ながら、締め切りまでにそれを書く時間はほとんどありません。ただし、inkscape 出力よりは解析がはるかに簡単です。

おすすめ記事