Проблема с кодировкой изображений Twitter

Если изображение стоит 1000 слов, сколько картинок вы можете вписать в 140 символов?

Примечание: Это люди! Крайний срок подачи жалобы здесь, и после некоторого жесткого обсуждения я решил, что запись Boojum едва ли вышла из Сэма Хосевара > . Я отправлю более подробные заметки, как только у меня будет возможность написать их. Разумеется, каждый должен свободно продолжать предлагать решения и улучшать решения для людей, на которых они могут голосовать. Спасибо всем, кто подал заявку; Мне понравилось все. Мне было очень весело работать, и я надеюсь, что это будет забавно как для абитуриентов, так и для зрителей.

Я встретил этот интересный пост о попытке сжимать изображения в комментарии Twitter и много людей в этом потоке (и thread on Reddit) предлагали разные способы, которыми вы могли бы это сделать. Итак, я полагаю, что это создаст хороший кодовый вызов; пусть люди вкладывают свои деньги туда, где есть их рот, и показывают, как их идеи о кодировании могут привести к более подробным сведениям в ограниченном пространстве, которое у вас есть.

Я призываю вас придумать систему общего назначения для кодирования изображений в 140-символьные сообщения Twitter и снова декодировать их в изображение. Вы можете использовать символы Unicode, поэтому вы получаете более 8 бит на символ. Однако, даже учитывая символы Unicode, вам нужно будет сжать изображения в очень маленькое пространство; это, безусловно, будет сжатием с потерями, и поэтому должны быть субъективные суждения о том, насколько хорош каждый результат.

Вот результат, который оригинал автора, Quasimondo, получен из его кодировки (изображение лицензируется под Лицензия Creative Commons Attribution-Noncommercial): Mona Lisa

Можете ли вы сделать лучше?

Правила

  • Ваша программа должна иметь два режима: кодирование и декодирование.
  • Когда кодировка:
    • Ваша программа должна принимать в качестве графического изображения в любом разумном растровом графическом формате по вашему выбору. Мы скажем, что любой растровый формат, поддерживаемый ImageMagick, считается разумным.
    • Ваша программа должна вывести сообщение, которое может быть представлено в 140 или менее кодов Unicode; 140 кодовых точек в диапазоне U+0000 - U+10FFFF, исключая несимволы (U+FFFE, U+FFFF, U+ n FFFE, U+ n FFFF, где n равно 1 - 10 шестнадцатеричный, а диапазон U+FDD0 - U+FDEF) и суррогатные коды (U+D800 - U+DFFF). Он может выводиться в любой разумной кодировке по вашему выбору; любая кодировка, поддерживаемая GNU iconv, будет считаться разумной, и ваша собственная кодировка или локальная кодировка вашей платформы, вероятно, будет хорошим выбором. Подробнее см. В Заметки Unicode ниже.
  • Когда декодирование:
    • Ваша программа должна принимать входные данные вашего режима кодирования.
    • Ваша программа должна выводить изображение в любом разумном формате по вашему выбору, как определено выше, хотя для выходных векторных форматов также хорошо.
    • Выход изображения должен быть приближением входного изображения; тем ближе вы можете добраться до входного изображения, тем лучше.
    • Процесс декодирования может не иметь доступа к какому-либо другому выходу процесса кодирования, кроме указанного выше; то есть вы не можете загрузить изображение где-нибудь и вывести URL-адрес для процесса декодирования для загрузки или что-то глупое.
  • Для обеспечения согласованности в пользовательском интерфейсе ваша программа должна вести себя следующим образом:

    • Ваша программа должна быть script, которая может быть установлена ​​на исполняемый файл на платформе с соответствующим интерпретатором или программой, которая может быть скомпилирована в исполняемый файл.
    • Ваша программа должна принимать в качестве первого аргумента либо encode, либо decode для установки режима.
    • Ваша программа должна вводить ввод одним или несколькими из следующих способов (если вы реализуете тот, который принимает имена файлов, вы также можете читать и писать из stdin и stdout, если имена файлов отсутствуют):

      • Взять входной сигнал от стандартного входа и произвести вывод на стандартном выходе.

        my-program encode <input.png >output.txt
        my-program decode <output.txt >output.png
        
      • Сделайте ввод из файла, названного во втором аргументе, и произведите вывод в файле, указанном в третьем.

        my-program encode input.png output.txt
        my-program decode output.txt output.png
        
  • Для вашего решения, пожалуйста, напишите:
    • Ваш код полностью и/или ссылка на него размещены в другом месте (если он очень длинный или требуется много файлов для компиляции или что-то еще).
    • Объяснение того, как это работает, если это не сразу видно из кода, или если код длинный, и люди будут заинтересованы в сводке.
    • Пример изображения с исходным изображением, сжатым текстом и декодированным изображением.
    • Если вы строите идею о том, что кто-то еще, укажите их. Это нормально, чтобы попытаться улучшить идею кого-то другого, но вы должны атрибуты.

Руководство

