Tantangan penyandian gambar Twitter [tertutup]

597

Jika gambar bernilai 1000 kata, berapa banyak gambar yang bisa Anda masukkan dalam 140 karakter?

Catatan : Itu orang-orang! Tenggat waktu hadiah ada di sini, dan setelah beberapa pertimbangan yang sulit, saya telah memutuskan bahwa entri Boojum nyaris tidak ada di tangan Sam Hocevar . Saya akan memposting catatan yang lebih detail begitu saya punya kesempatan untuk menuliskannya. Tentu saja, setiap orang harus merasa bebas untuk terus mengirimkan solusi dan meningkatkan solusi bagi orang untuk memilih. Terima kasih kepada semua orang yang mengirim dan mengirimkan; Saya menikmati semuanya. Ini sangat menyenangkan bagi saya untuk berlari, dan saya harap ini menyenangkan bagi para pendatang dan penonton.

Saya menemukan posting yang menarik ini tentang mencoba mengompres gambar menjadi komentar Twitter, dan banyak orang di utas itu (dan a utas di Reddit ) memiliki saran tentang berbagai cara yang dapat Anda lakukan untuk melakukannya. Jadi, saya pikir itu akan menjadi tantangan pengkodean yang bagus; biarkan orang menaruh uang mereka di mana mulut mereka berada, dan tunjukkan bagaimana ide-ide mereka tentang penyandian dapat mengarah ke lebih detail dalam ruang terbatas yang Anda miliki.

Saya menantang Anda untuk membuat sistem tujuan umum untuk meng-encode gambar ke dalam 140 karakter pesan Twitter, dan mendekodekannya menjadi gambar lagi. Anda dapat menggunakan karakter Unicode, sehingga Anda mendapatkan lebih dari 8 bit per karakter. Meskipun memungkinkan untuk karakter Unicode, Anda harus memampatkan gambar ke dalam ruang yang sangat kecil; ini tentu akan menjadi kompresi yang hilang, dan karenanya harus ada penilaian subyektif tentang seberapa baik setiap hasil terlihat.

Berikut adalah hasil yang penulis asli, Quasimondo , dapatkan dari penyandiannya (gambar dilisensikan dengan lisensi Creative Commons Attribution-Noncommercial ): Mona lisa

Bisakah kamu berbuat lebih baik?

Aturan

  1. Program Anda harus memiliki dua mode: encoding dan decoding .
  2. Saat menyandikan :
    1. Program Anda harus memasukkan grafik dalam format grafik raster yang masuk akal sesuai pilihan Anda. Kami akan mengatakan bahwa format raster apa pun yang didukung oleh ImageMagick dianggap masuk akal.
    2. Program Anda harus menampilkan pesan yang dapat direpresentasikan dalam 140 atau kurang poin kode Unicode; 140 kode poin di kisaran U+0000- U+10FFFF, tidak termasuk non-karakter ( U+FFFE, U+FFFF, U+nFFFE , U+nFFFF di mana n adalah 1- 10heksadesimal, dan kisaran U+FDD0- U+FDEF) dan titik kode pengganti ( U+D800- U+DFFF). Ini bisa berupa output dalam penyandian yang masuk akal pilihan Anda; setiap penyandian yang didukung oleh GNUiconv akan dianggap masuk akal, dan penyandian asli platform atau penyandian lokal Anda mungkin akan menjadi pilihan yang baik. Lihat catatan Unicode di bawah ini untuk lebih jelasnya.
  3. Saat mendekode :
    1. Program Anda harus mengambil input dari mode encoding Anda .
    2. Program Anda harus menampilkan gambar dalam format yang masuk akal pilihan Anda, seperti yang didefinisikan di atas, meskipun untuk format vektor keluaran juga OK.
    3. Output gambar harus merupakan perkiraan gambar input; semakin dekat Anda dengan gambar input, semakin baik.
    4. Proses decoding mungkin tidak memiliki akses ke output lain dari proses encoding selain output yang ditentukan di atas; artinya, Anda tidak dapat mengunggah gambar di suatu tempat dan mengeluarkan URL untuk proses penguraian kode unduhan, atau hal konyol lainnya.
  4. Demi konsistensi dalam antarmuka pengguna, program Anda harus berperilaku sebagai berikut:

    1. Program Anda harus berupa skrip yang dapat diatur agar dapat dieksekusi pada platform dengan interpreter yang sesuai, atau program yang dapat dikompilasi menjadi executable.
    2. Program Anda harus mengambil sebagai argumen pertama encodeatau decodeuntuk mengatur mode.
    3. Program Anda harus mengambil input dalam satu atau lebih cara berikut (jika Anda menerapkan yang mengambil nama file, Anda juga dapat membaca dan menulis dari stdin dan stdout jika nama file hilang):

      1. Ambil input dari standar masuk dan hasilkan standar keluar.

        my-program encode <input.png >output.txt
        my-program decode <output.txt >output.png
        
      2. Ambil input dari file yang disebutkan di argumen kedua, dan hasilkan output di file yang disebutkan di argumen ketiga.

        my-program encode input.png output.txt
        my-program decode output.txt output.png
        
  5. Untuk solusi Anda, silakan kirim:
    1. Kode Anda, secara penuh, dan / atau tautan yang dihosting di tempat lain (jika sangat panjang, atau membutuhkan banyak file untuk dikompilasi, atau sesuatu).
    2. Penjelasan tentang cara kerjanya, jika tidak segera jelas dari kode atau jika kode panjang dan orang akan tertarik pada ringkasan.
    3. Contoh gambar, dengan gambar asli, teks yang dikompres ke bawah, dan gambar yang diterjemahkan.
    4. Jika Anda membangun ide yang dimiliki orang lain, mohon cantumkan. Tidak masalah untuk mencoba melakukan penyempurnaan terhadap ide orang lain, tetapi Anda harus mengaitkannya.

Pedoman

Ini pada dasarnya adalah aturan yang dapat dilanggar, saran, atau kriteria penilaian:

  1. Estetika itu penting. Saya akan menilai, dan menyarankan agar orang lain menilai, berdasarkan:
    1. Seberapa baik gambar output terlihat, dan seberapa mirip gambar aslinya.
    2. Alangkah bagusnya teks itu. Buku gobbledigook yang benar-benar acak tidak masalah jika Anda memiliki skema kompresi yang sangat pintar, tetapi saya juga ingin melihat jawaban yang mengubah gambar menjadi puisi mutli-bahasa, atau sesuatu yang pintar seperti itu. Perhatikan bahwa pembuat solusi asli memutuskan untuk hanya menggunakan karakter Cina, karena terlihat lebih bagus.
    3. Kode yang menarik dan algoritme pintar selalu bagus. Saya suka pendek, to the point, dan kode yang jelas, tetapi algoritma rumit benar-benar pintar juga OK selama mereka menghasilkan hasil yang baik.
  2. Kecepatan juga penting, meskipun tidak sepenting seberapa baik pekerjaan mengompres gambar yang Anda lakukan. Saya lebih suka memiliki program yang dapat mengkonversi gambar dalam sepersepuluh detik dari sesuatu yang akan menjalankan algoritma genetika selama berhari-hari.
  3. Saya lebih suka solusi yang lebih pendek daripada yang lebih lama, asalkan kualitasnya sebanding; keringkasan adalah suatu kebajikan.
  4. Program Anda harus diimplementasikan dalam bahasa yang memiliki implementasi yang tersedia secara bebas di Mac OS X, Linux, atau Windows. Saya ingin dapat menjalankan program, tetapi jika Anda memiliki solusi hebat yang hanya berjalan di bawah MATLAB atau sesuatu, itu tidak masalah.
  5. Program Anda harus bersifat umum; itu harus bekerja untuk sebanyak mungkin gambar yang berbeda, meskipun beberapa mungkin menghasilkan hasil yang lebih baik daripada yang lain. Khususnya:
    1. Memiliki beberapa gambar yang dibangun ke dalam program yang cocok dan menulis referensi, dan kemudian menghasilkan gambar yang cocok saat decoding, cukup timpang dan hanya akan mencakup beberapa gambar.
    2. Suatu program yang dapat mengambil gambar bentuk sederhana, datar, geometris dan menguraikannya menjadi beberapa vektor primitif cukup bagus, tetapi jika gagal pada gambar di luar kompleksitas tertentu mungkin itu tidak cukup umum.
    3. Program yang hanya dapat mengambil gambar dengan rasio aspek tetap tertentu tetapi melakukan pekerjaan dengan baik juga akan baik-baik saja, tetapi tidak ideal.
    4. Anda mungkin menemukan bahwa gambar hitam dan putih dapat memperoleh lebih banyak informasi ke dalam ruang yang lebih kecil daripada gambar berwarna. Di sisi lain, itu dapat membatasi jenis gambar yang dapat diterapkan; wajah menjadi hitam dan putih, tetapi desain abstrak mungkin tidak berjalan dengan baik.
    5. Tidak apa-apa jika gambar output lebih kecil dari input, sementara proporsi yang kira-kira sama. Tidak apa-apa jika Anda harus memperbesar gambar untuk membandingkannya dengan aslinya; yang penting adalah tampilannya.
  6. Program Anda harus menghasilkan output yang benar-benar bisa melalui Twitter dan keluar tanpa cedera. Ini hanya panduan daripada aturan, karena saya tidak dapat menemukan dokumentasi tentang set karakter yang didukung, tetapi Anda mungkin harus menghindari karakter kontrol, karakter menggabungkan yang funky yang tak terlihat, karakter penggunaan pribadi, dan sejenisnya.

