Twitter resim kodlama zorluğu [kapalı]


597

Bir resim 1000 kelimeye bedelse, 140 karaktere bir resmin ne kadarını sığdırabilirsiniz?

Not : Hepsi bu kadar! Ödül verme zamanı geldi ve bazı zorlu görüşmelerden sonra Boojum'un girişinin Sam Hocevar'ı zar zor kestiğine karar verdim . Yazma şansım olduğunda daha ayrıntılı notlar göndereceğim. Tabii ki, herkes çözüm sunmaya devam etmekte ve insanların oy kullanması için çözümleri geliştirmekten çekinmeyin. Gönderen ve giriş yapan herkese teşekkür ederim; Hepsinden keyif aldım. Bu benim için çok eğlenceli geçti ve umarım hem katılımcılar hem de seyirciler için eğlenceli olmuştur.

Görüntüleri bir Twitter yorumuna sıkıştırmaya çalışmakla ilgili bu ilginç gönderiyle karşılaştım ve bu iş parçacığında (ve Reddit'te bir iş parçacığında ) birçok kişinin bunu yapabileceğiniz farklı yollar hakkında önerileri vardı. Yani, iyi bir kodlama zorluğu yaratacağını düşünüyorum; insanların paralarını ağızlarına koymasına izin verin ve kodlama hakkındaki fikirlerinin, sahip olduğunuz sınırlı alanda nasıl daha fazla ayrıntıya yol açabileceğini gösterin.

Görüntüleri 140 karakterlik Twitter mesajlarına kodlamak ve tekrar bir görüntüye çözmek için genel bir amaç sistemi bulmanıza meydan okuyorum. Unicode karakterleri kullanabilirsiniz, böylece karakter başına 8 bitten fazla elde edersiniz. Bununla birlikte, Unicode karakterlere izin vermek bile, görüntüleri çok küçük bir alana sıkıştırmanız gerekir; bu kesinlikle kayıplı bir sıkıştırma olacaktır ve bu nedenle her sonucun ne kadar iyi göründüğü konusunda öznel yargılar olmalıdır.

Orijinal yazar Quasimondo'nun kodlamasından aldığı sonuç (resim bir Creative Commons Atıf-Ticari Olmayan lisansı altında lisanslanmıştır ): Mona Lisa

Daha iyisini yapabilir misin?

kurallar

  1. Programınızın iki modu olmalıdır: kodlama ve kod çözme .
  2. Tüm kodlayan :
    1. Programınız , seçtiğiniz herhangi bir makul raster grafik formatında bir grafik olarak girdi almalıdır . ImageMagick tarafından desteklenen herhangi bir raster biçiminin makul sayıldığını söyleyeceğiz .
    2. Programınız 140 veya daha az Unicode kod noktasında temsil edilebilecek bir mesaj vermelidir; Aralığında 140 kod noktaları U+0000- U+10FFFFhariç olmayan karakter ( U+FFFE, U+FFFF, U+nFFFE , U+n,FFFF burada n bir 1- 10onaltılı, ve aralık U+FDD0- U+FDEF) ve yedek kod noktaları ( U+D800- U+DFFF). Seçtiğiniz herhangi bir makul kodlamada çıktı alınabilir; GNUiconv tarafından desteklenen herhangi bir kodlama makul olarak kabul edilir ve platform yerel kodlaması veya yerel ayar kodlaması muhtemelen iyi bir seçim olacaktır. Daha fazla ayrıntı için aşağıdaki Unicode notlarına bakın.
  3. Kod çözme sırasında :
    1. Programınız kodlama modunuzun çıktısını girdi olarak almalıdır .
    2. Çıktı vektörü formatları için de uygun olsa da, programınızın yukarıda tanımlandığı gibi seçtiğiniz herhangi bir makul formatta bir görüntü vermesi gerekir.
    3. Görüntü çıkışı, giriş görüntüsünün yaklaşık bir değeri olmalıdır; giriş görüntüsüne ne kadar yakınlaşırsanız o kadar iyidir.
    4. Kod çözme işleminin, kodlama işleminin yukarıda belirtilen çıktıdan başka bir çıktısına erişimi olmayabilir; yani, görüntüyü bir yere yükleyemez ve kod çözme işleminin indirileceği URL'yi veya bunun gibi aptalca bir şeyi çıktılayamazsınız.
  4. Kullanıcı arayüzünde tutarlılık sağlamak için programınız aşağıdaki gibi davranmalıdır:

    1. Programınız, uygun yorumlayıcıya sahip bir platformda yürütülebilir olarak ayarlanabilen bir komut dosyası veya yürütülebilir bir dosyada derlenebilecek bir program olmalıdır.
    2. Programın ilk argümanı olarak ya encodeda decodemodu ayarlamak için alması gerekir .
    3. Programınız aşağıdaki yollardan bir veya daha fazlasını girmelidir (dosya adlarını alan dosyayı uygularsanız, dosya adları eksikse stdin ve stdout'tan da okuyabilir ve yazabilirsiniz):

      1. Standart girişten giriş alın ve standart çıkışta çıkış üretin.

        my-program encode <input.png >output.txt
        my-program decode <output.txt >output.png
        
      2. İkinci bağımsız değişkende adlandırılmış bir dosyadan girdi alın ve üçüncü bağımsız değişkende adlandırılmış dosyada çıktı üretin.

        my-program encode input.png output.txt
        my-program decode output.txt output.png
        
  5. Çözümünüz için lütfen gönderin:
    1. Kodunuz, tam olarak ve / veya başka bir yerde barındırılan bir bağlantı (çok uzunsa veya derlenmesi için çok sayıda dosya gerekiyorsa).
    2. Koddan hemen anlaşılmadıysa veya kod uzunsa ve insanlar bir özetle ilgilenecekse, nasıl çalıştığına dair bir açıklama.
    3. Orijinal görüntü, sıkıştırıldığı metin ve kod çözülmüş görüntü ile birlikte örnek bir görüntü.
    4. Başka birinin sahip olduğu bir fikir üzerine inşa ediyorsanız, lütfen bunları belirtin. It yolundaysa başkasının fikrine ait arıtımı yapmak denemek için, ama gerekir onları bağlıyor.

Kuralları

Bunlar temel olarak kırılabilecek kurallar, öneriler veya puanlama ölçütleridir:

  1. Estetik önemlidir. Yargılayacağım ve diğer insanların aşağıdakilere dayanarak yargılanmasını öneriyorum:
    1. Çıktı görüntüsünün ne kadar iyi göründüğü ve orijinaline ne kadar benzediği.
    2. Metin ne kadar güzel görünüyor. Gerçekten zekice bir sıkıştırma düzeniniz varsa tamamen rastgele gobbledigook tamam, ama aynı zamanda görüntüleri çok dilli şiirlere veya bunun gibi akıllı bir şeye dönüştüren cevapları görmek istiyorum. Orijinal çözümün yazarının sadece Çince karakterler kullanmaya karar verdiğine dikkat edin, çünkü bu daha hoş görünüyordu.
    3. İlginç kod ve akıllı algoritmalar her zaman iyidir. Kısa, açık ve net kod gibi, ama gerçekten zeki karmaşık algoritmalar iyi sonuçlar ürettikleri sürece de sorun yok.
  2. Hız da önemlidir, ancak yaptığınız görüntüyü sıkıştıran bir iş kadar iyi değildir. Genetik algoritmaları günlerce çalıştıracak bir şeyden bir saniyenin onda birinde bir görüntüyü dönüştürebilmeyi tercih ederim.
  3. Kalitesi makul düzeyde karşılaştırılabilir olduğu sürece daha uzun olanlara daha kısa çözümleri tercih edeceğim; özlülük bir erdemdir.
  4. Programınız, Mac OS X, Linux veya Windows üzerinde ücretsiz olarak kullanılabilen bir dilde uygulanmalıdır. Programları çalıştırabilmek istiyorum, ancak sadece MATLAB veya benzeri bir şeyle çalışan harika bir çözümünüz varsa , sorun değil.
  5. Programınız mümkün olduğunca genel olmalıdır; bazılarının diğerlerinden daha iyi sonuçlar vermesine rağmen, olabildiğince çok farklı görüntü için çalışmalıdır. Özellikle:
    1. Eşleşen ve bir referans yazdığı programa yerleştirilmiş birkaç görüntüye sahip olmak ve daha sonra kod çözme üzerine eşleşen görüntüyü üretmek, oldukça topaldır ve sadece birkaç görüntüyü kapsayacaktır.
    2. Basit, düz, geometrik şekillerin görüntülerini alıp bir vektör ilkeline ayırabilen bir program oldukça şıktır, ancak belirli bir karmaşıklığın ötesindeki görüntülerde başarısız olursa, muhtemelen yeterince geneldir.
    3. Sadece belirli bir sabit en boy oranına sahip görüntüler alabilen, ancak onlarla iyi iş yapan bir program da iyi olurdu, ancak ideal değildir.
    4. Siyah beyaz bir görüntünün, renkli bir görüntüden daha küçük bir alana daha fazla bilgi alabileceğini görebilirsiniz. Öte yandan, uygulanabilir olduğu görüntü türlerini sınırlayabilir; yüzler siyah beyaz olarak güzel çıkıyor, ancak soyut tasarımlar çok iyi sonuç vermeyebilir.
    5. Çıktı görüntüsünün girişten daha küçük olması ve kabaca aynı oranda olması mükemmeldir. Resmi orijinal ile karşılaştırmak için ölçeklendirmeniz gerekiyorsa sorun değil; önemli olan nasıl göründüğüdür.
  6. Programınız aslında Twitter üzerinden geçip yaralanmadan çıkabilecek çıktılar üretmelidir. Desteklenen karakter kümesiyle ilgili herhangi bir belge bulamadığım için bu kuraldan ziyade sadece bir kılavuzdur, ancak muhtemelen kontrol karakterlerinden, korkak görünmez birleştirme karakterlerinden, özel kullanım karakterlerinden ve benzerlerinden kaçınmalısınız.

Puanlama tablosu

Kabul edilen çözümümü seçerken çözümleri nasıl sıralayacağım konusunda genel bir rehber olarak, çözümleri 25 puanlık bir ölçekte değerlendireceğimizi söyleyelim (bu çok kaba ve hiçbir şeyi doğrudan puanlamayacağım, sadece kullanarak bu temel bir kılavuz olarak):

  • Kodlama şemasının çok çeşitli giriş görüntüleri ne kadar iyi oluşturduğuna dair 15 puan . Bu öznel, estetik bir yargı
    • 0 hiç işe yaramadığı, her seferinde aynı görüntüyü geri verdiği anlamına gelir
    • 5, kodu çözülmüş sürüm çirkin görünse de birkaç görüntüyü kodlayabileceği anlamına gelir ve daha karmaşık görüntülerde hiç çalışmayabilir
    • 10, çok çeşitli görüntüler üzerinde çalıştığı ve zaman zaman ayırt edilebilir olabilecek hoş görünümlü görüntüler ürettiği anlamına gelir
    • 15, bazı görüntülerin mükemmel kopyalarını ürettiği ve hatta daha büyük ve daha karmaşık görüntüler için bile tanınabilir bir şey verdiği anlamına gelir. Ya da, belki de oldukça tanınabilir olan görüntüleri yapmaz, ancak orijinalden açıkça türetilen güzel görüntüler üretir.
  • Unicode karakter setinin akıllı kullanımı için 3 puan
    • İzin verilen karakter kümesinin tamamını kullanmak için 0 puan
    • Twitter üzerinden veya daha çeşitli durumlarda aktarım için güvenli olan sınırlı bir karakter kümesi kullanmak için 1 puan
    • Yalnızca Han ideografları veya yalnızca sağdan sola karakterler gibi tematik bir karakter alt kümesi kullanmak için 2 nokta
    • Okunabilir metin oluşturmak veya söz konusu resme benzeyen karakterler kullanmak gibi gerçekten düzgün bir şey yapmak için 3 puan
  • Akıllı algoritmik yaklaşımlar ve kod stili için 3 puan
    • Görüntüyü küçültmek, piksel başına 1 bit olarak işlemek ve base64 kodlamak için 1000 satır kodlu bir şey için 0 puan
    • Standart bir kodlama tekniği kullanan ve iyi yazılmış ve kısa olan bir şey için 1 puan
    • Nispeten yeni bir kodlama tekniği tanıtan veya şaşırtıcı derecede kısa ve temiz bir şey için 2 puan
    • Gerçekten iyi sonuçlar veren bir astar için 3 puan veya grafik kodlamada yeni bir çığır açan bir şey için (bu, yeni bir zemini kırmak için az sayıda puan gibi görünüyorsa, bu iyi bir sonucun muhtemelen estetik için yüksek bir puan alacağını unutmayın. de)
  • Hız için 2 puan . Diğer her şey eşit, daha hızlı daha iyidir, ancak yukarıdaki kriterler hızdan daha önemlidir
  • Özgür yazılımı tercih ettiğim için 1 puan , çünkü özgür yazılımı tercih ediyorum (C # 'in Mono üzerinde çalıştığı sürece hala bu nokta için uygun olacağını unutmayın, aynı şekilde MATLAB kodu GNU Octave üzerinde çalışıyorsa da uygun olacaktır)
  • Tüm kuralları takip etmek için 1 puan . Bu kurallar biraz büyük ve karmaşık hale geldi, bu yüzden muhtemelen küçük bir detayı yanlış yapan iyi cevapları kabul edeceğim, ancak aslında tüm kuralları takip eden herhangi bir çözüme ekstra bir puan vereceğim.

Referans resimler

Bazı insanlar bazı referans resimler istediler. İşte deneyebileceğiniz birkaç referans görüntüsü; daha küçük sürümler burada gömülüdür, hepsi ihtiyacınız varsa görüntünün daha büyük sürümlerine bağlanır:

Lena Mona Lisa Cornell Kutusu Logo akışı

Ödül

Ben yukarıdaki kriterler temelinde, en iyi sevdiğim çözüm için 500 rep lütuf (artı 50 StackOverflow başladı). Tabii ki, burada da herkesi favori çözümlerine oy vermeye teşvik ediyorum.

Son başvuru tarihi ile ilgili not

Bu yarışma ödül bitene kadar devam edecek, 30 Mayıs Cumartesi günü 18.00 civarında. Kesin zamanın biteceğini söyleyemem; 17: 00-17: 00 arasında herhangi bir yerde olabilir. 2 PM tarafından gönderilen tüm kayıtlara bakacağımı garanti edeceğim ve 16 PM tarafından gönderilen tüm kayıtlara bakmak için elimden geleni yapacağım; bundan sonra çözümler sunulursa, kararımı vermeden önce onlara adil bir göz atma şansım olmayabilir. Ayrıca, ne kadar erken gönderirseniz, en iyi çözümü seçmeme yardımcı olmak için oylama şansınız o kadar artar, bu yüzden son teslim tarihine kadar değil, daha erken göndermeyi deneyin.

Unicode notları

Unicode karakterlerin tam olarak hangi karakterlere izin verildiği konusunda da karışıklıklar oldu. Mümkün Unicode kod noktalarına aralığıdır U+0000için U+10FFFF. Herhangi bir açık veri alışverişinde Unicode karakter olarak hiçbir zaman geçerli olmayan bazı kod noktaları vardır; bunlar karakter olmayanlar ve yedek kod noktalarıdır . Noncharacters tanımlanan Unidode standart 5.1.0 Bölüm 16.7 değerleri olarak U+FFFE, U+FFFF, U+nFFFE , U+n,FFFF burada n bir 1- 10onaltılı, ve aralık U+FDD0-U+FDEF. Bu değerlerin uygulamaya özgü dahili kullanım için kullanılması amaçlanmıştır ve uyumlu uygulamalar bu karakterleri kendileri tarafından işlenen metinden çıkarabilir. Tanımlanan Vekil kod noktaları, The Unicode Standard 5.1.0 3.8 bölümüne olarak U+D800- U+DFFFUTF-16 temel Multilingual düzlemi ötesine karakter kodlaması için kullanılır; bu nedenle, bu kod noktalarını doğrudan UTF-16 kodlamasında temsil etmek imkansızdır ve bunları başka herhangi bir kodlamada kodlamak geçersizdir. Böylece, bu yarışma amacıyla, bir dizi herhangi bir fazla 140 Unicode kod noktaları dizisi görüntüleri kodlayan herhangi bir program sağlayacak U+0000- U+10FFFFyukarıda tarif edildiği gibi bütün noncharacters ve vekil çiftleri hariç.

Yalnızca atanmış karakterleri ve daha sonra atanmış karakterlerin akıllı alt kümelerini kullanan veya kullandıkları karakter kümesiyle ilginç bir şey kullanan daha iyi çözümleri tercih edeceğim . Atanan karakterlerin listesi için bkz. Unicode Karakter Veritabanı ; bazı karakterlerin doğrudan, bazıları ise yalnızca aralığın başlangıcı ve sonu olarak listelendiğini unutmayın. Ayrıca yedek kod noktalarının veritabanında listelendiğini, ancak yukarıda belirtildiği gibi yasaklandığını unutmayın. Çıkardığınız metni daha ilginç hale getirmek için karakterlerin belirli özelliklerinden yararlanmak istiyorsanız , adlandırılmış kod bloklarının listesi ve çeşitli karakter özellikleri gibi çeşitli karakter bilgileri veritabanları vardır..

Twitter destekledikleri karakter setini tam olarak belirtmediğinden, bazı karakterler fazladan sayıldığı veya belirli karakterler çıkarıldığı için aslında Twitter ile çalışmayan çözümlere karşı açık olacağım. Tüm kodlanmış çıkışların Twitter veya identi.ca gibi başka bir mikroblog servisi aracılığıyla zarar görmeden aktarılması tercih edilir, ancak zorunlu değildir . Twitter varlığının <,> ve & kodladığını ve dolayısıyla bunları sırasıyla 4, 4 ve 5 karakter olarak saydığını belirten bazı belgeler gördüm, ancak bunu kendim test etmedim ve JavaScript karakter sayacı görünmüyor onları bu şekilde saymak.

İpuçları ve Linkler

  • Kurallardaki geçerli Unicode karakterlerin tanımı biraz karmaşıktır. CJK Birleşik İdeograflar (U + 4E00 – U + 9FCF) gibi tek bir karakter bloğu seçmek daha kolay olabilir.
  • Görüntü manipülasyonunuz için ImageMagick veya Python Imaging Library gibi mevcut görüntü kitaplıklarını kullanabilirsiniz .
  • Unicode karakter kümesini ve çeşitli kodlamalarını anlamak için yardıma ihtiyacınız varsa, bu hızlı kılavuza veya Linux ve Unix'teki UTF-8 hakkındaki ayrıntılı SSS'ye bakın .
  • Çözümünüzü ne kadar erken alırsanız, ben (ve oy kullanan diğer insanlar) buna o kadar çok zaman ayırmak zorunda kalacaksınız. Geliştirirseniz çözümünüzü düzenleyebilirsiniz; Çözümlerime son baktığımda ödülümü en son sürüme dayandıracağım.
  • Ayrıştırmak ve yazmak için kolay bir görüntü formatı istiyorsanız (ve sadece mevcut bir formatı kullanmak istemiyorsanız), PPM formatını kullanmanızı öneririm . Çalışması çok kolay olan metin tabanlı bir biçimdir ve ImageMagick'i ona dönüştürmek için kullanabilirsiniz .

Yorumlarda yazdığım kurallar hakkında önerilerde bulunmaktan çekinmeyin; Eğer insanlar açıklığa ihtiyaç duyuyorlarsa veya çok fazla belirtilmişlerse kendilerini kesinlikle değiştirmeye hazırım.
Brian Campbell

6
Muhtemelen resmi bir sunucuya yüklemenin ve URL'yi yayınlamanın geçerli olmadığını söylemelisiniz.
Shay Erlichmen

2
@Shay Bunu daha önce söylemedim mi? "Kod çözme işleminin, kodlama işleminin yukarıda belirtilen çıktıdan başka herhangi bir çıktısına erişimi olmayabilir; başka bir deyişle, resmi bir yere yükleyemez ve kod çözme işleminin indirileceği URL'yi veya bunun gibi aptalca bir şeyi çıkaramazsınız. ."
Brian Campbell

1
@Konrad Rudolph Katılıyorum; Pratik açıdan "aptal" demek istemedim (açıkça, bu yarışma pratik açıdan aptalca), bu yarışma bağlamında "aptal" demek istedim. Bir URI kullanmak bilgi teorisi anlamında gerçekten bir sıkıştırma algoritması değildir, çünkü sadece alternatif bir kanal kullanmadan daha fazla bilgi aktarmanıza izin vermez. Kodlayıcıya ve kod çözücüye büyük bir görüntü veritabanı verebilir ve buna yalnızca sınırlı bir dizi resim üzerinde çalışan sıkıştırma diyebilirsiniz, ancak rastgele bir görüntüyü işlemeniz gerektiğini belirttim.
Brian Campbell

2
Karşılaştığım, yardımcı olabilecek birkaç bağlantı: şu andaki Unicode karakterlerinin açıklaması için azillionmonkeys.com/qed/unicode.html . UTF kodlamalarının tüm Unicode aralığını kodlayabilenler olduğunu unutmayın; UCS-4, Unicode'un bir üst kümesidir ve UCS-2 ve ASCII, alt kümelerdir. Sıkıştırma cephesinde, orijinal mesajla benzer bir teknik var, ancak 350 bayt yerine 1k'a izin veriyor olsa da: screamingduck.com/Article.php?ArticleID=46&Show=ABCE
Brian Campbell

Yanıtlar:


244

Tamam, işte benim: nanocrunch.cpp ve CMakeLists.txt dosyası CMake kullanarak oluşturmak için. Görüntü işlemenin çoğu için Magick ++ ImageMagick API'sine dayanır . Ayrıca dize kodlaması için bignum aritmetiği için GMP kütüphanesini gerektirir .

Çözümümü fraktal görüntü sıkıştırmasına dayanarak birkaç benzersiz bükülme ile oluşturdum. Temel fikir, görüntüyü çekmek, bir kopyayı% 50'ye küçültmek ve orijinal görüntüdeki çakışmayan bloklara benzeyen çeşitli yönlerde parçaları aramaktır. Bu aramaya çok kaba bir güç yaklaşımı gerektirir, ancak bu benim değişikliklerimi tanıtmayı kolaylaştırır.

İlk değişiklik, doksan derece dönüşlere ve döndürmelere bakmak yerine, programımın 45 derecelik yönelimleri de dikkate almasıdır. Her blok için bir bit daha, ancak görüntü kalitesine son derece yardımcı olur.

Diğer bir şey, her bloğun renk bileşenlerinin her biri için bir kontrast / parlaklık ayarı depolamanın çok pahalı olmasıdır. Bunun yerine, büyük miktarlarda renklendirilmiş (palette sadece 4 * 4 * 4 = 64 renk var) saklıyorum. Matematiksel olarak, bu, her renk için değişken bir parlaklığa ve sabit kontrast ayarına eşdeğerdir. Ne yazık ki, aynı zamanda renkleri çevirmek için olumsuz bir kontrast olmadığı anlamına gelir.

Her blok için konum, yön ve renk hesaplandıktan sonra bunu UTF-8 dizgisine kodlar. İlk olarak, blok tablosundaki verileri ve görüntü boyutunu temsil etmek için çok büyük bir bignum oluşturur. Buna yaklaşım Sam Hocevar'ın çözümüne benziyor - bir yarıçapı pozisyona göre değişen çok sayıda.

Daha sonra bunu, mevcut karakter kümesinin boyutu ne olursa olsun bir tabana dönüştürür. Varsayılan olarak, eklenmiş unicode karakter kümesini, eksi ve işareti, kontrol, birleştirme ve vekil ve özel karakterlerden daha az, eksi tam olarak kullanır. Güzel değil ama işe yarıyor. Ayrıca varsayılan tabloyu yorumlayabilir ve bunun yerine yazdırılabilir 7 bitlik ASCII'yi (yine <,> ve & karakterler hariç) veya CJK Birleştirilmiş İdeografları seçebilirsiniz. Karakter kodlarının bulunduğu tablo, geçersiz ve geçerli karakterlerin dönüşümlü çalışmalarıyla kodlanmış bir çalışma uzunluğu saklanır.

Her neyse, bazı görüntüler ve süreler (eski 3.0GHz P4'ümde ölçüldüğü gibi) ve yukarıda açıklanan tam atanmış unicode kümesinde 140 karaktere sıkıştırılmış. Genel olarak, hepsinin nasıl ortaya çıktığı ile oldukça memnunum. Bunun üzerinde çalışmak için daha fazla zamanım olsaydı, muhtemelen sıkıştırılmış görüntülerin tıkanıklığını azaltmaya çalışırdım. Yine de, sonuçların aşırı sıkıştırma oranı için oldukça iyi olduğunu düşünüyorum. Açılmış görüntüler biraz izlenimci, ama bitlerin orijinaline nasıl karşılık geldiğini görmenin nispeten kolay olduğunu düşünüyorum.

Yığın Taşması Logosu (kodlanacak 8.6s, kod çözülecek 7.9s, 485 bayt):
http://i44.tinypic.com/2w7lok1.png

Lena (kodlanacak 32.8s, kod çözülecek 13.0s, 477 bayt):
http://i42.tinypic.com/2rr49wg.png http://i40.tinypic.com/2rhxxyu.png

Mona Lisa (kodlanacak 43.2s, kod çözülecek 14.5s, 490 bayt):
http://i41.tinypic.com/ekgwp3.png http://i43.tinypic.com/ngsxep.png

Düzenleme: CJK Birleştirilmiş Karakterler

Sam, bunu CJK ile kullanma hakkındaki yorumlarda sordu. Mona Lisa'nın CJK Unified karakter setinden 139 karaktere sıkıştırılmış bir versiyonu:

http://i43.tinypic.com/2yxgdfk.png 咏璘驞凄脒鵚据蛥鸂拗朐朖辿韩瀦魷歪痫栘璯緍脲蕜抱揎頻蓼債鑡嗞靊寞柮嚛嚵籥聚隤慛絖銓馿渫櫰矍昀鰛掾撄粂敽牙稉擎蔍螎葙峬覧絀蹔抆惫冧笻哜搀澐芯譶辍澮垝黟偞媄童竽梀韠镰猳閺狌而羶喙伆杇婣唆鐤諽鷍鴞駫搶毤埙誖萜愿旖鞰萗勹鈱哳垬濅鬒秀瞛洆认気狋異闥籴珵仾氙熜謋繴茴晋髭杍嚖熥勳縿餅珝爸擸萿

Bunun için kullandığım programın üstündeki ayar parametreleri şunlardı: 19, 19, 4, 4, 3, 10, 11, 1000, 1000. Ayrıca, number_assigned ve kodların ilk tanımını da yorumladım ve uncommented CJK Birleştirilmiş karakter kümesini seçmek için son tanımları.


Vaov! İyi iş. Bu kadar küçük görüntüler için fraktal görüntü sıkıştırma konusunda şüpheliydim, ama aslında oldukça iyi sonuçlar üretiyor. Derlemek ve çalıştırmak da oldukça kolaydı.
Brian Campbell

1
Teşekkürler beyler! Sam, sadece 140 CJK karakteriyle sonuç mu demek istediniz? Öyleyse, evet, üstteki sayıları ayarlamanız gerekir. Bit cinsinden son boyut log2 civarındadır (steps_in_x steps_in_y steps_in_red steps_in_green steps_in_blue) * blocks_in_x blocks_in_y + log2 ( maksimum_width maximum_height ).
Boojum

Düzenleme: Ben ilk log2 () dışında * 16 vardır. Bu olası yönelimler içindir.
Boojum

20
Bunu kullanan bir görüntüyü daha önce hiç kimse heyecanlandırdı mı?
dbr

288

görüntü dosyaları ve python kaynağı (sürüm 1 ve 2)

Sürüm 1 İşte ilk denemem. Ben giderken güncelleme yapacağım.

SO logosunu neredeyse kayıpsız 300 karaktere düşürdüm. Tekniğim SVG vektör sanatına dönüşüm kullanıyor, bu yüzden en iyi resim üzerinde çalışıyor. Aslında bir SVG kompresörüdür, yine de orijinal sanatın bir vektörizasyon aşamasından geçmesini gerektirir.

İlk denemem için PNG izlemesi için bir çevrimiçi hizmet kullandım, ancak potrace (açık kaynak) dahil olmak üzere bu kısmı işleyebilen çok sayıda ücretsiz ve özgür olmayan araç var .

Sonuçlar burada

Orijinal SO Logosu http://www.warriorhut.org/graphics/svg_to_unicode/so-logo.png Orijinal Kod Çözülmüş SO Logosu http://www.warriorhut.org/graphics/svg_to_unicode/so-logo-decoded.png Kodlamadan sonra ve şifre çözme

Karakterler : 300

Zaman : Ölçülmedi ancak pratik olarak anında (vektörizasyon / rasterleştirme adımları dahil değil)

Bir sonraki aşama, unicode karakter başına 4 sembol (SVG yol noktaları ve komutları) gömmek olacaktır. Şu anda python derlememin karakter başına çözünürlüğümü sınırlayan geniş karakter desteği UCS4 yok. Ayrıca, maksimum aralığı unicode ayrılmış aralığın 0xD800'ünün alt ucuyla sınırladım, ancak izin verilen karakterlerin bir listesini ve bunları önlemek için bir filtre oluşturduğumda, teorik olarak gerekli karakter sayısını 70-100 kadar düşük tutabilirim yukarıdaki logo.

Şu anda bu yöntemin bir sınırlaması, çıktı boyutunun sabit olmamasıdır. Vektörizasyondan sonra vektör düğümlerinin / noktalarının sayısına bağlıdır. Bu sınırın otomatikleştirilmesi, görüntünün pikselleştirilmesini (vektörlerin ana yararını kaldırır) veya istenen düğüm sayısına ulaşılana kadar (şu anda Inkscape'te manuel olarak yaptığım) yolların basitleştirme aşaması boyunca tekrarlanmasını gerektirir.

Versiyon 2

GÜNCELLEME : v2 artık rekabet edebilecek niteliktedir. değişiklikler:

  • Komut satırı kontrolü giriş / çıkış ve hata ayıklama
  • Normal ifade yerine SVG'yi işlemek için XML ayrıştırıcısını (lxml) kullanır
  • Unicode sembolü başına 2 yol parçası paketler
  • Dokümantasyon ve temizleme
  • Destek stili = "dolgu: renk" ve dolgu = "renk"
  • Belge genişliği / yüksekliği tek bir karakterde paketlenmiştir
  • Yol rengi tek karaktere paketlenmiştir
  • Renk sıkıştırma, renk başına 4 bit renk verisi atılarak ve onaltılık dönüştürme yoluyla bir karaktere paketlenerek elde edilir.

Karakterler : 133

Zaman : Birkaç saniye

v2 çözülmüş http://www.warriorhut.org/graphics/svg_to_unicode/so-logo-decoded-v2.png Kodlama ve kod çözme işleminden sonra (sürüm 2)

Gördüğünüz gibi bu sefer bazı eserler var. Yöntemin bir sınırlaması değil, dönüşümlerimin bir yerinde bir hata. Artefaktlar puanlar 0.0 - 127.0 aralığının dışına çıktığında meydana gelir ve onları sınırlama girişimlerim karışık bir başarı elde etti. Çözüm sadece görüntüyü küçültmektir, ancak çalışma yüzeyi veya grup matrisi yerine gerçek noktaları ölçeklendirmede sorun yaşadım ve şimdi ilgilenmek için çok yorgunum. Kısacası, puanlarınız desteklenen aralıktaysa genellikle çalışır.

Ortadaki kıvrımın, bağlı olduğu bir sapın diğer tarafına hareket eden bir saptan kaynaklandığına inanıyorum. Temelde noktalar ilk etapta birbirine çok yakın. Kaynak görüntü üzerinde sıkıştırmadan önce basitleştirilmiş bir filtre çalıştırmak bunu düzeltmeli ve bazı gereksiz karakterleri tıraş etmelidir.

GÜNCELLEME : Bu yöntem basit nesneler için iyidir, bu yüzden karmaşık yolları basitleştirmek ve gürültüyü azaltmak için bir yola ihtiyacım vardı. Bu görev için Inkscape'i kullandım . Inkscape kullanarak gereksiz yolları tımar etmek için biraz şansım vardı ama otomatikleştirmeyi denemek için zamanım olmadı. Yol sayısını azaltmak için Inkscape 'Basitleştir' işlevini kullanarak bazı örnek svgs yaptım.

Sadeleştirmek tamam ama bu birçok yolla yavaş olabilir.

otomatik izleme örneği http://www.warriorhut.org/graphics/svg_to_unicode/autotrace_16_color_manual_reduction.png cornell kutusu http://www.warriorhut.com/graphics/svg_to_unicode/cornell_box_simplified.png lena http://www.warhut.com/ /svg_to_unicode/lena_std_washed_autotrace.png

izlenen küçük resimler http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_autotrace.png

İşte bazı ultra düşük çözünürlüklü çekimler. Bazı akıllı yol sıkıştırmaları da gerekebilir, ancak bunlar 140 karakter sınırına daha yakın olacaktır.

bakımlı http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_groomed.png Basitleştirilmiş ve çürümüş.

trianglulated http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_triangulated.png Basitleştirilmiş, çürümüş ve üçgenlenmiş .

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

YUKARI: Otomatik izleme kullanarak basitleştirilmiş yollar .

Ne yazık ki ayrıştırıcım otomatik izleme çıktısını işlemiyor, bu yüzden noktaların nasıl kullanıldığını veya ne kadar basitleştirileceğini bilmiyorum, ne yazık ki son tarihten önce yazmak için çok az zaman var. Yine de, inkscape çıktısından ayrıştırmak çok daha kolay.


2
Mükemmel! İlk başta hem keskin kenarları hem de pürüzsüz alanları olan hibrit bir vektör çözümü oluşturmak istedim, ancak bir izleme kütüphanesi (kullanmak istemediğim) kullanmadan çok karmaşık olduğunu kanıtladım. Metodunuzla ne kadar ilerleyebileceğinizi görmek için sabırsızlanıyorum!
sam hocevar

Güzel! Vectorization ile neredeyse kayıpsız yaklaşımlar için bazı girişimler göreceğimizi umuyordum. Bu, genelliği daha düşük olduğu, ancak kapsadığı görüntüler için daha yüksek kalitede olduğu anlamına gelir. Vektörleştirme için bir çevrimiçi hizmet kullanmak iyidir. Boyutu daha da aşağı almakta iyi şanslar!
Brian Campbell

Görüntü sıkıştırma ve karakter kodlamayı iki farklı adım olarak düşünürdüm - Sam'in tekniği kodlama için en uygun gibi görünüyor ve kolayca bağımsız bir programa kurulabilir. Çözümünüzün benzersiz kısmına (yani sıkıştırma kısmı) odaklanarak ve sadece bir dizi bit çıkararak paranız için daha fazla patlama elde edersiniz.
Mark Ransom

70
Vay. Bu görüntüler gerçekten şık görünüyor.
Rinat Abdullin

199

Tam çözümümü şu adreste bulabilirsiniz: http://caca.zoy.org/wiki/img2twit . Aşağıdaki özelliklere sahiptir:

  • Makul sıkıştırma süresi (yüksek kalite için yaklaşık 1 dakika)
  • Hızlı dekompresyon (saniyenin bir kısmı)
  • Orijinal görüntü boyutunu korur (yalnızca en boy oranı değil)
  • İyi rekonstrüksiyon kalitesi (IMHO)
  • Mesaj uzunluğu ve karakter kümesi (ASCII, CJK, Semboller) çalışma zamanında seçilebilir
  • Mesaj uzunluğu ve karakter seti dekompresyon zamanında otomatik olarak algılanır
  • Çok verimli bilgi paketleme

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

蜥 秓 鋖 筷 聝 诿 缰 偺 腶 漷 庯 祩 皙 靊 谪 獜 岨 幻 寤 厎 趆 脘 搇 梄 踥 桻 理 戂 溥 欇 渹 裏 軱 骿 苸 髙 骟 市 簶 璨 粭 浧 鱉 捕 弫 潮 衍 蚙 瀹 岚玧 霫 鏓 蓕 戲 債 鼶 襋 躻 弯 袮 足 庭 侅 旍 凼 飙 驅 據 嘛 掔 倾 诗 籂 阉 嶹 婻 椿 糢 墤 渽 緛 赐 更 儅 棫 武 婩 縑 逡 荨 璙 杯 翉 珸 齸 陁 颗 鳣 憫擲 舥 攩 寉 鈶 兓 庭 璱 篂 鰀 乾 丕 耓 庁 錸 努 樀 肝 亖 弜 喆 蝞 躐 葌 熲 谎 蛪 曟 暙 刍 镶 媏 嘝 驌 慸 盂 氤 缰 殾 譑

Kodlama işlemine genel bir bakış:

  • Kullanılabilir bit sayısı istenen mesaj uzunluğundan ve kullanılabilir karakter kümesinden hesaplanır
  • Kaynak görüntü, mevcut bitlerin izin verdiği sayıda kare hücreye bölünür
  • Başlangıç ​​koordinatları ve renk değerleri ile her hücreye sabit sayıda nokta (şu anda 2) etkilenir
  • Bir kalite koşulu karşılanana kadar aşağıdakiler tekrarlanır:
    • Bir nokta rastgele seçilir
    • Bu noktada rastgele bir işlem gerçekleştirilir (hücresinin içinde hareket ettirilir, rengini değiştirir)
    • Ortaya çıkan görüntü (aşağıdaki kod çözme işlemine bakın) kaynak görüntüye daha yakınsa, işlem korunur
  • Görüntü boyutu ve nokta listesi UTF-8 olarak kodlanmıştır

Ve bu kod çözme işlemi:

  • Görüntü boyutu ve noktaları UTF-8 akışından okunur
  • Hedef görüntüdeki her piksel için:
    • Doğal komşuların listesi hesaplanır
    • Pikselin son rengi, doğal komşularının renklerinin ağırlıklı ortalaması olarak ayarlanır

Programın en orijinal kısmı bit akımı olduğuna inandığım şey. Bit hizalı değerleri ( stream <<= shift; stream |= value) paketlemek yerine, iki aralığın gücü ( stream *= range; stream += value) içinde olmayan rastgele değerler paketlerim . Bu bignum hesaplamaları gerektirir ve elbette çok daha yavaştır, ancak 20902 ana CJK karakterini kullanırken bana 1960.18 bit veriyor (bu veriye koyabileceğim üç nokta daha var). ASCII kullanırken, 840 yerine 917.64 bit veriyor.

İlk görüntü hesaplaması için ağır silahlar (köşe algılama, özellik çıkarma, renk nicemleme ...) gerektiren bir yönteme karar verdim çünkü ilk başta gerçekten yardımcı olacağından emin değildim. Şimdi yakınsamanın yavaş olduğunu fark ediyorum (1 dakika kabul edilebilir ama yine de yavaş) ve bunu geliştirmeye çalışabilirim.

Ana bağlantı halkası, Doğrudan İkili Arama renk taklidi algoritmasından gevşek bir şekilde esinlenmiştir (burada pikseller daha iyi bir yarı ton elde edilene kadar rastgele değiştirilir veya çevrilir). Enerji hesaplaması basit bir kök-ortalama-kare mesafedir, ancak önce orijinal görüntü üzerinde 5x5 medyan bir filtre gerçekleştiriyorum. Gauss bulanıklığı muhtemelen insan gözü davranışını daha iyi temsil eder, ancak keskin kenarları kaybetmek istemedim. Ayrıca, tavlamayı ya da ayarlaması zor diğer yöntemlere karşı karar verdim çünkü süreci kalibre edecek aylarım yok. Dolayısıyla, "kalite" bayrağı sadece kodlayıcı sona ermeden önce her bir noktada gerçekleştirilen yineleme sayısını temsil eder.

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

苉 憗 揣 嶕 繠 剳 腏 篮 濕 茝 霮 墧 蒆 棌 杚 蓳 縳 樟 赒 肴 飗 噹 砃 燋 任 朓 峂 釰 靂 陴 貜 犟 掝 喗 讄 荛 砙 矺 敨 鷾 瓔 亨 髎 芟 氲 簵 鸬 嫤 鉸 俇激 躙 憮 鄴 甮 槺 骳 佛 愚 猪 駪 惾 嫥 綖 珏 矯 坼 堭 颽 箽 赭 飉 訥 偁 箝 窂 蹻 熛 漧 衆 橼 愀 航 玴 毡 裋 頢 羔 恺 墎 嬔 鑹 楄 瑥 鶼 呍 蕖 抲 鸝 秓苾 绒 酯 嵞 脔 婺 污 囉 酼 俵 菛 琪 棺 则 辩 曚 鸸 職 銛 蒝 礭 鱚 蟺 稿 纡 醾 陴 鳣 尥 蟀 惘 鋁 髚 忩 祤 脤 养 趯 沅 况

Tüm görüntüler iyi sıkıştırılmasa da, sonuçlardan şaşırdım ve bir görüntüyü 250 bayta sıkıştırabilecek başka yöntemler olduğunu gerçekten merak ediyorum.

Ayrıca, enkoder durumunun gelişmesi hakkında rastgele bir başlangıç ​​durumundan ve "iyi" bir başlangıç ​​durumundan küçük filmlerim var .

Düzenleme : sıkıştırma yöntemi JPEG ile nasıl karşılaştırılır. Solda, jamoes'in 536 baytlık resmin üzerinde. Sağda, Mona Lisa burada açıklanan yöntemi kullanarak 534 bayta kadar sıkıştırdı (burada belirtilen baytlar veri baytlarına atıfta bulunur, bu nedenle Unicode karakterleri kullanılarak boşa harcanan bitleri yok sayılır):

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

Düzenleme : sadece CJK metnini görüntülerin en yeni sürümleriyle değiştirdi.


Aslında kodu çalıştırmak gerek yok (Ben kurallar değil, bir öneri olarak kurallar, çalıştırma hakkında bölümü koymak); Çalıştırmayı tercih ederim, ancak bunu daha çok oluşturduğunuz görüntülerin kalitesi, kod ve ilginç hileler veya algoritmalar hakkında değerlendireceğim. Çalıştırmak istiyorsam ve ana sistemime kurmak istemediğim veya kurmak istemediğim paketler gerektiriyorsa, bir Amazon EC2 örneğini önyükleyebilir ve yükleyebilirim. Büyük dağıtımlardan biri için paketlenmiş kütüphanelerle çalıştığınız sürece çalıştırabilmeliyim. CGAL'ı kullanmaktan çekinmeyin.
Brian Campbell

2
Tamam, işte benim çözümüm (kaynak kodu): caca.zoy.org/browser/libpipi/trunk/examples/img2twit.cpp Açıklama girişimim ve birkaç örnek caca.zoy.org/wiki/img2twit
sam hocevar

2
Çözümünü gerçekten seviyorum. İnsan gözü maviyi çok iyi çözemediğinden mavi kanala atanan değer sayısını azaltmayı denemelisiniz: nfggames.com/games/ntsc/visual.shtm ; bu, bazı renk bilgilerinin kaybolması pahasına daha fazla ayrıntıya sahip olmanızı sağlayacaktır. Ya da belki yeşile atar mısın?
rpetrich

5
İyi bir nokta. Bu fikrin birkaç varyasyonunu denedim (RANGE_X tanımından önce yorumlara bakın) ama çok iyice değil. Gördüğünüz gibi, 6 yerine 5 mavi değer kullanmak hatayı 7 yeşil değerden biraz daha az arttırdı. İkisini de tembellikten yapmayı denemedim. Sahip olduğum bir başka sorun da çok iyi bir hata fonksiyonumun olmaması. Şu anda iyi çalışan ∑ (∆r² + ∆g² + ∆b²) / 3 kullanıyorum. YUV'un Y bileşenine dayanarak physical (0.299∆r² + 0.587∆g² + 0.114∆b²) denedim (fiziksel bir gerekçe olmadan), ancak mavi hatalara karşı çok toleranslıydım. Bu konu hakkında yazılar bulmaya çalışacağım.
sam hocevar

2
@rpetrich: Programı, yeterli bit olduğu sürece r / g / b aralıklarını dinamik olarak artırması için değiştirdim. Bu, tüm bit akışında asla 13 bitten fazlasını boşa harcamamamızı sağlar (ancak pratikte genellikle 1 veya 2'dir). Ve görüntüler biraz daha iyi görünüyor.
sam hocevar

45

Aşağıdakiler resmi bir başvuru değildir, çünkü yazılımım belirtilen görev için hiçbir şekilde uyarlanmamıştır. DLI , genel amaçlı kayıplı görüntü kodekini optimize etmek olarak tanımlanabilir. Görüntü sıkıştırma için PSNR ve MS-SSIM kayıt tutucusu ve bu özel görev için nasıl çalıştığını görmenin ilginç olacağını düşündüm. Sağlanan referans Mona Lisa görüntüsünü kullandım ve 100x150'ye kadar ölçeklendirdim, sonra 344 bayta sıkıştırmak için DLI kullandım.

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

JPEG ve IMG2TWIT sıkıştırılmış örnekleriyle karşılaştırmak için, görüntüyü 534 bayta sıkıştırmak için DLI kullandım. JPEG 536 bayt ve IMG2TWIT 534 bayttır. Kolay karşılaştırma için görüntüler yaklaşık olarak aynı boyuta ölçeklendirilmiştir. JPEG soldaki resim, IMG2TWIT orta ve DLI ise doğru resim.

Karşılaştırma http://i42.tinypic.com/302yjdg.png

DLI görüntüsü bazı yüz özelliklerini, özellikle de ünlü gülümsemeyi korumayı başarıyor :).


6
Hata. Yukarıdakiler, ilk olarak gönderen Dennis Lee'ye yatırılmalıdır. Sadece görüntüleri satır içi gömmek ve Google tarafından bulduğum referansa bağlantı oluşturmak için düzenledim. Ve söylemeliyim ki, vay canına, sıkıştırmadan etkilendim. DLI sıkıştırmasını kontrol etmem gerekecek.
Brian Campbell

1
Bu arada, DLI yazarı "uzun işlem süresinden" bahsediyor. Yazılımını çalıştıramadığım için, bize kaba sıkıştırma süresi numaraları verebilir misiniz?
sam hocevar

1
Bir AMD Athlon64 2.4Ghz kullanarak, 100x150 Mona Lisa görüntüsünün sıkıştırılması 38 saniye ve dekompresyon 6 saniye sürer. Maksimum 251 bayta sıkıştırmak daha zordur, çıktı kalitesi önemli ölçüde azalır. Referans Mona Lisa görüntüsünü kullanarak, 60x91'e kadar ölçeklendirdim, sonra DLI'yı 243 bayta sıkıştırmak için kullandım (gitmeden 251'e en yakın). Bu çıktı i43.tinypic.com/2196m4g.png Bit hızı sadece% 50 azaltılmış olsa bile ayrıntı 534 bayt DLI'nın yakınında değil. Ancak görüntünün yapısı oldukça iyi korunmuştur.

1
250 baytlık sıkıştırılmış örnekleri karşılaştırmayı kolaylaştırmaya karar verdi. 243 bayt DLI büyütüldü ve IMG2TWIT numunesinin yanına yerleştirildi. Solda IMG2TWIT, sağda DLI. İşte i40.tinypic.com/30ndks6.png resmi

1
DLI, JPEG gibi bir kalite parametresi kullanır, bu nedenle hedef çıktı boyutu isteniyorsa deneme yanılma gerekir.

21

Çözümüme genel bir bakış:

  1. 140 utf8 karakterine sığdırabileceğiniz maksimum ham veri miktarını hesaplamakla başlıyorum.
    • (Orijinal web sitesinin twitter mesajlarını sakladığını iddia ettiği utf8 olduğunu varsayıyorum . Bu, utf16 için soran yukarıdaki sorun ifadesinden farklıdır.)
    • Bu utf8 sssini kullanarak , tek bir utf8 karakterinde kodlayabileceğiniz maksimum bit sayısının 31 bit olduğunu hesaplıyorum. Bunu yapmak için U-04000000 - U-7FFFFFFF aralığındaki tüm karakterleri kullanırdım. (1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx, 31 x var, bu nedenle 31 bite kadar kodlayabilirim).
    • 31 bitlik 140 karakter 4340 bittir. 524,5 elde etmek için bunu 8'e bölün ve 542 bayta düşürün .
    • (Kendimizi utf16 ile kısıtlarsak, karakter başına sadece 2 bayt depolayabiliriz, bu da 280 bayta eşit olur).
  2. Standart jpg sıkıştırmasını kullanarak görüntüyü sıkıştırın.
    • Görüntüyü yaklaşık 50x50 piksel olacak şekilde yeniden boyutlandırın, ardından devam etmeden mümkün olduğunca 542 bayta yakın bir görüntü elde edene kadar çeşitli sıkıştırma düzeylerinde sıkıştırmayı deneyin.
    • Bu, 536 bayta kadar sıkıştırılmış mona lisa'nın bir örneğidir .
  3. Sıkıştırılmış görüntünün ham bitlerini utf-8 karakterlerine kodlayın.
    • Her bir x'i aşağıdaki baytlarda değiştirin: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx, resimdeki bitlerle.
    • Bu bölüm muhtemelen kodun büyük çoğunluğunun yazılması gereken bölüm olacaktır, çünkü şu anda bunu yapan hiçbir şey yoktur.

Kod istediğini biliyorum, ama gerçekten bu kodu kodlamak için zaman harcamak istemiyorum. Verimli bir tasarımın en azından bunu kodlaması için bir başkasına ilham verebileceğini düşündüm.

Önerilen çözümümün en büyük yararı, mümkün olan en fazla teknolojiyi yeniden kullanmasıdır. İyi bir sıkıştırma algoritması yazmaya çalışmak eğlenceli olabilir, ancak daha yüksek bir matematik derecesine sahip insanlar tarafından yazılmış daha iyi bir algoritma olması garanti edilir.

Diğer bir önemli not ise, utf16'nın tercih edilen kodlama olduğuna karar verilirse, bu çözümün parçalanmasıdır. jpeg'ler 280 bayta kadar sıkıştırıldığında gerçekten çalışmaz. Yine de, bu özel sorun bildirimi için jpg'den daha iyi bir sıkıştırma algoritması olabilir.


Şu an işteyim ama eve geldiğimde bu çözümü kesinlikle uyguluyorum.
Paulo Santos

2
Deneyimden, UTF-16 gerçekten Twitter'ın karakter saydığı gibi görünüyor; BMP karakterleri 1, daha yüksek düzlem karakterleri 2 olarak sayılır. Belgelenmemiştir, ancak giriş kutusuna yazdığınızda JavaScript karakter sayaçları bu şekilde sayılır. Orijinal konudaki yorumlarda da belirtilmiştir. Sayaç bozuk olup olmadığını görmek için API üzerinden göndermeyi denemedim; öyleyse, gerçek kısıtlamalar için sorunu güncelleyeceğim. Bununla birlikte, kodlayabileceğiniz bu uzun dizilerin çoğu geçerli Unicode olmadığından, keyfi UTF-8'i kullanmanız olası değildir.
Brian Campbell

4
API'leriyle test ettikten sonra, UTF-16 kod birimleri yerine Unicode karakterleri (kod noktaları) ile sayıldıkları ortaya çıkıyor (görünüşe göre JavaScript uzunluk yönteminin yaptığı budur, çünkü UTF-16 ile sayılan JavaScript karakter sayacı) . Böylece orada biraz daha bilgi edinebilirsiniz; geçerli Unicode karakterler U + 0000 ile U + 10FFFF arasındadır (karakter başına 20 bitten biraz fazla; karakter başına 2 ^ 20 + 2 ^ 16 olası değer). UTF-8, Unicode'da izin verilenden daha fazla değerin kodlanmasına izin verir, bu nedenle kendinizi Unicode ile kısıtlarsanız, 542 değil, yaklaşık 350 bayt alan elde edebilirsiniz.
Brian Campbell

3
Bu 536 bayt mona lisa, aşırı sıkıştırma göz önüne alındığında şaşırtıcı derecede iyi görünüyor!
Chris

3
Şu anda 129,775 farklı (atanmış, kontrolsüz, özel olmayan) Unicode karakteri kodlayabiliriz. Kendimizi bu altkümeyle sınırlarsak, toplam 2377 bit veya 297 bayt olur. Kod burada: porg.es/blog/what-can-we-fit-in-140-characters
porges

20

Tamam, oyuna geç kaldım ama yine de projemi yaptım.

İlk görüntüyü yeniden oluşturmak için yarı saydam renkli daireler kullanan bir oyuncak genetik algoritmasıdır.

Özellikleri:

  • saf Lua. Lua yorumlayıcısının çalıştığı her yerde çalışır.
  • netpbm P3 biçimini kullanır
  • kapsamlı bir birim test paketi ile birlikte gelir
  • orijinal görüntü boyutunu korur

Mis-feautres:

  • yavaş
  • bu boşluk kısıtlamalarında, sadece ilk görüntünün temel renk şemasını ve birkaç özelliğinin genel bir taslağını korur.

İşte Lena'yı temsil eden bir örnek twit: 犭 楊 谷 杌 蒝 嚎 匘 澹 扝 簜 俄 晃 客 猘 摈 硰 刀 萕 码 摃 斢 蜁 義 倨 襠 凁 凁 凁岂 掂 戇 耔 攋 斘 眐 奡 萛 狂 昸 箆 亲 嬎 廙 栃 兡 塅 受 橯 恰 应 戞 优 猫 僘 瑩 吱 賾 卣 朸 杈 腠 綍 蝘 猕 屐 稱 悡 ​​詬 來 噩 压 罍 尕 熚 帤 厥 虤 嫐虲 兙 罨 縨 炘 排 叁 抠 堃 從 弅 慌 螎 熰 標 宑 簫 柢 橙 拃 丨 蜊 缩 昔 儻 舭 勵 癳 冂 囤 璟 彔 榕 兠 摈 侑 蒖 孂 埮 槃 姠 璐 哠 眛 嫡 琠 枀 訜 苄 暬厇 廩 焛 瀻 严 啘 刱 垫 仔

orijinal lena kodlanmış Lena

Kod bitbucket.org adresindeki bir Mercurial deposundadır. Check out http://bitbucket.org/tkadlubo/circles.lua


2
Müthiş! Düzgün, sanatsal görünümlü görüntüler oluşturur. İnsanlar hala bu konuda çalışıyorlar; tüm farklı yaklaşımları görmek çok eğlenceliydi.
Brian Campbell

1
Bunun orijinalin şeffaf bir kaplaması gibi kullanıldığını ve bokeh efekti gibi bir şey verdiğini görmek istiyorum.
Nick Radford

19

Aşağıdaki sorun benim yaklaşım ve itiraf etmeliyim ki bu üzerinde çalışmak için oldukça ilginç bir proje, kesinlikle normal çalışma alanı dışında olduğunu ve bana öğrenmek için yeni bir şey verdi.

Madenin arkasındaki temel fikir şöyledir:

  1. Toplam 16 farklı ton olacak şekilde görüntünün gri skalasını aşağı örnekleyin
  2. Resimde RLE'yi önceden biçimlendirin
  3. Sonuçları UTF-16 karakterlerine paketleme
  4. Karakter çoğalmasını kaldırmak için paketlenmiş sonuçlarda RLE oluşturun

Bunun işe yaradığı ortaya çıktı, ancak aşağıdaki örnek resimlerden görebileceğiniz gibi sınırlı bir ölçüde. Çıktı açısından, aşağıdaki örnek, özellikle örneklerde gösterilen Lena görüntüsü için bir örnek tweet'tir.

乤 乤 万 乐 唂 伂 倂 倁 企 儂 2 企 倁 3 企 倁 2 企 伂 8 企 伂 3 企 伂 5 企 倂 倃 伂 倁 3 企 儁 企 2 伂 倃 5 企 倁 3 企 倃 4 企 倂 企 倁 企伂 2 企 伂 5 企 倁 企 伂 쥹 皗 鞹 鐾 륶 䦽 阹 럆 䧜 椿 籫 릹 靭 욶 옷뎷 歩 㰷 歉 䴗 鑹 㞳 鞷 㬼 獴 鏙 돗 鍴 祳 㭾 뤶 殞 焻 乹 Ꮛ 靆 䍼

Gördüğünüz gibi, karakter setini biraz kısıtlamaya çalıştım; ancak, görüntü renk verilerini depolarken bunu yaparken sorunlar yaşadım. Ayrıca, bu kodlama şeması ayrıca ek görüntü bilgileri için kullanılabilecek bir grup veri parçasını boşa harcıyor.

Çalışma süreleri açısından, küçük görüntüler için kod son derece hızlıdır, sağlanan örnek görüntüler için yaklaşık 55 ms'dir, ancak daha büyük görüntülerde süre artar. 512x512 Lena referans görüntüsü için çalışma süresi 1182 ms'dir. Oranları kod kendisi performans için çok optimize olmadığını (örneğin her şey bir Bitmap olarak çalışılır ) oldukça iyi olduğunu unutmayın, böylece zamanlar bazı yeniden düzenleme sonra biraz aşağı gidebilir.

Daha iyi neler yapabileceğimi veya kodda neyin yanlış olabileceğini öğrenmek için lütfen bana herhangi bir öneri sunmaktan çekinmeyin. Çalışma sürelerinin ve örnek çıktıların tam listesi şu konumda bulunabilir: http://code-zen.info/twitterimage/

Bir Güncelleme

Temel bir geri bakmak için tweet dizesini sıkıştırırken kullanılan RLE kodunu güncelledim ve eğer öyleyse çıkış için kullanın. Bu yalnızca sayı değeri çiftleri için geçerlidir, ancak birkaç karakter verisi kaydeder. Çalışma süresi, görüntü kalitesinin yanı sıra aşağı yukarı aynıdır, ancak tweetler biraz daha küçük olma eğilimindedir. Testi tamamlarken web sitesindeki grafiği güncelleyeceğim. Aşağıda, Lena'nın küçük versiyonu için örnek tweet dizelerinden biri var:

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

İki Güncelleme

Başka bir küçük güncelleştirme, ancak kodu renk tonlarını dört grubun aksine üç gruba paketlemek için değiştirdim, bu biraz daha fazla alan kullanıyor, ancak bir şey kaçırmadıkça "tek" karakterlerin artık rengin artık görünmediği anlamına gelmeli veridir. Ayrıca, sıkıştırmayı biraz daha güncelledim, böylece sadece renk sayım bloğunun aksine tüm dize üzerinde hareket edebilir. Ben hala çalışma sürelerini test ediyorum, ama onlar nominal olarak geliştirilmiş gibi görünüyor; ancak görüntü kalitesi hala aynı. Aşağıdakiler Lena tweet'in en yeni versiyonudur:

2 乤 万 乐 唂 伂 倂 倁 企 儂 2 企 倁 3 企 倁 ウ 伂 8 企 伂 エ 伂 5 企 倂 倃 伂 倁 グ 儁 企 2 伂 倃 ガ 倁 ジ 倃 4 企 倂 企 倁 企 伂 ツ 伂 ス 倁企 伂 坹 坼 坶 坻 刾 啩 容 力 吹 婩 媷 劝 圿 咶 坼 妛 啭 奩 嗆 婣 冷 咛 啫 凃 奉 佶 坍 均 喳 女 媗 决 兴宗 喓 夽 兴 唹 屹 冷 圶 埫 奫 唓 坤 喝 奎 似商 嗉 乃

StackOverflow Logosu http://code-zen.info/twitterimage/images/stackoverflow-logo.bmp Cornell Kutusu http://code-zen.info/twitterimage/images/cornell-box.bmp Lena http: // kod-zen .info / twitterimage / images / lena.bmp Mona Lisa http://code-zen.info/twitterimage/images/mona-lisa.bmp


1
Harika, giriş için teşekkürler! Gri tonlama aslında bunların çoğu için oldukça iyi çalışıyor, ancak Lena'nın yapımı biraz zor. Kaynağınızı arıyordum ama 404 aldım; orada olduğundan emin olabilir misin?
Brian Campbell

Şimdi tekrar kontrol edin, güncellemeleri arasında beni yakalamış olabileceğiniz için siteyi güncelliyordum.
rjzii

Evet, şimdi indirebilirim. Şimdi elbette Mono'yu derlemeye başlayıp başaramayacağımı bulmam gerekiyor.
Brian Campbell

Evet! Mono altında çalışır, "gmcs -r System.Drawing TwitterImage.cs Program.cs" ile derlenmiş ve "mono TwitterImage.exe kodlamak lena.png lena.txt" ile çalıştırın
Brian Campbell

Güzel! Kullandığım kütüphanelerin Mono için listelendiğinden emin olmak için iki kez kontrol ettim, ama aslında Mono ile henüz çalışmadım, bu yüzden emin olup olmayacağından emin değildim.
rjzii


12

Orijinal sınamada, boyut sınırı, metninizi metin kutularına yapıştırıp "güncelle" ye basarsanız Twitter'ın göndermenize izin verdiği şey olarak tanımlanır. Bazı insanlar doğru bir şekilde fark bu cep telefonunuzdan SMS kısa mesaj olarak gönderebilirsiniz ne farklıdır.

Açıkça belirtilmeyen şey (ancak kişisel kuralım neydi) tarayıcınızda tweetlenmiş mesajı seçebilmeniz, panoya kopyalayabilmeniz ve kod çözücünüzün bir metin giriş alanına yapıştırabilmenizdir. Elbette, mesajı bir metin dosyası olarak kaydedebilir ve tekrar okuyabilir veya Twitter API'sına erişen ve bir görüntü koduna benzeyen herhangi bir mesajı filtreleyen bir araç yazabilirsiniz (özel belirteçler? Göz kırpıyor ). Ancak kural, mesajın kodunu çözmenize izin verilmeden önce Twitter üzerinden geçmesi gerektiğidir.

350 bayt ile iyi şanslar - onlardan yararlanabileceğinizden şüpheliyim.


1
Evet, karakter setinde daha sıkı kısıtlamaların tercih edildiğini ancak gerekli olmadığını gösteren bir puanlama tablosu ekledim. Mesajların Twitter'dan yaralanmadan geçmesini gerektiren bir kurala sahip olmak isterim, ancak neyin işe yaradığının kesin ayrıntılarını anlamak için çok fazla deneme yanılma gerektirir ve yaratıcı kullanımlara izin vermek için biraz boşluk bırakmak istedim. kod alanı. Yani, zorluğumdaki tek gereksinim 140 geçerli Unicode karakter. Bu arada, uğradığın için teşekkürler! Çözümünüzü gerçekten çok seviyorum ve kibitzerlerden herhangi birinin gerçekten bunu geliştirip geliştiremeyeceğini görmek istiyorum.
Brian Campbell,

12

Tek Renkli veya Gri Tonlamalı bir görüntü yayınlamak, rengi umursamadığınız için o alana kodlanabilecek görüntünün boyutunu iyileştirmelidir.

Yeniden birleştirildiğinde size tam renkli bir görüntü veren ve her bir ayrı görüntüde tek renkli bir sürümü koruyan üç görüntü yükleme zorluğunu artırabilir.

Yukarıdakilere biraz sıkıştırma ekleyin ve uygulanabilir görünmeye başlayabilir ...

Güzel!!! Şimdi sizler ilgimi uyandırdınız. Günün geri kalanında hiçbir iş yapılmayacak ...


9
s / sivri / pike / g
eleven81

1
Üç görüntü fikrini seviyorum, twitter için böyle bir fikir uygulamak mümkün olmalı ve sonuç oldukça iyi olurdu.
Makis

9

Bu zorluğun kodlama / kod çözme kısmı ile ilgili olarak. base16b.org , daha yüksek Unicode düzlemlerinde ikili verileri güvenli ve verimli bir şekilde kodlamak için standart bir yöntem belirleme girişimimdir.

Bazı özellikler :

  • Sadece Unicode'nin Özel Kullanıcı Alanlarını kullanır
  • Karakter başına 17 bite kadar kodlama yapar; Base64'ten neredeyse üç kat daha verimli
  • Kodlama / kod çözmenin referans Javascript uygulaması sağlanmıştır
  • Twitter ve Wordpress dahil olmak üzere bazı örnek kodlamalar dahildir

Üzgünüz, bu cevap orijinal yarışma için çok geç geliyor. Projeye, yarı yolda keşfettiğim bu görevden bağımsız olarak başladım.


8

Bir grup referans görüntüsünü saklama fikri ilginçtir. 25Mb örnek görüntüleri depolamak ve enkoderin bunları kullanarak bir görüntü oluşturmasını denemek o kadar yanlış olur mu? Böyle küçük bir boru ile, her iki uçtaki makine zorunlu olarak geçen veri hacminden çok daha büyük olacaktır, bu yüzden 25Mb kod ile 1Mb kod ve 24Mb görüntü verisi arasındaki fark nedir?

(orijinal yönergelerin, kütüphanede bulunan görüntülerle girdilerin sınırlandırılmasını engellediğine dikkat edin - bunu önermiyorum).


1
Her iki uç noktada da sabit, sınırlı miktarda veriye sahip olduğunuz sürece bu iyi olur. Tabii ki, tıpkı herhangi bir istatistiksel doğal dil süreci problemi gibi, eğitim setinde olmayan görüntülerle çalıştığını göstermeniz gerekir. Görüntü kodlamaya istatistiksel olarak yaklaşan bir şey görmek isterim.
Brian Campbell

16
Birincisi, Mona Lisa'nın sadece Boba Fett fan sanatını kaynak olarak kullanarak yeniden yapıldığını görmek isterim.
Nosredna

Katılıyorum - fotomosaik yaklaşım kurallar içinde gibi görünüyor ve birinin bıçak attığını görmek çok ilginç olurdu.
An Maydrew

8

Aptalca bir fikir, ancak sha1(my_image)herhangi bir görüntünün "mükemmel" bir temsili ile sonuçlanır (çarpışmalar göz ardı edilir). Açık olan sorun, kod çözme işleminin aşırı miktarda kaba kuvvet gerektirmesidir.

1-bit monokrom biraz daha kolay olurdu .. Her piksel 1 veya 0 olur, böylece 100 * 100 piksel görüntü için 1000 bit veriye sahip olursunuz. SHA1 karması 41 karakter olduğundan, üç tanesini tek bir iletiye sığdırabiliriz, sadece 2 set 3333 bit ve bir set 3334 setini zorlamak zorundayız (bu muhtemelen hala normal olsa da)

Tam olarak pratik değil. Sabit uzunlukta 1-bit 100 * 100px görüntüde bile .., yanlış hesaplama yapmadığım varsayılarak, 49995000 kombinasyonları veya üçe ayrıldığında 16661667 var.

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

10
Sha1 (my_image) ile ilgili sorun, zamanınızı zorlamak için acele ederseniz, muhtemelen gerçek görüntüyü bulmadan önce birçok çarpışma bulacaksınız; ve tabii ki kaba zorlama sha1 neredeyse hesapsal olarak mümkün değildir.
Brian Campbell

5
SHA1 sıkıştırmasından bile daha iyi: "flickr" sıkıştırma algoritmam! 1.Adım: Flickr'a resim yükleyin. Adım 2: Twitter'da bir bağlantı yayınlayın. Tadda! Sadece 15 bayt kullanır!
niXar

2
niXar: Hayır, kural 3.4: "Kod çözme işleminin, kodlama işleminin yukarıda belirtilen çıktıdan başka bir çıktısına erişimi olmayabilir; başka bir deyişle, resmi bir yere yükleyemez ve kod çözme işleminin URL'sini indir, ya da bunun gibi aptalca bir şey. "
dbr

6
Biliyorum, alaycı davranıyordum.
niXar


0

Fikir: Yazı tipini palet olarak kullanabilir misiniz? Bir vektör kümesindeki bir görüntüyü, vektör kümelerinin bir kombinasyonu ile tanımlamaya çalışarak kırmaya çalışın (her karakter esas olarak bir vektör kümesidir). Yazı tipini sözlük olarak kullanıyor. Örneğin dikey bir çizgi için al ve yatay bir çizgi için - kullanabilir miyim? Sadece bir fikir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.