Это в основном правила, которые могут быть нарушены, предложения или критерии оценки:

  • Эстетика важна. Я буду судить и предлагаю, чтобы другие люди судили, основываясь на:
    • Как хорошо выглядит выходное изображение и насколько оно выглядит как оригинал.
    • Как хорошо выглядит текст. Полностью случайный gobbledigook в порядке, если у вас действительно умная схема сжатия, но я также хочу видеть ответы, которые превращают изображения в черепочные стихотворения или что-то умное. Обратите внимание, что автор оригинального решения решил использовать только китайских иероглифов, так как он выглядел лучше всего.
    • Интересный код и умные алгоритмы всегда хороши. Мне нравится коротко, по сути, и ясный код, но на самом деле умные сложные алгоритмы в порядке, пока они дают хорошие результаты.
  • Скорость также важна, хотя и не такая важная, как хорошая работа, сжимающая изображение, которое вы делаете. Я бы предпочел иметь программу, которая может преобразовать изображение в десятую часть секунды, чем что-то, что будет запускать генетические алгоритмы в течение нескольких дней подряд.
  • Я предпочел бы более короткие решения для более длинных, если они достаточно сопоставимы по качеству; краткость - это добродетель.
  • Ваша программа должна быть реализована на языке, который имеет свободно доступную реализацию в Mac OS X, Linux или Windows. Я хотел бы иметь возможность запускать программы, но если у вас есть отличное решение, которое работает только под MATLAB или что-то в этом роде хорошо.
  • Ваша программа должна быть как можно более общей; он должен работать как можно больше различных изображений, хотя некоторые из них могут давать лучшие результаты, чем другие. В частности:
    • Наличие нескольких изображений, встроенных в программу, которые соответствуют и записывают ссылку, а затем создает подходящее изображение при декодировании, является довольно хромым и будет охватывать только несколько изображений.
    • Программа, которая может принимать изображения простых, плоских геометрических фигур и декомпозировать их в некоторый векторный примитив, довольно изящна, но если она не удалась на изображениях, не зависящих от определенной сложности, это, вероятно, недостаточно общий.
    • Программа, которая может принимать только изображения определенного фиксированного соотношения сторон, но делает хорошую работу с ними, также будет в порядке, но не идеальна.
    • Вы можете обнаружить, что черно-белое изображение может получить больше информации в меньшем пространстве, чем цветное изображение. С другой стороны, это может ограничивать типы изображений, к которым оно применимо; лица выглядят прекрасно в черно-белом цвете, но абстрактные рисунки могут не так хорошо жить.
    • Совершенно нормально, если выходное изображение меньше ввода, при этом примерно такая же пропорция. Хорошо, если вам нужно масштабировать изображение, чтобы сравнить его с оригиналом; что важно, как это выглядит.
  • Ваша программа должна выводить результат, который действительно может пройти через Twitter и выйти невредимым. Это лишь правило, а не правило, поскольку я не мог найти документацию о точном наборе поддерживаемых символов, но вам, вероятно, следует избегать управляющих символов, фанки-невидимых сочетающихся символов, персонажей частного использования и т.п.

Оценка рубрики