Rubrik penilaian

Sebagai panduan umum tentang bagaimana saya akan menentukan peringkat solusi ketika memilih solusi yang saya terima, katakanlah saya mungkin akan mengevaluasi solusi pada skala 25 poin (ini sangat kasar, dan saya tidak akan mencetak apa pun secara langsung, hanya menggunakan ini sebagai pedoman dasar):

  • 15 poin untuk seberapa baik skema pengkodean mereproduksi berbagai macam gambar input. Ini adalah penilaian subyektif dan estetis
    • 0 berarti itu tidak berfungsi sama sekali, itu memberikan gambar yang sama kembali setiap kali, atau sesuatu
    • 5 berarti ia dapat meng-enkode beberapa gambar, meskipun versi yang didekodekannya terlihat jelek dan mungkin tidak bekerja sama sekali pada gambar yang lebih rumit
    • 10 berarti bahwa ia bekerja pada berbagai gambar, dan menghasilkan gambar tampak menyenangkan yang kadang-kadang dapat dibedakan
    • 15 berarti bahwa itu menghasilkan replika sempurna dari beberapa gambar, dan bahkan untuk gambar yang lebih besar dan lebih kompleks, memberikan sesuatu yang dapat dikenali. Atau, mungkin itu tidak membuat gambar yang cukup dikenali, tetapi menghasilkan gambar yang indah yang jelas berasal dari aslinya.
  • 3 poin untuk penggunaan cerdas dari rangkaian karakter Unicode
    • 0 poin untuk hanya menggunakan seluruh rangkaian karakter yang diizinkan
    • 1 poin untuk menggunakan serangkaian karakter terbatas yang aman untuk ditransfer melalui Twitter atau dalam berbagai situasi yang lebih luas
    • 2 poin untuk menggunakan subset karakter tematik, seperti hanya Han ideograf atau hanya karakter kanan-ke-kiri
    • 3 poin untuk melakukan sesuatu yang sangat rapi, seperti menghasilkan teks yang dapat dibaca atau menggunakan karakter yang terlihat seperti gambar yang dimaksud
  • 3 poin untuk pendekatan algoritmik cerdas dan gaya kode
    • 0 poin untuk sesuatu yang 1000 baris kode hanya untuk memperkecil gambar, perlakukan sebagai 1 bit per piksel, dan base64 mengkodekan itu
    • 1 poin untuk sesuatu yang menggunakan teknik pengkodean standar dan ditulis dengan baik dan singkat
    • 2 poin untuk sesuatu yang memperkenalkan teknik pengodean yang relatif baru, atau yang mengejutkan pendek dan bersih
    • 3 poin untuk satu liner yang benar-benar menghasilkan hasil yang baik, atau sesuatu yang membuka jalan baru dalam penyandian grafis (jika ini seperti jumlah poin yang rendah untuk menerobos landasan baru, ingatlah bahwa hasil yang baik ini kemungkinan akan memiliki skor tinggi untuk estetika demikian juga)
  • 2 poin untuk kecepatan. Semuanya sama, lebih cepat lebih baik, tetapi kriteria di atas lebih penting daripada kecepatan
  • 1 poin untuk berjalan pada perangkat lunak bebas (open source), karena saya lebih suka perangkat lunak gratis (perhatikan bahwa C # akan tetap memenuhi syarat untuk titik ini selama ini berjalan pada Mono, demikian juga kode MATLAB akan memenuhi syarat jika berjalan pada GNU Octave)
  • 1 poin untuk benar-benar mengikuti semua aturan. Aturan-aturan ini menjadi agak besar dan rumit, jadi saya mungkin akan menerima jawaban yang baik jika tidak salah detail kecil, tapi saya akan memberikan poin tambahan untuk solusi yang benar-benar mengikuti semua aturan

Gambar referensi

Beberapa orang telah meminta beberapa gambar referensi. Berikut adalah beberapa gambar referensi yang dapat Anda coba; versi yang lebih kecil tertanam di sini, semuanya terhubung ke versi gambar yang lebih besar jika Anda membutuhkannya:

Lena Mona lisa Kotak Cornell Logo StackOverflow

Hadiah

Saya menawarkan hadiah 500 rep (ditambah 50 yang ditendang oleh StackOverflow) untuk solusi yang saya sukai, berdasarkan kriteria di atas. Tentu saja, saya mendorong semua orang untuk memilih solusi favorit mereka di sini juga.

Perhatikan tenggat waktu

Kontes ini akan berlangsung hingga hadiah habis, sekitar jam 6 sore pada hari Sabtu, 30 Mei. Saya tidak dapat mengatakan waktu pasti akan berakhir; mungkin berkisar antara 5 hingga 7 malam. Saya akan menjamin bahwa saya akan melihat semua entri yang dikirimkan pada pukul 14:00, dan saya akan melakukan yang terbaik untuk melihat semua entri yang diserahkan pada pukul 16:00; jika solusi diajukan setelah itu, saya mungkin tidak memiliki kesempatan untuk memberi mereka pandangan yang adil sebelum saya harus membuat keputusan. Selain itu, semakin awal Anda mengirim, semakin banyak peluang yang Anda miliki untuk memberikan suara untuk dapat membantu saya memilih solusi terbaik, jadi cobalah dan kirimkan lebih awal daripada tepat di tenggat waktu.

Catatan Unicode

Ada juga beberapa kebingungan tentang apa yang diperbolehkan oleh karakter Unicode. Kisaran poin kode Unicode yang mungkin adalah U+0000untuk U+10FFFF. Ada beberapa titik kode yang tidak pernah valid untuk digunakan sebagai karakter Unicode dalam pertukaran data apa pun yang terbuka; ini adalah karakter noncharacters dan kode pengganti . Noncharacters didefinisikan dalam Unidode Standard 5.1.0 bagian 16,7 sebagai nilai-nilai U+FFFE, U+FFFF, U+nFFFE , U+nFFFF di mana n adalah 1- 10heksadesimal, dan kisaran U+FDD0-U+FDEF. Nilai-nilai ini dimaksudkan untuk digunakan untuk penggunaan internal spesifik aplikasi, dan aplikasi yang sesuai dapat menghapus karakter ini dari teks yang diproses oleh mereka. Poin pengganti kode, didefinisikan dalam Unicode Standard 5.1.0 bagian 3.8 sebagai U+D800- U+DFFF, digunakan untuk pengkodean karakter di luar Basic Multilingual Plane di UTF-16; dengan demikian, tidak mungkin untuk mewakili titik-titik kode ini secara langsung dalam pengkodean UTF-16, dan tidak sah untuk menyandikannya dalam pengkodean lainnya. Dengan demikian, untuk tujuan kontes ini, saya akan mengizinkan program apa pun yang menyandikan gambar ke dalam urutan yang tidak lebih dari 140 titik kode Unicode dari rentang U+0000- U+10FFFF, tidak termasuk semua noncharacters dan pasangan pengganti sebagaimana didefinisikan di atas.

Saya akan lebih suka solusi yang hanya menggunakan karakter yang ditugaskan, dan bahkan yang lebih baik yang menggunakan himpunan bagian cerdas dari karakter yang ditugaskan atau melakukan sesuatu yang menarik dengan set karakter yang mereka gunakan. Untuk daftar karakter yang ditugaskan, lihat Database Karakter Unicode ; perhatikan bahwa beberapa karakter dicantumkan secara langsung, sementara beberapa terdaftar hanya sebagai awal dan akhir suatu rentang. Juga perhatikan bahwa poin kode pengganti tercantum dalam database, tetapi dilarang seperti yang disebutkan di atas. Jika Anda ingin memanfaatkan properti karakter tertentu untuk membuat teks yang Anda hasilkan lebih menarik, ada berbagai database informasi karakter yang tersedia, seperti daftar blok kode bernama dan berbagai properti karakter.

Karena Twitter tidak menentukan set karakter yang tepat yang mereka dukung, saya akan menerima solusi yang tidak benar-benar bekerja dengan Twitter karena karakter tertentu menghitung ekstra atau karakter tertentu dilucuti. Lebih disukai tetapi tidak diharuskan bahwa semua keluaran yang disandikan harus dapat ditransfer tanpa cedera melalui Twitter atau layanan microblogging lainnya seperti identi.ca . Saya telah melihat beberapa dokumentasi yang menyatakan bahwa entitas Twitter mengkodekan <,>, dan &, dan dengan demikian menghitungnya masing-masing 4, 4, dan 5 karakter, tetapi saya belum menguji itu sendiri, dan penghitung karakter JavaScript mereka tampaknya tidak terlihat. untuk menghitungnya seperti itu.

Kiat & Tautan

  • Definisi karakter Unicode yang valid dalam aturan agak rumit. Memilih satu blok karakter, seperti CJK Unified Ideographs (U + 4E00 – U + 9FCF) mungkin lebih mudah.
  • Anda dapat menggunakan pustaka gambar yang ada, seperti ImageMagick atau Python Imaging Library , untuk manipulasi gambar Anda.
  • Jika Anda memerlukan bantuan untuk memahami rangkaian karakter Unicode dan beragam penyandiannya, lihat panduan cepat ini atau FAQ terperinci tentang UTF-8 di Linux dan Unix .
  • Semakin awal Anda mendapatkan solusi, semakin banyak waktu saya (dan orang lain memberikan suara) harus melihatnya. Anda dapat mengedit solusi Anda jika Anda memperbaikinya; Saya akan mendasarkan karunia saya pada versi terbaru ketika saya melihat solusi terakhir saya.
  • Jika Anda ingin format gambar yang mudah diurai dan ditulis (dan tidak ingin hanya menggunakan format yang sudah ada), saya sarankan menggunakan format PPM . Ini adalah format berbasis teks yang sangat mudah digunakan, dan Anda dapat menggunakan ImageMagick untuk mengonversi dari dan ke sana.
Brian Campbell
sumber
Jangan ragu untuk memberikan saran tentang aturan yang saya tulis di komentar; Saya tentu saja ingin mengubah mereka jika orang merasa mereka perlu klarifikasi atau terlalu spesifik.
Brian Campbell
6
Anda mungkin harus mengatakan bahwa mengunggah gambar ke server dan mengeposkan url ke sana tidak valid.
Shay Erlichmen
2
@Shay Bukankah saya sudah mengatakan itu? "Proses decoding mungkin tidak memiliki akses ke output lain dari proses encoding selain output yang ditentukan di atas; yaitu, Anda tidak dapat mengunggah gambar di suatu tempat dan output URL untuk proses decoding untuk mengunduh, atau hal konyol seperti itu . "
Brian Campbell
1
@Konrad Rudolph Saya setuju; Saya tidak bermaksud "konyol" dari sudut pandang praktis (jelas, seluruh kontes ini konyol dari sudut pandang praktis), maksud saya "konyol" dalam konteks kontes ini. Menggunakan URI sebenarnya bukan algoritma kompresi, dalam arti teori informasi, karena tidak memungkinkan Anda untuk mentransfer informasi lebih lanjut tanpa hanya menggunakan saluran alternatif. Anda bisa memberi pembuat kode dan pembuat kode basis data gambar besar, dan menyebutnya kompresi yang hanya berfungsi pada set gambar yang terbatas, tetapi saya menentukan bahwa Anda harus bisa menangani gambar yang sewenang-wenang.
Brian Campbell
2
Berikut adalah beberapa tautan yang pernah saya temui yang dapat membantu orang-orang: azillionmonkeys.com/qed/unicode.html untuk penjelasan tentang kisaran karakter Unicode yang valid. Perhatikan bahwa pengkodean UTF adalah yang dapat menyandikan seluruh rentang Unicode; UCS-4 adalah superset dari Unicode, dan UCS-2 & ASCII adalah himpunan bagian. Dan di bagian kompresi, inilah teknik yang mirip dengan pos asli, meskipun dia membiarkan dirinya 1k daripada 350 byte: screamingduck.com/Article.php?ArticleID=46&Show=ABCE
Brian Campbell

Jawaban:

244

Baiklah, ini milik saya: nanocrunch.cpp dan file CMakeLists.txt untuk membuatnya menggunakan CMake. Itu bergantung pada Magick ++ ImageMagick API untuk sebagian besar penanganan gambarnya. Ini juga membutuhkan pustaka GMP untuk aritmatika bignum untuk pengkodean string-nya.

Saya mendasarkan solusi saya dari kompresi gambar fraktal, dengan beberapa tikungan unik. Ide dasarnya adalah untuk mengambil gambar, mengurangi salinan hingga 50% dan mencari potongan-potongan dalam berbagai orientasi yang terlihat mirip dengan blok yang tidak tumpang tindih dalam gambar asli. Dibutuhkan pendekatan yang sangat kasar untuk pencarian ini, tetapi itu hanya membuatnya lebih mudah untuk memperkenalkan modifikasi saya.

Modifikasi pertama adalah bahwa alih-alih hanya melihat rotasi dan flips sembilan puluh derajat, program saya juga mempertimbangkan orientasi 45 derajat. Satu bit lebih per blok, tetapi sangat membantu kualitas gambar.

Hal lain adalah bahwa menyimpan penyesuaian kontras / kecerahan untuk masing-masing komponen warna setiap blok terlalu mahal. Sebagai gantinya, saya menyimpan warna yang sangat terkuantisasi (palet hanya memiliki 4 * 4 * 4 = 64 warna) yang cukup dicampur dalam proporsi tertentu. Secara matematis, ini setara dengan kecerahan variabel dan penyesuaian kontras konstan untuk setiap warna. Sayangnya, itu juga berarti tidak ada kontras negatif untuk membalik warna.

Setelah itu dihitung posisi, orientasi dan warna untuk setiap blok, itu mengkodekan ini menjadi string UTF-8. Pertama, ini menghasilkan bignum yang sangat besar untuk mewakili data dalam tabel blok dan ukuran gambar. Pendekatan ini mirip dengan solusi Sam Hocevar - semacam jumlah besar dengan radix yang bervariasi berdasarkan posisi.

Kemudian mengkonversi itu menjadi basis berapa pun ukuran set karakter yang tersedia. Secara default, ini menggunakan set karakter unicode yang ditugaskan secara penuh, minus kurang dari, lebih besar dari, ampersand, kontrol, menggabungkan, dan karakter pengganti dan pribadi. Itu tidak cantik tapi berhasil. Anda juga dapat mengomentari tabel default dan memilih ASCII 7-bit yang dapat dicetak (sekali lagi tidak termasuk <,>, & & karakter) atau sebagai gantinya CJK Unified Ideographs. Tabel kode karakter mana yang tersedia disimpan panjang run dikodekan dengan bolak-balik berjalan karakter yang tidak valid dan valid.

Lagi pula, berikut adalah beberapa gambar dan waktu (yang diukur pada P4 3.0GHz lama saya), dan dikompresi menjadi 140 karakter dalam set unicode yang ditugaskan penuh dijelaskan di atas. Secara keseluruhan, saya cukup senang dengan hasilnya. Jika saya memiliki lebih banyak waktu untuk mengerjakan ini, saya mungkin akan mencoba untuk mengurangi kebuntuan dari gambar yang terkompresi. Meski begitu, saya pikir hasilnya cukup bagus untuk rasio kompresi ekstrem. Gambar yang didekompresi agak impresionis, tetapi saya merasa relatif mudah untuk melihat bagaimana bit sesuai dengan aslinya.

Stack Overflow Logo (8,6s untuk meng-encode, 7,9s ke decode, 485 bytes):
http://i44.tinypic.com/2w7lok1.png

Lena (32.8s untuk meng-encode, 13.0s ke decode, 477 bytes):
http://i42.tinypic.com/2rr49wg.png http://i40.tinypic.com/2rhxxyu.png

Mona Lisa (43.2s untuk menyandikan, 14.5s untuk menyandikan, 490 bytes):
http://i41.tinypic.com/ekgwp3.png http://i43.tinypic.com/ngsxep.png

Sunting: CJK Unified Characters

Sam bertanya dalam komentar tentang menggunakan ini dengan CJK. Berikut adalah versi Mona Lisa yang dikompresi menjadi 139 karakter dari rangkaian karakter CJK Unified:

http://i43.tinypic.com/2yxgdfk.png 咏 璘 驞 凄 脒 鵚 据 蛥 鸂 拗 朐 辿 韩 韩 瀦 瀦 歪 歪 歪 緍 緍 蕜 抱 抱 揎 頻 蓼 靊 寞 嚛 嚵 聚 聚 聚 聚 聚 聚隤 慛 絖 銓 馿 渫 櫰 矍 昀 鰛 掾 撄 粂 敽 牙 稉 稉 蔍 螎 覧 覧 絀 絀 絀 抆 惫 惫 惫 搀 譶 譶 譶 辍 童 童 童 竽 喙 狌 狌 狌 狌 狌 狌 狌 狌 狌 狌 狌 狌 镰伆 杇 婣 唆 鐤 諽 鷍 鴞 駫 搶 毤 埙 誖 萜 愿 旖 旖 萗 勹 垬 垬 濅 濅 濅 秀 瞛 瞛 瞛 狋 籴 籴 籴 珵 茴 茴 茴 晋 爸 縿 縿 縿 縿 縿 縿 縿 縿 縿 縿 縿 縿 嚖擸 萿

Parameter penyetelan di bagian atas program yang saya gunakan untuk ini adalah: 19, 19, 4, 4, 3, 10, 11, 1000, 1000. Saya juga mengomentari definisi pertama dari number_assigned dan kode, dan menghapus komentar dari definisi terakhir dari mereka untuk memilih set karakter CJK Unified.

Boojum
sumber
Wow! Pekerjaan yang baik. Saya ragu dengan kompresi gambar fraktal untuk gambar sekecil ini, tetapi sebenarnya menghasilkan hasil yang lumayan. Itu juga cukup mudah untuk dikompilasi dan dijalankan.
Brian Campbell
1
Terima kasih teman-teman! Sam, maksud Anda hasil dengan hanya 140 karakter CJK? Jika demikian, maka ya, Anda harus menyetel angka di bagian atas. Ukuran akhir dalam bit adalah sekitar log2 (steps_in_x steps_in_y steps_in_red steps_in_green steps_in_blue) * blocks_in_x blocks_in_y + log2 ( maksimum_width maksimum_tinggi ).
Boojum
Sunting: Ada * 16 di log2 pertama () yang saya tinggalkan. Itu untuk kemungkinan orientasi.
Boojum
20
Adakah yang punya twitter untuk menggunakan ini?
dbr
288

file gambar dan sumber python (versi 1 dan 2)

Versi 1 Ini adalah upaya pertama saya. Saya akan memperbarui saat saya pergi.

Saya telah mendapatkan logo SO hingga 300 karakter yang hampir tanpa kerugian. Teknik saya menggunakan konversi ke seni vektor SVG sehingga bekerja paling baik pada seni garis. Ini sebenarnya adalah kompresor SVG, masih membutuhkan karya seni asli melalui tahap vektorisasi.

Untuk upaya pertama saya, saya menggunakan layanan online untuk jejak PNG namun ada banyak alat gratis dan tidak-bebas yang dapat menangani bagian ini termasuk potrace (open-source).

Inilah hasilnya

Asli SO Logo http://www.warriorhut.org/graphics/svg_to_unicode/so-logo.png asli Decoded SO Logo http://www.warriorhut.org/graphics/svg_to_unicode/so-logo-decoded.png Setelah encoding dan decoding

Karakter : 300

Waktu : Tidak diukur tetapi praktis instan (tidak termasuk langkah-langkah vektorisasi / rasterisasi)

Tahap selanjutnya adalah menanamkan 4 simbol (SVG path points dan perintah) per karakter unicode. Saat ini python build saya tidak memiliki dukungan karakter lebar UCS4 yang membatasi resolusi saya per karakter. Saya juga membatasi rentang maksimum ke bagian bawah kisaran unicode yang disediakan 0xD800 namun begitu saya membangun daftar karakter yang diizinkan dan filter untuk menghindarinya, saya secara teoritis dapat mendorong jumlah karakter yang diperlukan hingga 70-100 untuk logo di atas.

Keterbatasan metode ini saat ini adalah ukuran output tidak tetap. Itu tergantung pada jumlah titik / titik vektor setelah vektorisasi. Mengotomatiskan batas ini akan membutuhkan pixelating gambar (yang menghilangkan manfaat utama vektor) atau mengulangi menjalankan jalur melalui tahap penyederhanaan hingga jumlah simpul yang diinginkan tercapai (yang saat ini saya lakukan secara manual di Inkscape).

Versi 2

UPDATE : v2 sekarang memenuhi syarat untuk bersaing. Perubahan:

  • Input / output kontrol dan debugging baris perintah
  • Menggunakan parser XML (lxml) untuk menangani SVG alih-alih regex
  • Paket 2 segmen jalur per simbol unicode
  • Dokumentasi dan pembersihan
  • Gaya dukungan = "isi: warna" dan isi = "warna"
  • Lebar / tinggi dokumen dikemas dalam satu karakter
  • Warna jalur dikemas menjadi satu karakter
  • Kompresi warna dicapai dengan membuang 4 bit data warna per warna kemudian mengemasnya menjadi karakter melalui konversi hex.

Karakter : 133

Waktu : Beberapa detik

v2 decoded http://www.warriorhut.org/graphics/svg_to_unicode/so-logo-decoded-v2.png Setelah penyandian dan decoding (versi 2)

Seperti yang Anda lihat ada beberapa artefak saat ini. Ini bukan batasan metode tetapi kesalahan di konversi saya. Artefak terjadi ketika poin pergi di luar kisaran 0,0 - 127,0 dan upaya saya untuk membatasi mereka telah berhasil beragam. Solusinya adalah hanya dengan menurunkan skala gambar tetapi saya mengalami kesulitan skala poin sebenarnya daripada artboard atau grup matriks dan saya terlalu lelah sekarang untuk peduli. Singkatnya, jika poin Anda berada dalam rentang yang didukung, biasanya berfungsi.

Saya percaya kekusutan di tengah disebabkan oleh pegangan yang bergerak ke sisi lain pegangan yang terhubung dengannya. Pada dasarnya poinnya terlalu berdekatan. Menjalankan filter penyederhanaan di atas gambar sumber sebelum mengompresnya harus memperbaiki ini dan mencukur beberapa karakter yang tidak perlu.

PEMBARUAN : Metode ini baik untuk objek sederhana jadi saya perlu cara untuk menyederhanakan jalur yang rumit dan mengurangi kebisingan. Saya menggunakan Inkscape untuk tugas ini. Saya sudah beruntung dengan menata jalur yang tidak perlu menggunakan Inkscape tetapi tidak punya waktu untuk mencoba mengotomatiskannya. Saya telah membuat beberapa sampel svgs menggunakan fungsi 'Sederhanakan' Inkscape untuk mengurangi jumlah jalur.

Sederhanakan berfungsi dengan baik tetapi bisa lambat dengan banyak jalur ini.

contoh autotrace http://www.warriorhut.org/graphics/svg_to_unicode/autotrace_16_color_manual_reduction.png kotak cornell http://www.warriorhut.com/graphics/svg_to_unicode/cornell_box_simplified.png lena http://www.warriorhut.com/graphics /svg_to_unicode/lena_std_washed_autotrace.png

thumbnail yang menelusuri http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_autotrace.png

Inilah beberapa foto dengan resolusi sangat rendah. Ini akan lebih dekat ke batas 140 karakter meskipun beberapa kompresi jalur pintar mungkin juga diperlukan.

groomed http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_groomed.png Disederhanakan dan dicela.

trianglulated http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_triangulated.png Disederhanakan, dikecewakan, dan triangulasi.

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

DI ATAS: Jalur yang disederhanakan menggunakan autotrace .

Sayangnya parser saya tidak menangani output autotrace jadi saya tidak tahu bagaimana poin dapat digunakan atau seberapa jauh untuk menyederhanakan, sayangnya ada sedikit waktu untuk menulisnya sebelum batas waktu. Ini jauh lebih mudah untuk diurai daripada output inkscape.

SpliFF
sumber
2
Luar biasa! Pada awalnya saya ingin membuat solusi vektor hibrida dengan tepi yang tajam dan area yang halus, tetapi ternyata terlalu rumit tanpa menggunakan tracing library (yang saya tidak ingin gunakan). Saya menantikan untuk melihat seberapa jauh Anda bisa mendapatkan dengan metode Anda!
sam hocevar
Bagus! Saya berharap kita akan melihat beberapa upaya pendekatan mendekati-lossless oleh vektorisasi. Ini berarti memiliki generalitas yang lebih rendah, tetapi kualitas yang lebih tinggi untuk gambar yang dicakupnya. Tidak apa-apa menggunakan layanan online untuk vektorisasi. Semoga berhasil mendapatkan ukuran turun lebih lanjut!
Brian Campbell
Saya akan mempertimbangkan kompresi gambar dan pengkodean karakter sebagai dua langkah yang berbeda - teknik Sam tampaknya optimal untuk pengkodean, dan dapat dengan mudah dibangun menjadi program yang berdiri sendiri. Anda akan mendapatkan lebih banyak keuntungan dengan berkonsentrasi pada bagian unik dari solusi Anda (yaitu bagian kompresi) dan hanya mengeluarkan serangkaian bit.
Mark Ransom
70
Wow. Gambar-gambar ini terlihat sangat bergaya.
Rinat Abdullin
199

Solusi lengkap saya dapat ditemukan di http://caca.zoy.org/wiki/img2twit . Ini memiliki beberapa fitur berikut:

  • Waktu kompresi yang masuk akal (sekitar 1 menit untuk kualitas tinggi)
  • Dekompresi cepat (sepersekian detik)
  • Menyimpan ukuran gambar asli (bukan hanya rasio aspek)
  • Kualitas rekonstruksi yang layak (IMHO)
  • Panjang pesan dan set karakter (ASCII, CJK, Simbol) dapat dipilih saat runtime
  • Panjang pesan dan set karakter secara otomatis terdeteksi pada waktu dekompresi
  • Pengemasan informasi yang sangat efisien

http://caca.zoy.org/raw-attachment/wiki/img2twit/so-logo.png http://caca.zoy.org/raw-attachment/wiki/img2twit/twitter4.png

蜥 秓 鋖 筷 聝 诿 缰 偺 腶 漷 庯 祩 皙 靊 谪 獜 獜 幻 寤 脘 脘 搇 搇 搇 踥 桻 桻 桻 欇 軱 軱 軱 骿 璨 璨 璨 粭 岚 衍 衍 衍 衍 衍 衍 衍 衍 衍 衍 衍 衍 捕 衍 衍 衍玧 霫 鏓 蓕 戲 債 鼶 襋 躻 弯 袮 足 庭 侅 旍 凼 凼 驅 據 倾 倾 诗 诗 诗 阉 嶹 嶹 嶹 墤 赐 赐 赐 更 逡 逡 逡 荨 憫 陁 陁 陁 陁 陁 陁 陁 陁 陁 陁 陁 陁 翉 陁 陁 陁擲 舥 攩 寉 鈶 兓 庭 璱 篂 鰀 鰀 乾 丕 庁 錸 錸 努 樀 肝 亖 蝞 蝞 躐 躐 葌 熲 谎 谎 谎 谎 刍 媏 媏 嘝 嘝 驌 盂 缰 殾 譑 譑 譑

Berikut ini gambaran umum kasar dari proses penyandian:

  • Jumlah bit yang tersedia dihitung dari panjang pesan yang diinginkan dan charset yang dapat digunakan
  • Gambar sumber tersegmentasi menjadi sel kuadrat sebanyak yang diizinkan bit
  • Jumlah titik tetap (saat ini 2) dipengaruhi untuk setiap sel, dengan koordinat awal dan nilai warna
  • Berikut ini diulangi hingga kondisi kualitas terpenuhi:
    • Suatu titik dipilih secara acak
    • Operasi dilakukan secara acak pada titik ini (memindahkannya ke dalam selnya, mengubah warnanya)
    • Jika gambar yang dihasilkan (lihat proses decoding di bawah) lebih dekat ke gambar sumber, operasi disimpan
  • Ukuran gambar dan daftar titik dikodekan dalam UTF-8

Dan ini adalah proses decoding:

  • Ukuran dan titik gambar dibaca dari aliran UTF-8
  • Untuk setiap piksel dalam gambar tujuan:
    • Daftar neigbours alami dihitung
    • Warna akhir piksel ditetapkan sebagai rata-rata tertimbang dari warna tetangganya yang alami

Apa yang saya yakini adalah bagian paling asli dari program ini adalah bitstream. Alih-alih mengemas nilai bit-aligned ( stream <<= shift; stream |= value), saya mengemas nilai arbitrer yang tidak berada dalam rentang dua kekuatan ( stream *= range; stream += value). Ini membutuhkan perhitungan bignum dan tentu saja jauh lebih lambat, tetapi memberi saya 2009,18 bit, bukan 1960 ketika menggunakan 20902 karakter CJK utama (itu tiga poin lagi yang bisa saya masukkan ke dalam data). Dan ketika menggunakan ASCII, itu memberi saya 917,64 bit, bukan 840.

Saya memutuskan untuk tidak menggunakan metode penghitungan gambar awal yang membutuhkan persenjataan berat (deteksi sudut, ekstraksi fitur, quantisation warna ...) karena pada awalnya saya tidak yakin itu akan sangat membantu. Sekarang saya menyadari konvergensi lambat (1 menit dapat diterima tetapi tetap lambat) dan saya dapat mencoba meningkatkannya.

Loop pas utama diilhami secara longgar dari algoritma dithering Direct Binary Seach (di mana piksel ditukar secara acak atau dibalik sampai halftone yang lebih baik diperoleh). Perhitungan energi adalah jarak root-mean-square sederhana, tetapi saya melakukan filter median 5x5 pada gambar asli terlebih dahulu. Gaussian blur mungkin akan lebih mewakili perilaku mata manusia, tetapi saya tidak ingin kehilangan tepi tajam. Saya juga memutuskan menentang anil simulasi atau metode sulit lainnya karena saya tidak punya waktu berbulan-bulan untuk mengkalibrasi proses. Jadi bendera "kualitas" hanya mewakili jumlah iterasi yang dilakukan pada setiap titik sebelum encoder berakhir.

http://caca.zoy.org/raw-attachment/wiki/img2twit/Mona_Lisa_scaled.jpg http://caca.zoy.org/raw-attachment/wiki/img2twit/twitter2.png

苉 憗 揣 嶕 繠 剳 腏 篮 濕 茝 霮 墧 蒆 棌 杚 蓳 蓳 樟 赒 噹 噹 砃 砃 砃 任 朓 朓 朓 陴 掝 掝 掝 喗 鷾 鷾 鷾 瓔 俇 鸬 鸬 鸬 鸬 鸬 鸬 鸬 鸬 鸬 鸬 鸬 鸬 芟 鸬 鸬 鸬激 躙 憮 鄴 甮 槺 骳 佛 愚 猪 駪 惾 嫥 綖 珏 矯 矯 堭 颽 飉 飉 訥 訥 訥 箝 窂 窂 窂 衆 航 航 航 玴 墎 墎 墎 ​​嬔 秓 蕖 蕖 蕖 蕖 蕖 蕖 蕖 蕖 蕖 蕖 蕖 蕖 瑥 蕖 蕖 蕖苾 绒 酯 嵞 脔 婺 污 囉 酼 俵 俵 菛 琪 则 辩 辩 曚 鸸 職 銛 鱚 鱚 蟺 蟺 稿 纡 醾 醾 醾 蟀 蟀 鋁 鋁 髚 髚 忩 脤 趯 沅 况 况 况 况 况 况 况 况

Meskipun tidak semua gambar kompres dengan baik, saya terkejut dengan hasilnya dan saya benar-benar bertanya-tanya metode apa yang ada yang dapat memampatkan gambar hingga 250 byte.

Saya juga memiliki film kecil evolusi negara pembuat kode dari keadaan awal acak dan dari keadaan awal yang "baik" .

Sunting : di sini adalah perbandingan metode kompresi dengan JPEG. Di sebelah kiri, gambar jamoes di atas 536 byte. Di sebelah kanan, Mona Lisa dikompresi menjadi 534 byte menggunakan metode yang dijelaskan di sini (byte yang disebutkan di sini mengacu pada data byte, oleh karena itu mengabaikan bit yang terbuang dengan menggunakan karakter Unicode):

http://caca.zoy.org/raw-attachment/wiki/img2twit/minimona.jpg http://caca.zoy.org/raw-attachment/wiki/img2twit/minimona2.png

Sunting : baru saja mengganti teks CJK dengan versi gambar terbaru.

sam hocevar
sumber
Saya sebenarnya tidak perlu bisa menjalankan kode (saya menempatkan bagian tentang menjalankannya dalam pedoman, sebagai saran, bukan aturan); Saya lebih suka untuk dapat menjalankannya, tetapi saya akan menilai ini lebih pada kualitas gambar yang Anda hasilkan, kode, dan trik atau algoritma yang menarik. Jika saya ingin menjalankannya dan memerlukan paket yang tidak saya miliki atau tidak ingin instal di sistem utama saya, saya bisa mem-boot instance Amazon EC2 dan menginstalnya. Selama Anda bekerja dengan perpustakaan yang dikemas untuk salah satu distro utama, saya harus dapat menjalankannya. Jangan ragu untuk menggunakan CGAL.
Brian Campbell
2
Oke, inilah solusi saya (kode sumber): caca.zoy.org/browser/libpipi/trunk/examples/img2twit.cpp Upaya penjelasan saya dan beberapa contoh ada di caca.zoy.org/wiki/img2twit
sam hocevar
2
Saya sangat suka solusi Anda. Anda harus mencoba mengurangi jumlah nilai yang ditetapkan ke saluran biru karena mata manusia tidak dapat menyelesaikan biru dengan baik: nfggames.com/games/ntsc/visual.shtm ; ini akan memungkinkan Anda untuk memiliki lebih banyak detail dengan mengorbankan beberapa informasi warna yang hilang. Atau mungkin menugaskannya ke hijau?
rpetrich
5
Poin yang bagus. Saya memang mencoba beberapa variasi ide ini (lihat komentar sebelum definisi RANGE_X) tetapi tidak terlalu menyeluruh. Seperti yang Anda lihat, menggunakan 5 nilai biru bukannya 6 meningkatkan kesalahan sedikit kurang dari menggunakan 7 nilai hijau menguranginya. Saya tidak mencoba melakukan keduanya karena malas. Masalah lain yang saya miliki adalah bahwa saya tidak memiliki fungsi kesalahan yang sangat baik. Saat ini saya menggunakan β (∆r² + ∆g² + ∆b²) / 3, yang berfungsi dengan baik. Saya mencoba § (0,299∆r² + 0,587∆g² + 0,114∆b²), berdasarkan (tanpa pembenaran fisik) pada komponen YUV Y, tetapi terlalu toleran dengan kesalahan biru. Saya akan mencoba mencari makalah tentang masalah ini.
sam Hocevar
2
@rpetrich: Saya memodifikasi program untuk membuatnya meningkatkan rentang r / g / b secara dinamis selama ada cukup bit yang tersedia. Ini memastikan bahwa kami tidak pernah membuang lebih dari 13 bit di seluruh bitstream (tetapi dalam praktiknya biasanya 1 atau 2). Dan gambar terlihat sedikit lebih baik.
sam hocevar
45

Berikut ini bukan pengajuan resmi, karena perangkat lunak saya belum dirancang dengan cara apa pun untuk tugas yang ditunjukkan. DLI dapat digambarkan sebagai optimalisasi codec gambar lossy tujuan umum. Ini adalah pemegang catatan PSNR dan MS-SSIM untuk kompresi gambar, dan saya pikir akan menarik untuk melihat bagaimana kinerjanya untuk tugas khusus ini. Saya menggunakan gambar referensi Mona Lisa yang disediakan dan memperkecil ke 100x150 kemudian menggunakan DLI untuk mengompresnya menjadi 344 byte.

Mona Lisa DLI http://i40.tinypic.com/2md5q4m.png

Untuk perbandingan dengan sampel terkompresi JPEG dan IMG2TWIT, saya menggunakan DLI untuk mengkompresi gambar ke 534 byte juga. JPEG adalah 536 byte dan IMG2TWIT adalah 534 byte. Gambar telah diskalakan hingga ukuran yang kira-kira sama untuk perbandingan yang mudah. JPEG adalah gambar kiri, IMG2TWIT tengah, dan DLI adalah gambar kanan.

Perbandingan http://i42.tinypic.com/302yjdg.png

Gambar DLI berhasil mempertahankan beberapa fitur wajah, terutama senyum yang terkenal :).