Как общее руководство по тому, как я буду оценивать решения при выборе моего принятого решения, скажу, что я, вероятно, буду оценивать решения по 25-балльной шкале (это очень грубо, и я не буду ничего забивать напрямую, просто используя это как основное руководство):

  • 15 баллов за то, насколько хорошо схема кодирования воспроизводит широкий диапазон входных изображений. Это субъективное, эстетическое суждение
    • 0 означает, что он вообще не работает, он возвращает одно и то же изображение каждый раз или что-то
    • 5 означает, что он может кодировать несколько изображений, хотя декодированная версия выглядит уродливой и может вообще не работать на более сложных изображениях
    • 10 означает, что он работает с широким спектром изображений и создает приятные изображения, которые иногда могут быть различимы.
    • 15 означает, что он производит совершенные реплики некоторых изображений, и даже для более крупных и более сложных изображений дает то, что можно распознать. Или, возможно, это не делает изображения, которые являются вполне узнаваемыми, но создает красивые изображения, которые явно получены из оригинала.
  • 3 балла для умного использования набора символов Unicode
    • 0 баллов за простое использование всего набора допустимых символов
    • 1 балл за использование ограниченного набора символов, которые безопасны для передачи через Twitter или в более широком диапазоне ситуаций.
    • 2 точки для использования тематического подмножества символов, например, только идеографы Хан или только символы справа налево
    • 3 балла за то, что вы делаете что-то действительно аккуратное, например, генерируете читаемый текст или используете символы, которые выглядят как соответствующее изображение.
  • 3 балла для умных алгоритмических подходов и стиля кода
    • 0 баллов за то, что составляет 1000 строк кода, только для масштабирования изображения вниз, рассматривать его как 1 бит на пиксель, а base64 - кодирование, которое
    • 1 пункт для чего-то, что использует стандартную технику кодирования и хорошо написано и кратко
    • 2 пункта для чего-то, что вводит относительно новую технику кодирования, или это удивительно коротко и чисто.
    • 3 балла за один лайнер, который на самом деле дает хорошие результаты или что-то новое, что ломает новую почву в графическом кодировании (если это кажется небольшим количеством точек для взлома новой земли, помните, что результат, который, вероятно, будет иметь высокий уровень оценка для эстетики также)
  • 2 балла для скорости. При прочих равных условиях быстрее, но вышеприведенные критерии важнее скорости.
  • 1 балл для работы на бесплатном (с открытым исходным кодом) программном обеспечении, потому что я предпочитаю бесплатное программное обеспечение (обратите внимание, что С# по-прежнему будет иметь право на этот момент, пока он работает на Mono, аналогично код MATLAB иметь право, если он работает на GNU Octave)
  • 1 балл для фактического выполнения всех правил. Эти правила стали немного большими и сложными, поэтому я, вероятно, соглашусь с другими хорошими ответами, которые будут иметь небольшую деталь неправильно, но я дам дополнительный пункт любому решению, которое действительно соответствует всем правилам.

Обратные изображения

Некоторые люди попросили некоторые ссылочные изображения. Вот несколько эталонных изображений, которые вы можете попробовать. более мелкие версии встроены здесь, все они ссылаются на более крупные версии изображения, если вам это нужно:

Lena Mona Lisa Cornell Box StackOverflow Logo

Приз

Я предлагаю 500 rep bounty (плюс 50, которые StackOverflow делает) для решения, которое мне больше всего нравится, на основе вышеуказанных критериев. Конечно, я призываю всех остальных проголосовать за их любимые решения здесь.

Примечание о крайнем сроке

Этот конкурс будет проводиться до тех пор, пока в субботу, 30 мая, не начнется грандиозность, около 6 часов вечера. Я не могу сказать, какое точное время закончится; это может быть где угодно от 5 до 7 вечера. Я гарантирую, что рассмотрю все записи, представленные к 2 PM, и я сделаю все возможное, чтобы посмотреть все записи, представленные к 16:00; если решения будут представлены после этого, у меня может не быть возможности дать им честный взгляд, прежде чем я должен принять решение. Кроме того, чем раньше вы отправляете, тем больше у вас шансов на голосование, чтобы помочь мне выбрать наилучшее решение, поэтому постарайтесь представить более раннее, а не право в крайний срок.

Заметки Unicode

Также существует некоторая путаница в том, какие именно символы Unicode разрешены. Диапазон возможных кодовых точек Unicode составляет от U+0000 до U+10FFFF. Есть некоторые кодовые точки, которые никогда не действительны для использования в качестве символов Юникода при любом открытом обмене данными; это нехарактеры и суррогатные коды. Нехарактеры определяются в Unidode Standard 5.1.0, раздел 16.7как значения U+FFFE, U+FFFF, U+ n FFFE, U+ n FFFF, где n равно 1 - 10 шестнадцатеричный, а диапазон U+FDD0 - U+FDEF. Эти значения предназначены для использования для внутреннего использования приложения, и соответствующие приложения могут лишать эти символы из обработанного ими текста. Суррогатные кодовые точки, определенные в Unicode Standard 5.1.0, раздел 3.8 как U+D800 - U+DFFF, используются для кодирования символов за пределами Основная многоязычная плоскость в UTF-16; таким образом, невозможно представить эти кодовые точки непосредственно в кодировке UTF-16, и недопустимо кодировать их в любом другом кодировании. Таким образом, для целей этого конкурса я разрешу любую программу, которая кодирует изображения в последовательности не более 140 кодов Unicode из диапазона U+0000 - U+10FFFF, исключая все нехарактеры и суррогатные пары, как определено выше.

Я предпочитаю решения, которые используют только назначенные символы, и даже лучшие, которые используют умные подмножества назначенных символов или делают что-то интересное с набором символов, который они используют. Список назначенных символов см. В Unicode Character Database; обратите внимание, что некоторые символы перечислены непосредственно, а некоторые перечислены только как начало и конец диапазона. Также обратите внимание, что суррогатные коды указаны в базе данных, но запрещены, как указано выше. Если вы хотите использовать некоторые свойства символов для получения более интересного текста, вы можете найти множество баз данных символьной информации доступный, например список именованных кодовых блоков и различные свойства символов.

Так как Twitter не указывает точный набор символов, который они поддерживают, я буду снисходителен к решениям, которые на самом деле не работают с Twitter, потому что некоторые персонажи подсчитывают лишние или некоторые персонажи лишаются. Предпочтительно, но не обязательно, чтобы все закодированные выходные данные могли быть перенесены без обращения через Twitter или другую службу микроблогов, например identi.ca. Я видел некоторую документацию, в которой говорится о том, что объект-кодировщик Twitter <, > , и &, и, следовательно, считает их 4, 4 и 5 символами соответственно, но я не проверял это самостоятельно, и их счетчик символов JavaScript не работает Кажется, они так считают.

Советы и ссылки

  • Определение правильных символов Юникода в правилах немного сложнее. Выбор одного блока символов, например унифицированных идеографов CJK (U + 4E00-U + 9FCF), может быть проще.
  • Вы можете использовать существующие библиотеки изображений, например ImageMagick или Библиотека изображений Python, для обработки изображений.
  • Если вам нужна помощь в понимании набора символов Unicode и его различных кодировок, см. это краткое руководство или этот подробный FAQ по UTF-8 в Linux и Unix.
  • Чем раньше вы получите свое решение, тем больше времени мне придется (и другим людям голосовать). Вы можете отредактировать свое решение, если вы его улучшите; Я буду основывать свою награду на последней версии, когда я рассмотрю последние решения.
  • Если вам нужен простой формат изображения для разбора и записи (и вы не хотите использовать только существующий формат), я бы предложил использовать PPM формат. Это текстовый формат, с которым очень легко работать, и вы можете использовать ImageMagick для преобразования в него и из него.

Ответ 1

Хорошо, здесь моя: nanocrunch.cpp и CMakeLists.txt для его создания с помощью CMake. Он полагается на Magick++ API ImageMagick для большей части обработки изображений. Он также требует библиотеку GMP для арифметики bignum для ее строковой кодировки.

Я основал свое решение от фрактального сжатия изображения, с несколькими уникальными завихрениями. Основная идея состоит в том, чтобы взять изображение, уменьшить копию до 50% и искать фрагменты в разных ориентациях, которые похожи на неперекрывающиеся блоки в исходном изображении. Для этого поиска требуется очень грубая сила, но это упрощает введение моих изменений.

Первая модификация заключается в том, что вместо того, чтобы просто смотреть на девяносто градусные вращения и сальто, моя программа также рассматривает 45-градусные ориентации. Это еще один бит за блок, но он очень помогает качеству изображения.

Другое дело, что сохранение регулировки контрастности/яркости для каждого из цветовых компонентов каждого блока слишком дорого. Вместо этого я храню сильно квантованный цвет (палитра имеет только 4 * 4 * 4 = 64 цвета), которая просто смешивается в некоторой пропорции. Математически это эквивалентно переменной яркости и постоянной настройке контрастности для каждого цвета. К сожалению, это также означает отсутствие отрицательного контраста для переворота цветов.

После вычисления позиции, ориентации и цвета для каждого блока он кодирует это в строку UTF-8. Во-первых, он генерирует очень большое значение для представления данных в таблице блоков и размера изображения. Подход к этому похож на решение Сэма Хочевара - вид большого числа с радиусом, который изменяется по положению.

Затем он преобразует это в базу любого размера набора символов. По умолчанию он в полной мере использует назначенный набор символов Юникода, минус меньше, больше, амперсанд, управление, объединение и суррогатное и личное персонажи. Это не очень, но это работает. Вы также можете прокомментировать таблицу по умолчанию и выбрать печатный 7-битный ASCII (опять же исключая <, > , и и символы) или унифицированные идеограммы CJK. Таблица, в которой имеются коды символов, хранится в кодировке с длиной пробега, чередующейся с недействительными и допустимыми символами.

В любом случае, вот некоторые изображения и время (как измерено на моем старом 3.0GHz P4) и сжаты до 140 символов в полном назначенном наборе unicode, описанном выше. В целом, я доволен тем, как все получилось. Если бы у меня было больше времени для работы над этим, я бы, вероятно, попытался уменьшить блокировку распакованных изображений. Тем не менее, я думаю, что результаты довольно хороши для экстремальной степени сжатия. Декомпрессированные изображения бит-импрессионистские, но я считаю, что относительно легко увидеть, как биты соответствуют оригиналу.

Логотип (8.6s для кодирования, 7.9s для декодирования, 485 байт):
so-logo.pnghttp://i44.tinypic.com/2w7lok1.png

Лена (32.8s для кодирования, 13.0s для декодирования, 477 байт):
http://i42.tinypic.com/2rr49wg.png http://i40.tinypic.com/2rhxxyu.png

Мона Лиза (43.2s для кодирования, 14.5s для декодирования, 490 байт):
http://i41.tinypic.com/ekgwp3.png http://i43.tinypic.com/ngsxep.png

Изменить: унифицированные символы CJK

Сэм спросил в комментариях об использовании этого с CJK. Здесь версия Mona Lisa сжата до 139 символов из набора символов CJK Unified:

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

Параметры настройки в верхней части программы, которые я использовал для этого, были: 19, 19, 4, 4, 3, 10, 11, 1000, 1000. Я также прокомментировал первое определение number_assigned и кодов и без комментирования последних определений их для выбора унифицированного набора символов CJK.

Ответ 2

файлы изображений и источник python (версии 1 и 2)

Версия 1 Вот моя первая попытка. Я обновлю, когда пойду.

У меня есть логотип SO до 300 символов, практически без потерь. Моя техника использует преобразование в векторное искусство SVG, поэтому она лучше всего работает в линейном искусстве. Это на самом деле компрессор SVG, он по-прежнему требует, чтобы оригинальное искусство проходило стадию векторизации.

Для моей первой попытки я использовал онлайн-службу для трассировки PNG, но есть МНОГИЕ бесплатные и несвободные инструменты, которые могут обрабатывать эту часть, включая potrace (с открытым исходным кодом).

Вот результаты

Оригинальный SO Logo http://www.warriorhut.org/graphics/svg_to_unicode/so-logo.png Оригинал Декодированный SO Logo http://www.warriorhut.org/graphics/svg_to_unicode/so-logo-decoded.png После кодирования и декодирования

Персонажи: 300

Время: не измеряется, но практически мгновенно (не включая шаги векторизации/растеризации)

Следующий этап будет состоять в том, чтобы вставить 4 символа (точки и команды пути SVG) для каждого символа Юникода. На данный момент моя сборка python не имеет широкой поддержки символов UCS4, которая ограничивает мое разрешение на символ. Я также ограничил максимальный диапазон для нижнего конца зарезервированного диапазона unicode 0xD800, однако, как только я создаю список допустимых символов и фильтр, чтобы избежать их, я теоретически могу указать необходимое количество символов как 70-100 для логотип выше.

Ограничение этого метода в настоящее время - размер выхода не фиксирован. Это зависит от количества векторных узлов/точек после векторизации. Автоматизация этого ограничения потребует либо пикселизации изображения (что устраняет основное преимущество векторов), либо повторного запуска путей через этап упрощения до тех пор, пока не будет достигнут желаемый счетчик node (который я сейчас делаю вручную в Inkscape).

Версия 2

ОБНОВЛЕНИЕ: v2 теперь имеет право конкурировать. Изменения:

  • Ввод/вывод команд командной строки и отладка
  • Использует парсер XML (lxml) для обработки SVG вместо регулярного выражения
  • Пакеты 2 сегмента пути для каждого символа Unicode
  • Документация и очистка
  • Поддержка style = "fill: color" и fill = "color"
  • Ширина документа/высота, упакованная в один символ
  • Цвет пути, упакованный в один символ
  • Сжатие цвета достигается выбрасывание 4 бит данных цвета за цвет, затем упаковывая его в символ через шестнадцатеричное преобразование.

Персонажи: 133

Время: несколько секунд

v2 decoded http://www.warriorhut.org/graphics/svg_to_unicode/so-logo-decoded-v2.png После кодирования и декодирования (версия 2)

Как вы можете видеть, на этот раз есть некоторые артефакты. Это не ограничение метода, а ошибка где-то в моих конверсиях. Артефакты происходят, когда точки выходят за пределы диапазона 0.0 - 127.0, и мои попытки ограничить их имели смешанный успех. Решение состоит в простом масштабировании изображения, однако у меня были проблемы с масштабированием фактических точек, а не с монтажной или групповой матрицей, и я слишком устал сейчас, чтобы позаботиться. Короче говоря, если ваши точки находятся в поддерживаемом диапазоне, он обычно работает.

Я считаю, что изгиб посередине связан с тем, что рукоятка перемещается к другой стороне рукоятки, к которой она привязана. В основном, точки находятся слишком близко друг к другу, в первую очередь. Запуск упрощенного фильтра по исходному изображению перед сжатием должен исправить это и сбрить некоторые ненужные символы.

UPDATE: Этот метод подходит для простых объектов, поэтому мне нужен способ упростить сложные пути и уменьшить шум. Для этой задачи я использовал Inkscape. Мне повезло, что у меня возникли ненужные пути с использованием Inkscape, но у меня не было времени попробовать его автоматизировать. Я сделал несколько примеров svgs, используя функцию Inkscape 'Simplify', чтобы уменьшить количество путей.

Упростите работу нормально, но это может быть медленным с помощью этого множества путей.

пример автотрассировки http://www.warriorhut.org/graphics/svg_to_unicode/autotrace_16_color_manual_reduction.png cornell box 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

трассированные эскизы http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_autotrace.png

Вот несколько снимков с низким разрешением. Они были бы ближе к пределу 140 символов, хотя может понадобиться некоторое умное сжатие пути.

ухоженный http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_groomed.png Упрощенный и оплодотворенный.

треугольный http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_triangulated.png Упрощенный, опресненный и триангулированный.

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

ВЫШЕ: Упрощенные пути с использованием autotrace.

К сожалению, мой синтаксический анализатор не обрабатывает вывод autotrace, поэтому я не знаю, как можно использовать точки и насколько их упростить, к сожалению, мало времени для написания до крайнего срока. Это намного проще разобрать, чем вывод inkscape.

Ответ 3

Мое полное решение можно найти на http://caca.zoy.org/wiki/img2twit. Он имеет следующие функции:

  • Разумное время сжатия (около 1 минуты для высокого качества)  
  • Быстрая декомпрессия (доля секунды)  
  • Сохраняет исходный размер изображения (а не только соотношение сторон)  
  • Достойное качество реконструкции (IMHO)  
  • Длина сообщения и набор символов (ASCII, CJK, Symbols) могут быть выбраны во время выполнения  
  • Длина сообщения и набор символов автоматически определяются во время декомпрессии  
  • Очень эффективная упаковка информации

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

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

Вот приблизительный обзор процесса кодирования:

  • Количество доступных бит вычисляется из требуемой длины сообщения и используемой кодировки
  • Исходное изображение сегментируется на столько квадратных ячеек, что доступные биты позволяют
  • На каждую ячейку влияет фиксированное количество точек (в настоящее время 2) с начальными координатами и значениями цвета
  • Повторяется следующее до тех пор, пока не будет выполнено условие качества:   
    • Точка выбирается случайным      
    • Операция выполняется случайным образом в этой точке (перемещая ее внутри своей ячейки, меняя ее цвет)      
    • Если полученное изображение (см. процесс декодирования ниже) ближе к исходному изображению, операция сохраняется  
  • Размер изображения и список точек кодируются в UTF-8

И это процесс декодирования:

  • Размер и точки изображения считываются из потока UTF-8
  • Для каждого пикселя в целевом изображении:   
    • Вычисляется список естественных neigbours      
    • Конечный цвет пикселя устанавливается как средневзвешенное значение цветов натуральных соседей

Я считаю, что самой оригинальной частью программы является бит-поток. Вместо того, чтобы упаковывать значения, выровненные по битам (stream <<= shift; stream |= value), я упаковываю произвольные значения, которые не входят в диапазоны мощности двух (stream *= range; stream += value). Для этого требуются вычисления бигнама и, конечно, намного медленнее, но он дает мне в 2009 году 18 бит вместо 1960 года при использовании основных символов CJK 20902 (что еще три точки могут помещать в данные). А при использовании ASCII он дает мне 917.64 бит вместо 840.

Я решил не использовать метод первоначального вычисления изображения, для которого потребовалось бы тяжелое вооружение (обнаружение углов, извлечение функции, квантование цвета...), потому что я не был уверен, что сначала это действительно поможет. Теперь я понимаю, что конвергенция медленная (1 минута приемлема, но тем не менее она медленная), и я могу попытаться улучшить это.

Основной контур фитинга слабо вдохновлен алгоритмом сглаживания прямого бинарного seach (где пиксели случайным образом меняются или переворачиваются до получения лучшего полутона). Вычисление энергии - это простое среднеквадратичное расстояние, но сначала я получаю срединный фильтр 5 × 5 на исходном изображении. Гауссовское размытие, вероятно, лучше отражает поведение человеческого глаза, но я не хочу терять острые края. Я также решил не моделировать отжиг или другие трудно настраиваемые методы, потому что у меня нет месяцев для калибровки процесса. Таким образом, флаг "качество" просто представляет количество итераций, которые выполняются в каждой точке до окончания кодирования.

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

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

Несмотря на то, что не все изображения хорошо сжимаются, меня удивляют результаты, и я действительно задаюсь вопросом, какие существуют другие методы, которые могут сжать изображение до 250 байтов.

У меня также есть небольшие фильмы об эволюции состояния энкодера из случайного начального состояния и из "хорошего" начального состояния.

Изменить: вот как метод сжатия сравнивается с JPEG. Слева - jamoes над изображением 536 байт. Справа Mona Lisa сжимается до 534 байт, используя описанный здесь метод (байты, упомянутые здесь, относятся к байтам данных, поэтому игнорирование битов впустую с использованием символов Unicode):

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

Изменить: только что заменил текст CJK на новейшие версии изображений.

Ответ 4

Ниже представлено не официальное представление, так как мое программное обеспечение никоим образом не предназначено для указанной задачи. DLI можно охарактеризовать как оптимизированный кодек изображений с потерями общего назначения. Это держатель записи PSNR и MS-SSIM для сжатия изображения, и я подумал, что было бы интересно посмотреть, как он работает для этой конкретной задачи. Я использовал предоставленное изображение ссылки Mona Lisa и уменьшил его до 100x150, затем использовал DLI, чтобы сжать его до 344 байт.

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

Для сравнения с сжатыми образцами JPEG и IMG2TWIT я использовал DLI для сжатия изображения до 534 байтов. JPEG составляет 536 байт, а IMG2TWIT - 534 байта. Для удобства сравнения изображения были увеличены до примерно одинакового размера. JPEG - это левое изображение, IMG2TWIT - центр, а DLI - правильное изображение.

Сравнение http://i42.tinypic.com/302yjdg.png

Изображение DLI позволяет сохранить некоторые черты лица, в первую очередь знаменитую улыбку:).

Ответ 5

Общий обзор моего решения:

  • Я начинаю с вычисления максимального количества необработанных данных, которые вы можете вписать в 140 символов utf8.
    • (Я предполагаю utf8, что и было в оригинальном сайте, в котором говорится, что твиттер хранит его сообщения. Это отличается от вышеприведенного описания проблемы, который запрашивает utf16.)
    • Используя этот utf8 faq, я рассчитываю, что максимальное количество бит, которое вы можете кодировать одним символом utf8, равно 31 бит. Чтобы сделать это, я использовал бы все символы, которые находятся в диапазоне U-04000000 - U-7FFFFFFF. (1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx, есть 31 x, поэтому я могу кодировать до 31 бит).
    • 31 бит раз 140 символов равно 4340 бит. Разделите это на 8, чтобы получить 524,5, и округлите до 542 байта.
    • (Если мы ограничимся utf16, тогда мы могли бы хранить только 2 байта на символ, что равно 280 байтам).
  • Сжатие изображения с помощью стандартного сжатия jpg.
    • Измените размер изображения примерно на 50x50 пикселей, а затем попытайтесь сжать его на разных уровнях сжатия, пока изображение не будет как можно ближе к 542 байтам, не пройдя.
    • Это пример mona lisa, сжатый до 536 байт.
  • Кодировать необработанные биты сжатого изображения в символы utf-8.
    • Заменить каждый x в следующих байтах: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx с битами изображения.
    • Эта часть, вероятно, будет частью, в которой большая часть кода должна быть написана, потому что в этом нет ничего, что в настоящее время существует.