Brian Campbell
sumber
6
Ups. Di atas harus dikreditkan ke Dennis Lee, yang mengirimkannya awalnya. Saya baru saja mengeditnya untuk menyematkan gambar inline & tautan ke referensi yang saya temukan oleh Googling. Dan saya harus mengatakan, wow, saya terkesan dengan kompresi. Saya harus memeriksa kompresi DLI.
Brian Campbell
1
Omong-omong, penulis DLI menyebutkan "waktu pemrosesan yang lama". Karena saya tidak dapat menjalankan perangkat lunaknya, dapatkah Anda memberi kami angka waktu kompresi yang kasar?
sam hocevar
1
Menggunakan AMD Athlon64 2.4Ghz, kompresi gambar Mona Lisa 100x150 membutuhkan waktu 38 detik dan dekompresi 6sec. Mengompresi hingga maksimum 251 byte lebih sulit, kualitas output berkurang secara signifikan. Menggunakan gambar referensi Mona Lisa, saya turunkan ke 60x91 kemudian menggunakan DLI untuk mengompresnya ke 243 byte (paling dekat dengan 251 tanpa pergi). Ini adalah output i43.tinypic.com/2196m4g.png Detailnya tidak dekat dengan 534 byte DLI meskipun bitrate hanya berkurang ~ 50%. Struktur gambar telah dipertahankan dengan cukup baik.
1
Memutuskan untuk membuatnya lebih mudah untuk membandingkan sampel terkompresi 250 byte. DLI 243 byte ditingkatkan dan ditempatkan di sebelah sampel IMG2TWIT. IMG2TWIT di sebelah kiri, DLI di sebelah kanan. Inilah gambar i40.tinypic.com/30ndks6.png
1
DLI menggunakan parameter kualitas seperti JPEG, sehingga percobaan-dan-kesalahan diperlukan jika ukuran output target diinginkan.
21