Я знаю, что вы просили код, но я действительно не хочу тратить время на то, чтобы на самом деле закодировать это. Я подумал, что эффективный дизайн может по крайней мере вдохновить кого-то еще на то, чтобы закодировать это.

Я думаю, что основным преимуществом моего предлагаемого решения является то, что он повторно использует как можно больше существующих технологий. Может быть интересно попытаться написать хороший алгоритм сжатия, но гарантированно будет лучший алгоритм там, скорее всего, написанный людьми, у которых есть степень в высшей математике.

Еще одно важное замечание состоит в том, что если принято решение, что utf16 является предпочтительной кодировкой, то это решение разваливается. jpegs действительно не работают при сжатии до 280 байтов. Хотя, возможно, для этой конкретной задачи существует лучший алгоритм сжатия, чем jpg.

Ответ 6

Хорошо, я опаздываю на игру, но тем не менее я сделал свой проект.

Это генетический алгоритм игрушек, который использует полупрозрачные красочные круги для воссоздания исходного изображения.

Особенности:

  • чистый Lua. Работает везде, где работает интерпретатор Lua.
  • использует формат netpbm P3
  • поставляется с полным набором модульных тестов
  • сохраняет исходный размер изображения

Mis-feautres:

  • медленный
  • при этом ограничении пространства он сохраняет только базовую цветовую схему исходного изображения и общую схему нескольких ее функций.