Gambaran umum solusi saya adalah:

  1. Saya mulai dengan menghitung jumlah maksimum data mentah yang dapat Anda masukkan ke dalam 140 utf8 karakter.
    • (Saya mengasumsikan utf8, yang adalah apa yang asli situs mengklaim twitter disimpan pesan itu dalam. Ini berbeda dari pernyataan masalah di atas, yang meminta UTF16.)
    • Menggunakan faq utf8 ini , saya menghitung bahwa jumlah maksimum bit yang dapat Anda enkode dalam karakter utf8 tunggal adalah 31 bit. Untuk melakukan ini, saya akan menggunakan semua karakter yang berada dalam kisaran U-04000000 - U-7FFFFFFFFF. (1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx, ada 31 x, oleh karena itu saya bisa menyandikan hingga 31 bit).
    • 31 bit kali 140 karakter sama dengan 4340 bit. Bagilah dengan 8 untuk mendapatkan 524.5, dan bulatkan ke 542 byte .
    • (Jika kita membatasi diri untuk utf16, maka kita hanya bisa menyimpan 2 byte per karakter, yang akan sama dengan 280 byte).
  2. Kompres gambar ke bawah menggunakan kompresi jpg standar.
    • Ubah ukuran gambar menjadi sekitar 50x50px, kemudian cobalah untuk mengompresnya pada berbagai tingkat kompresi hingga Anda memiliki gambar yang sedekat mungkin dengan 542 byte tanpa pergi.
    • Ini adalah contoh mona lisa yang dikompresi hingga 536 byte.
  3. Encode bit mentah dari gambar yang dikompresi menjadi karakter utf-8.
    • Ganti setiap x dalam byte berikut: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx, dengan bit dari gambar.
    • Bagian ini mungkin akan menjadi bagian di mana sebagian besar kode perlu ditulis, karena tidak ada apa pun yang ada saat ini yang melakukan ini.