Вот пример twit, который представляет Лену: 犭 楊 谷 杌 蒝 螦 界 匘 玏 扝 匮 俄 归 晃 客 猘 摈 硰 划 刀 萕 码 摃 斢 嘁 蜁 嚎 耂 澹 簜 僨 砠 偑 婊 內 團 揕 忈 義 倨 襠 凁 梡 岂 掂 戇 耔 攋 斘 眐 奡萛 狂 昸 箆 亲 嬎 廙 栃 兡 塅 受 橯 恰 应 戞 优 猫 僘 瑩 吱 賾 卣 朸 杈 腠 綍 蝘 猕 屐 稱 悡 ​​詬 來 噩 压 罍 尕 熚 帤 厥 虤 嫐 虲 兙 罨 縨 炘 排 叁 抠堃 從 弅 慌 螎 熰 標 宑 簫 柢 橙 拃 丨 蜊 缩 昔 儻 舭 勵 癳 冂 囤 璟 彔 榕 兠 摈 侑 蒖 孂 埮 槃 姠 璐 哠 眛 嫡 琠 枀 訜 苄 暬 厇 廩 焛 瀻 严 啘 刱 垫仔

original lenaencoded Lena

Код находится в репозитории Mercurial на bitbucket.org. Проверьте http://bitbucket.org/tkadlubo/circles.lua