Saya tahu Anda meminta kode, tetapi saya tidak benar-benar ingin menghabiskan waktu untuk benar-benar membuat kode ini. Saya pikir desain yang efisien mungkin setidaknya menginspirasi orang lain untuk membuat kode ini.

Saya pikir manfaat utama dari solusi yang saya usulkan adalah menggunakan kembali sebanyak mungkin teknologi yang ada. Mungkin menyenangkan untuk mencoba menulis algoritma kompresi yang baik, tetapi ada jaminan untuk menjadi algoritma yang lebih baik di luar sana, kemungkinan besar ditulis oleh orang-orang yang memiliki gelar dalam matematika yang lebih tinggi.

Satu catatan penting lainnya adalah bahwa jika diputuskan bahwa utf16 adalah pengkodean yang disukai, maka solusi ini berantakan. jpegs tidak benar-benar berfungsi ketika dikompresi hingga 280 byte. Meskipun, mungkin ada algoritma kompresi yang lebih baik daripada jpg untuk pernyataan masalah khusus ini.

Stephen McCarthy
sumber
Saya sedang bekerja sekarang, tapi saya jelas mengimplementasikan solusi ini ketika saya sampai di rumah.
Paulo Santos
2
Dari eksperimen saya, tampak bahwa UTF-16 memang bagaimana Twitter menghitung karakter; Karakter BMP dihitung sebagai 1, dan karakter bidang yang lebih tinggi dihitung sebagai 2. Tidak didokumentasikan, tetapi itulah penghitung karakter JavaScriptnya yang diperhitungkan saat Anda mengetik ke dalam kotak input. Itu juga disebutkan dalam komentar di utas asli. Saya belum mencoba mengirim melalui API untuk melihat apakah penghitungnya rusak; jika ya, saya akan memperbarui masalah untuk kendala yang sebenarnya. Namun, Anda tidak dapat menggunakan UTF-8 sewenang-wenang, karena banyak dari sekuens yang lebih panjang yang dapat Anda enkode itu bukan Unicode yang valid.
Brian Campbell
4
Setelah pengujian dengan API mereka, ternyata mereka menghitung dengan karakter Unicode (titik kode), bukan unit kode UTF-16 (ini adalah penghitung karakter JavaScript yang dihitung melalui UTF-16, karena tampaknya itulah yang dilakukan metode panjang JavaScript) . Jadi Anda bisa mendapatkan informasi lebih banyak di sana; Karakter Unicode yang valid berada dalam kisaran U + 0000 hingga U + 10FFFF (sedikit lebih dari 20 bit per karakter; 2 ^ 20 + 2 ^ 16 nilai yang mungkin per karakter). UTF-8 memungkinkan encoding dari nilai-nilai lebih dari yang diperbolehkan dalam Unicode, jadi jika Anda membatasi diri Anda untuk Unicode, Anda bisa mendapatkan sekitar 350 byte ruang, tidak 542.
Brian Campbell
3
Mona lisa 536-byte itu terlihat sangat bagus, mengingat kompresi yang ekstrem!
Chris
3
Saat ini kami dapat menyandikan 129.775 karakter Unicode yang berbeda (ditugaskan, tidak terkontrol, non-pribadi). Jika kita membatasi diri pada subset itu, totalnya adalah 2377 bit, atau 297 byte. Kode di sini: porg.es/blog/what-can-we-fit-in-140-characters
porges
20