Ответ 7

Ниже приведен мой подход к проблеме, и я должен признать, что это был довольно интересный проект, над которым он работал, он определенно находится за пределами моей обычной сферы работы и дал мне что-то новое, чтобы узнать о нем.

Основная идея моей заключается в следующем:

  • Вниз-образец изображения серого масштаба, чтобы было всего 16 разных оттенков.
  • Преформа RLE на изображении
  • Упакуйте результаты в символы UTF-16
  • Предварительно сформируйте RLE для упакованных результатов, чтобы удалить любое дублирование символов

Оказывается, что это работает, но только в ограниченной степени, как вы можете видеть из приведенных ниже образцов. Что касается вывода, то следует следующее тестовое твит, особенно для изображения Лены, показанного в образцах.

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

Как вы можете видеть, я попытался немного ограничить набор символов; однако я столкнулся с проблемами, возникающими при хранении данных цвета изображения. Кроме того, эта схема кодирования также имеет тенденцию тратить кучу бит данных, которые могут быть использованы для дополнительной информации изображения.

С точки зрения времени выполнения, для небольших изображений код очень быстрый, около 55 мс для предоставленных образцов изображений, но время увеличивается с большими изображениями. Для 512x512 Лена эталонного изображения, время работы было 1182ms. Я должен отметить, что шансы довольно хороши в том, что сам код не очень оптимизирован для производительности (например, все работает с Bitmap), поэтому время может немного пойдите после некоторого рефакторинга.

Пожалуйста, не стесняйтесь предлагать мне какие-либо предложения о том, что я мог бы сделать лучше или что может быть неправильным с кодом. Полный список времени выполнения и выборки можно найти по следующему адресу: http://code-zen.info/twitterimage/

Обновить

Я обновил код RLE, используемый при сжатии строки твита, чтобы сделать базовый внешний вид, и если это так, используйте это для вывода. Это работает только для пар чисел, но сохраняет несколько символов данных. Время работы более или менее такое же, как и качество изображения, но твиты, как правило, немного меньше. Я обновляю диаграмму на веб-сайте по мере завершения тестирования. Ниже следует одна из примеров твитовских строк, опять же для небольшой версии Лены:

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