Oke, saya terlambat ke permainan, tetapi bagaimanapun saya membuat proyek saya.

Ini adalah algoritma genetika mainan yang menggunakan lingkaran berwarna transparan untuk membuat ulang gambar awal.

Fitur:

  • Lua murni. Berjalan di mana saja di mana penerjemah Lua dijalankan.
  • menggunakan format P3 netpbm
  • dilengkapi dengan serangkaian unit test yang komprehensif
  • mempertahankan ukuran gambar asli

Mis-feautres:

  • lambat
  • pada batasan ruang ini hanya mempertahankan skema warna dasar dari gambar awal dan garis besar umum beberapa fitur darinya.

Ini contoh twit yang mewakili Lena: 犭 楊 谷 杌 蒝 螦 界 玏 扝 匮 匮 归 晃 摈 摈 摈 硰 硰 刀 萕 萕 萕 嘁 嚎 嚎 耂 澹 澹 內 內 凁 梡 倨 梡 梡 梡 梡 梡 倨 倨 倨 梡 梡 襠 襠 襠岂 掂 戇 耔 攋 斘 眐 奡 萛 狂 昸 箆 亲 嬎 廙 栃 栃 塅 受 应 应 戞 戞 戞 猫 僘 僘 僘 卣 腠 腠 腠 綍 詬 詬 詬 來 嫐 帤 帤 帤 帤 帤 帤 帤 帤 帤 帤 帤 帤 罍 帤 帤 帤虲 兙 罨 縨 炘 排 叁 抠 堃 從 弅 慌 螎 熰 標 宑 宑 柢 橙 蜊 蜊 缩 缩 缩 儻 舭 舭 舭 囤 榕 榕 榕 兠 槃 槃 槃 姠 暬 枀 枀 枀 枀 枀 枀 枀 枀 枀 枀 枀 枀 眛 枀 枀 枀厇 廩 焛 瀻 严 啘 刱 垫 仔

lena asli Lena yang dikodekan

Kode ini ada dalam repositori Mercurial di bitbucket.org. Lihat http://bitbucket.org/tkadlubo/circles.lua

Tadeusz A. Kadłubowski
sumber
2
Luar biasa! Membuat gambar yang tampak rapi dan artistik. Saya senang orang masih mengerjakan ini; sangat menyenangkan melihat semua pendekatan yang berbeda.
Brian Campbell
1
Saya ingin melihat ini digunakan sebagai overlay transparan pada aslinya, memberikan sesuatu seperti efek bokeh.
Nick Radford
19

Berikut ini adalah pendekatan saya untuk masalah ini dan saya harus mengakui bahwa ini adalah proyek yang cukup menarik untuk dikerjakan, itu jelas di luar bidang kerja normal saya dan telah memberi saya sesuatu yang baru untuk dipelajari.

Ide dasar di belakang saya adalah sebagai berikut:

  1. Turun-sampel gambar skala abu-abu sehingga ada total 16 warna yang berbeda
  2. Lakukan sebelumnya RLE pada gambar
  3. Kemas hasilnya ke dalam karakter UTF-16
  4. Lakukan sebelumnya RLE pada hasil yang dikemas untuk menghapus duplikasi karakter

Ternyata ini berhasil, tetapi hanya sampai batas tertentu seperti yang Anda lihat dari contoh gambar di bawah ini. Dalam hal output, yang berikut adalah tweet sampel, khusus untuk gambar Lena yang ditunjukkan dalam sampel.

乤 乤 万 乐 唂 伂 倂 倁 企 儂 2 企 倁 3 企 倁 2 企 伂 8 企 伂 8 企 伂 3 企 伂 5 企 倂 倃 倁 3 企 儁 企 2 伂 倃 5 企 企 3 企 企 倁 企 企 企 企 企伂 2 企 伂 5 企 倁 企 伂 쥹 皗 鞹 鐾 鐾 䦽 阹 럆 럆 椿 籫 籫 욶 욶 옷뎷 옷뎷 歩 歉 歉 歉 歉 㞳 獴 鏙 鏙 돗 돗 鍴 焻 焻 Ꮛ Ꮛ 䍼 䍼 䍼 䍼 䍼 䍼

Seperti yang Anda lihat, saya memang mencoba dan membatasi set karakter sedikit; Namun, saya mengalami masalah saat menyimpan data warna gambar. Selain itu, skema pengkodean ini juga cenderung membuang banyak bit data yang dapat digunakan untuk informasi gambar tambahan.

Dalam hal waktu menjalankan, untuk gambar kecil kodenya sangat cepat, sekitar 55 ms untuk sampel gambar yang disediakan, tetapi waktu memang meningkat dengan gambar yang lebih besar. Untuk gambar referensi Lena 512x512 waktu berjalan adalah 1182 ms. Saya harus mencatat bahwa peluangnya cukup bagus bahwa kode itu sendiri tidak terlalu dioptimalkan untuk kinerja (misalnya semuanya bekerja dengan Bitmap ) sehingga waktu dapat turun sedikit setelah beberapa refactoring.

Jangan sungkan menawarkan saran apa pun yang bisa saya lakukan dengan lebih baik atau apa yang mungkin salah dengan kode tersebut. Daftar lengkap waktu menjalankan dan output sampel dapat ditemukan di lokasi berikut: http://code-zen.info/twitterimage/

Perbarui Satu

Saya telah memperbarui kode RLE yang digunakan ketika mengompresi string tweet untuk melakukan tampilan dasar kembali dan jika demikian gunakan itu untuk output. Ini hanya berfungsi untuk pasangan nilai angka, tetapi ini memang menyimpan beberapa karakter data. Waktu berjalan kurang lebih sama dengan kualitas gambar, tetapi tweet cenderung sedikit lebih kecil. Saya akan memperbarui bagan di situs web saat saya menyelesaikan pengujian. Berikut ini adalah salah satu contoh tweet, sekali lagi untuk versi kecil Lena:

乤 乤 万 乐 唂 伂 倂 倁 企 儂 2 企 倁 3 企 倁 ウ 伂 8 企 伂 エ 伂 5 企 倂 倃 伂 伂 儁 伂 2 伂 倃 ガ 倁 ジ 倃 企 倁 伂 倁 倁 ス ス ス ス ス ス企 伂 쥹 皗 鞹 鐾 륶 䦽 阹 阹 럆 䧜 椿 릹 靭 靭 욶 옷뎷 歩 㰷 鑹 鑹 㞳 㞳 鞷 㬼 㬼 獴 獴 獴 祳 㭾 뤶 뤶 殞 焻 Ꮛ 䍼 䍼 䍼

Perbarui Dua

Pembaruan kecil lainnya, tapi saya memodifikasi kode untuk mengemas warna menjadi kelompok tiga dan bukan empat, ini menggunakan lebih banyak ruang, tetapi kecuali jika saya melewatkan sesuatu itu berarti bahwa karakter "aneh" tidak lagi muncul di mana warna data. Juga, saya memperbarui kompresi sedikit lagi sehingga sekarang dapat bertindak atas seluruh string yang bertentangan dengan hanya blok penghitungan warna. Saya masih menguji waktu menjalankan, tetapi mereka tampaknya ditingkatkan secara nominal; Namun, kualitas gambarnya masih sama. Berikut ini adalah versi terbaru dari tweet Lena:

2 乤 万 乐 唂 伂 倁 倁 企 儂 2 企 倁 3 企 倁 ウ 伂 8 企 伂 エ 伂 5 企 倂 倃 倃 伂 伂 儁 伂 2 倃 倃 ガ 倁 ジ 倃 企 企 伂 倁 倁 倁 ス ス ス 倁 倁企 伂 坹 坼 坶 坻 刾 啩 容 力 吹 婩 媷 劝 圿 咶 咶 妛 啭 婣 婣 婣 冷 冷 啫 凃 凃 凃 凃 媗 媗 媗 决 兴宗 屹 屹 屹 埫 喝 坤 坤 坤 坤 坤 坤 坤 坤 坤 坤 坤 坤 坤商 嗉 乃

StackOverflow Logo http://code-zen.info/twitterimage/images/stackoverflow-logo.bmp Cornell Box http://code-zen.info/twitterimage/images/cornell-box.bmp Lena http: // kode-zen .info / twitterimage / images / lena.bmp Mona Lisa http://code-zen.info/twitterimage/images/mona-lisa.bmp