Обновить два

Еще одно небольшое обновление, но я изменил код, чтобы упаковать оттенки цвета в группы по три, а не четыре, это использует еще немного места, но если я не пропущу что-то, это должно означать, что "нечетные" символы больше не появляются где данные цвета. Кроме того, я обновил сжатие немного больше, чтобы теперь он мог воздействовать на всю строку, а не только на блок подсчета цветов. Я все еще тестирую время выполнения, но они, как представляется, номинально улучшены; однако качество изображения остается прежним. Ниже приводится новейшая версия теневого письма Лены:

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

Логотип StackOverflow http://code-zen.info/twitterimage/images/stackoverflow-logo.bmp Cornell Box http://code-zen.info/twitterimage/images/cornell-box.bmp Лена http://code-zen.info/twitterimage/images/lena.bmp Мона Лиза http://code-zen.info/twitterimage/images/mona-lisa.bmp

Ответ 8

Этот генетический алгоритм, который написал Roger Alsing, имеет хорошую степень сжатия за счет длительного времени сжатия. Полученный вектор вершин может быть дополнительно сжат с использованием алгоритма с потерями или без потерь.

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

Будет интересная программа для реализации, но я дам ей промах.

Ответ 9

В исходной задаче ограничение размера определяется как то, что Twitter по-прежнему позволяет вам отправлять, если вы вставляете текст в свое текстовое поле и нажимаете "обновление". Как некоторые люди правильно заметили, это отличается от того, что вы могли бы отправить в виде текстового SMS-сообщения с вашего мобильного телефона.

Что неясно упоминается (но каким было мое личное правило), так это то, что вы должны выбрать твитированное сообщение в своем браузере, скопировать его в буфер обмена и вставить его в текстовое поле ввода вашего декодера, чтобы оно могло отобразите его. Конечно, вы также можете сохранить сообщение в виде текстового файла и прочитать его обратно или написать инструмент, который обращается к API Twitter и отфильтровывает любое сообщение, которое выглядит как код изображения (специальные маркеры кому-нибудь?). Но правило состоит в том, что сообщение должно пройти через Twitter, прежде чем вы сможете его декодировать.

Удачи с 350 байтами - я сомневаюсь, что вы сможете их использовать.

Ответ 10

Публикация монохромного или серого изображения должна улучшить размер изображения, которое может быть закодировано в этом пространстве, так как вы не заботитесь о цвете.

Возможно, добавление проблемы для загрузки трех изображений, которые при рекомбинации дают вам полноцветное изображение, сохраняя при этом монохромную версию на каждом отдельном изображении.

Добавьте некоторое сжатие к приведенному выше, и оно может начать выглядеть жизнеспособным...

Ницца!!! Теперь вы, ребята, заинтересовали меня. Никакая работа не будет сделана для остальной части дня...

Ответ 11

Что касается части кодирования/декодирования этой задачи. base16b.org - это моя попытка указать стандартный метод для безопасного и эффективного кодирования двоичных данных в более высоких плоскостях Юникода.

Некоторые функции:

  • Использует только пользовательские области Unicode
  • Кодирует до 17 бит на символ; почти в три раза эффективнее Base64
  • Предоставляется ссылка на реализацию Javascript для кодирования/декодирования
  • Включены некоторые примеры кодировок, включая Twitter и Wordpress

Извините, этот ответ приходит слишком поздно для первоначального конкурса. Я начал проект независимо от этого поста, который я обнаружил на полпути.

Ответ 12

Интересна идея хранения пучка опорных изображений. Было бы так неправильно хранить, скажем, 25 Мб образных изображений, и заставить кодер попробовать и составить изображение, используя бит из них? С такой крохотной трубой машина с обоих концов по необходимости будет намного больше, чем объем данных, проходящих через, так что разница между 25 Мб кода и 1 Мб кода и 24 Мб данных изображения?

(обратите внимание, что исходные правила исключают ограничение ввода изображений уже в библиотеке - я не предлагаю этого).

Ответ 13

Глупая идея, но sha1(my_image) приведет к "идеальному" представлению любого изображения (без учета коллизий). Очевидная проблема заключается в том, что процесс декодирования требует чрезмерных количеств грубой силы.

1-битный монохром будет немного проще. Каждый пиксель становится 1 или 0, поэтому у вас будет 1000 бит данных для изображения 100 * 100 пикселей. Поскольку хеш SHA1 имеет 41 символ, мы можем поместить три в одно сообщение, только для перебора силы 2 набора из 3333 бит и один набор из 3334 (хотя даже это, вероятно, все еще не определено)

Это не совсем практично. Даже с 1-битным 100-кратным изображением с фиксированной длиной 1.., предполагая, что я не ошибаюсь, 49995000 комбинаций или 16661667, если они разделены на три.

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

Ответ 15

Идея: Не могли бы вы использовать шрифт в качестве палитры? Попробуйте разбить изображение в серии векторов, пытающихся описать их комбинацией векторных множеств (каждый символ по существу представляет собой набор векторов). Это использует шрифт в качестве словаря. Я мог бы, например, использовать l для вертикальной линии и a - для горизонтальной линии? Просто идея.