Rob Z
sumber
1
Bagus, terima kasih untuk entri! Grayscale sebenarnya bekerja cukup baik untuk sebagian besar dari ini, meskipun Lena agak sulit untuk dibuat. Saya mencari sumber Anda tetapi mendapat 404; Bisakah Anda memastikan itu di atas sana?
Brian Campbell
Periksa sekarang, saya memperbarui situs sehingga Anda mungkin telah menangkap saya di antara pembaruan.
rjzii
Yap, saya bisa mengunduhnya sekarang. Sekarang tentu saja saya perlu mencari tahu apakah saya bisa mendapatkan Mono untuk mengkompilasinya.
Brian Campbell
Ya! Bekerja di bawah Mono, saya dikompilasi dengan "gmcs -r System.Drawing TwitterImage.cs Program.cs" dan dijalankan dengan "mono TwitterImage.exe menyandikan lena.png lena.txt"
Brian Campbell
Keren! Saya melakukan pengecekan ulang untuk memastikan bahwa perpustakaan yang saya gunakan terdaftar untuk Mono, tetapi saya belum benar-benar bekerja dengan Mono, jadi saya tidak yakin apakah mau atau tidak.
rjzii
15

Algoritma genetik yang ditulis Roger Alsing ini memiliki rasio kompresi yang baik, dengan mengorbankan waktu kompresi yang lama. Vektor verteks yang dihasilkan dapat dikompresi lebih lanjut menggunakan algoritma lossy atau lossless.

http://rogeralsing.com/2008/12/07/genetic-programming-evolution-of-mona-lisa/

Akan menjadi program yang menarik untuk diimplementasikan, tetapi saya akan melewatkannya.

CiscoIPPhone
sumber
12

Dalam tantangan asli, batas ukuran didefinisikan sebagai apa yang masih dapat Anda kirim oleh Twitter jika Anda menempelkan teks Anda di kotak teks mereka dan tekan "perbarui". Seperti yang beberapa orang perhatikan dengan benar, ini berbeda dari apa yang dapat Anda kirim sebagai pesan teks SMS dari ponsel Anda.

Apa yang tidak disebutkan secara eksplisit (tetapi apa aturan pribadi saya) adalah bahwa Anda harus dapat memilih pesan tweet di browser Anda, menyalinnya ke clipboard dan menempelkannya ke bidang input teks dari decoder Anda sehingga dapat menampilkannya. Tentu saja Anda juga bebas menyimpan pesan sebagai file teks dan membacanya kembali atau menulis alat yang mengakses Twitter API dan menyaring semua pesan yang tampak seperti kode gambar (spidol khusus siapa saja? Wink wink ). Tetapi aturannya adalah bahwa pesan tersebut harus melalui Twitter sebelum Anda diizinkan untuk memecahkan kode itu.

Semoga berhasil dengan 350 byte - Saya ragu Anda akan dapat menggunakannya.

Quasimondo
sumber
1
Ya, saya telah menambahkan rubrik penilaian yang menunjukkan bahwa pembatasan yang lebih ketat pada rangkaian karakter lebih disukai, tetapi tidak diperlukan. Saya ingin memiliki aturan yang mengharuskan pesan melewati Twitter tanpa cedera, tetapi itu akan membutuhkan banyak percobaan dan kesalahan untuk mengetahui detail yang tepat dari apa yang berhasil, dan saya ingin meninggalkan beberapa kelonggaran untuk memungkinkan penggunaan kreatif dari ruang kode. Jadi, satu-satunya persyaratan dalam tantangan saya adalah 140 karakter Unicode yang valid. Ngomong-ngomong, terima kasih sudah mampir! Saya sangat menyukai solusi Anda, dan ingin melihat apakah ada kibitz yang benar-benar dapat memperbaikinya.
Brian Campbell
12

Memposting gambar Monochrome atau Greyscale akan meningkatkan ukuran gambar yang dapat dikodekan ke dalam ruang tersebut karena Anda tidak peduli dengan warna.

Mungkin menambah tantangan untuk mengunggah tiga gambar yang ketika digabungkan kembali memberi Anda gambar penuh warna sambil tetap mempertahankan versi monokrom di setiap gambar yang terpisah.

Tambahkan beberapa kompresi ke atas dan Itu bisa mulai terlihat layak ...

Bagus!!! Sekarang kalian menggelitik minat saya. Tidak ada pekerjaan yang akan dilakukan untuk sisa hari itu ...

Gineer
sumber
9
s / peaked / piqued / g
eleven81
1
Saya suka ide tiga gambar, harus mungkin menerapkan ide seperti itu ke twitter dan hasilnya akan cukup bagus.
Makis
9

Mengenai bagian encoding / decoding dari tantangan ini. base16b.org adalah usaha saya untuk menentukan metode standar untuk pengkodean data biner yang aman dan efisien di pesawat Unicode yang lebih tinggi.

Beberapa fitur:

  • Hanya menggunakan Area Pengguna Pribadi Unicode
  • Mengkodekan hingga 17 bit per karakter; hampir tiga kali lebih efisien daripada Base64
  • Referensi implementasi Javascript dari encode / decode disediakan
  • Beberapa pengkodean sampel disertakan, termasuk Twitter dan Wordpress

Maaf, jawaban ini datang terlambat untuk kompetisi awal. Saya memulai proyek secara independen dari posting ini, yang saya temukan setengah jalan ke dalamnya.


sumber
8

Gagasan menyimpan banyak gambar referensi menarik. Apakah akan sangat salah untuk menyimpan katakan 25 MB sampel gambar, dan minta pembuat enkode mencoba dan menyusun gambar menggunakan bit-bit itu? Dengan pipa yang sangat kecil, mesin di kedua ujungnya dengan kebutuhan akan jauh lebih besar daripada volume data yang melewati, jadi apa perbedaan antara 25Mb kode, dan 1Mb kode dan 24Mb data gambar?

(perhatikan pedoman asli mengesampingkan membatasi input ke gambar yang sudah ada di perpustakaan - saya tidak menyarankan itu).


sumber
1
Itu akan baik-baik saja, selama Anda memiliki jumlah data yang tetap dan terbatas di kedua titik akhir. Tentu saja, Anda perlu menunjukkan bahwa itu bekerja dengan gambar yang tidak ada dalam set pelatihan, seperti halnya masalah proses bahasa alami statistik. Saya ingin melihat sesuatu yang menggunakan pendekatan statistik untuk pengkodean gambar.
Brian Campbell
16
Saya, untuk satu, akan senang melihat Mona Lisa redone hanya menggunakan Boba Fett fan art sebagai sumber.
Nosredna
Saya setuju - pendekatan photomosaic tampaknya berada dalam aturan & akan sangat menarik untuk melihat seseorang menikam.
An̲̳̳drew
8

Gagasan bodoh, tetapi sha1(my_image)akan menghasilkan representasi "sempurna" dari gambar apa pun (mengabaikan tabrakan). Masalah yang jelas adalah proses decoding membutuhkan jumlah brute-forcing yang berlebihan.

Monokrom 1-bit akan sedikit lebih mudah .. Setiap piksel menjadi 1 atau 0, sehingga Anda akan memiliki 1000 bit data untuk gambar 100 * 100 piksel. Karena hash SHA1 adalah 41 karakter, kita dapat memasukkan tiga menjadi satu pesan, hanya perlu mengubah 2 set 3333 bit dan satu set 3334 (walaupun itu mungkin masih banyak)

Ini tidak sepenuhnya praktis. Bahkan dengan gambar 1-bit 100 * 100px panjang tetap ada .., dengan asumsi saya tidak salah perhitungan, 4.9995.000 kombinasi, atau 16661667 ketika dipecah menjadi tiga.

def fact(maxu):
        ttl=1
        for i in range(1,maxu+1):
                ttl=ttl*i
        return ttl

def combi(setsize, length):
    return fact(length) / (fact(setsize)*fact(length-setsize))

print (combi(2, 3333)*2) + combi(2, 3334)
# 16661667L
print combi(2, 10000)
# 49995000L
dbr
sumber
10
Masalah dengan sha1 (my_image) adalah bahwa jika Anda menghabiskan waktu dengan kasar memaksanya, Anda mungkin akan menemukan banyak tabrakan sebelum menemukan gambar asli; dan tentu saja memaksa kasar sha1 cukup banyak tidak layak secara komputasi.
Brian Campbell
5
Bahkan lebih baik daripada kompresi SHA1: algoritma kompresi "flickr" saya! Langkah 1: unggah gambar ke flickr. Langkah 2: memposting tautan di twitter. Tadda! Hanya 15 byte yang digunakan!
niXar
2
niXar: Tidak, aturan 3.4: "Proses decoding mungkin tidak memiliki akses ke output lain dari proses encoding selain output yang ditentukan di atas; yaitu, Anda tidak dapat mengunggah gambar di suatu tempat dan output URL untuk proses decoding untuk unduh, atau yang konyol seperti itu. "
dbr
6
Saya tahu, saya bersikap sarkastik.
niXar
0

Ide: Bisakah Anda menggunakan font sebagai palet? Cobalah untuk memecah gambar dalam serangkaian vektor yang mencoba menggambarkannya dengan kombinasi set vektor (setiap karakter pada dasarnya adalah serangkaian vektor). Ini menggunakan font sebagai kamus. Misalnya saya dapat menggunakan al untuk garis vertikal dan - untuk garis horizontal? Hanya sebuah ide.

Maurits
sumber