Blog. Just Blog

Создание ASCII-картинки из изображения на PHP

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
Создание ASCII-картинки из изображения на PHP
Создание ASCII-картинки из изображения на PHP

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

У меня уже был самописный вариант генератора таких изображений где использовался широкий диапазон символов под каждый оттенок. И вот нашелся генератор с правильной математической моделью, который дает более лучший результат при использовании меньшего количества символов. За основу взят код от PerS'а, только свой вариант я постарался сделать без оверинженеринга. По-моему, нет смысла использовать классы там, где можно легко обойтись удобочитаемым линейным кодом.
  1. // Файл исходного изображения
  2. $file='image.jpg';
  3.  
  4. $im=ImageCreateFromJPEG($file);
  5. list($width,$height)=GetImageSize($file);
  6.  
  7. $luma_s=0;
  8. $luma=array();
  9. for ($x=0$x<$width$x++) {
  10.     for ($y=0$y<$height$y++) {
  11.         $RGB=ImageColorAt($im$x$y);
  12.         $R=(($RGB >> 16) & 0xFF)*0.299;
  13.         $G=(($RGB >> 8) & 0xFF)*0.587;
  14.         $B=($RGB 0xFF)*0.114;
  15.  
  16.         $tmp=$R+$G+$B;
  17.  
  18.         $luma_s+=$tmp;
  19.         $luma[]=$tmp;
  20.     }
  21. }
  22. $luma_m=$luma_s/$width/$height;
  23. $luma_q=0;
  24. foreach ($luma as $key=>$value) {
  25.     $luma_q+=pow($value-$luma_m2);
  26. }
  27. $luma_q=sqrt($luma_q/$width/$height);
  28.  
  29. $ascii='';
  30.  
  31. for ($y=0$y<($height-2); $y+=4) {
  32.     for ($x=0$x<($width-2); $x+=2) {
  33.         $char=0;
  34.         $char_m=0;
  35.  
  36.         for ($i=$y$i<($y+2); $i++) {
  37.              for ($j=$x$j<($x+2); $j++) {
  38.                 $RGB=ImageColorAt($im$j$i);
  39.                 $R=(($RGB >> 16) & 0xFF)*0.299;
  40.                 $G=(($RGB >> 8) & 0xFF)*0.587;
  41.                 $B=($RGB 0xFF)*0.114;
  42.  
  43.                 $tmp=$R+$G+$B;
  44.                 if ($tmp<$luma_m) { $char++; }
  45.                 $char=($char<<1);
  46.                 $char_m+=$tmp;
  47.             }
  48.         }
  49.         $char_m/=4;
  50.  
  51.         switch($char) {
  52.             case 0b0000: {
  53.                 if ($char_m>=($luma_m+$luma_q) || $char_m>=255) {
  54.                     $ascii.=' ';
  55.                 }
  56.                 elseif ($char_m>=($luma_m+$luma_q/3)) {
  57.                     $ascii.='.';
  58.                 }
  59.                 elseif ($char_m>=$luma_m) {
  60.                     $ascii.='*';
  61.                 }
  62.                 else {
  63.                     $ascii.=' ';
  64.                 }
  65.                 break;
  66.             }
  67.             case 0b0001:
  68.             case 0b0010: {
  69.                 $ascii.=',';
  70.                 break;
  71.             }
  72.             case 0b0011:
  73.             case 0b0111: {
  74.                 $ascii.='/';
  75.                 break;
  76.             }
  77.             case 0b0101:
  78.             case 0b1010: {
  79.                 $ascii.='=';
  80.                 break;
  81.             }
  82.             case 0b0110: {
  83.                 $ascii.='+';
  84.                 break;
  85.             }
  86.             case 0b1000:
  87.             case 0b0100: {
  88.                 $ascii.='`';
  89.                 break;
  90.             }
  91.             case 0b1001: {
  92.                 $ascii.='"';
  93.                 break;
  94.             }
  95.             case 0b1011: {
  96.                 $ascii.='&gt;';
  97.                 break;
  98.             }
  99.             case 0b1100:
  100.             case 0b1110: {
  101.                 $ascii.='\\';
  102.                 break;
  103.             }
  104.             case 0b1101: {
  105.                 $ascii.='&lt;';
  106.                 break;
  107.             }
  108.             default: {
  109.                 if ($char_m<=($luma_m-$luma_q) || $char_m<=0) {
  110.                     $ascii.='@';
  111.                 }
  112.                 elseif ($char_m<=($luma_m-$luma_q/3)) {
  113.                     $ascii.='O';
  114.                 }
  115.                 elseif ($char_m<=$luma_m) {
  116.                     $ascii.='o';
  117.                 }
  118.                 else {
  119.                     $ascii.='+';
  120.                 }
  121.                 break;
  122.             }
  123.         }
  124.    }
  125.    $ascii.="\n";
  126. }
  127. echo '<pre style="font-family:monospace; line-height:100%;">';
  128. echo $ascii;
  129. echo '</pre>';
Чтобы большие картинки лучше смотрелась в браузере, рекомендуется уменьшить масштаб комбинацией клавиш Ctrl+"-" (минус). Для достижения более правильных пропорций готовой ASCII-картинки при ее отображении на экране или при печати можно поиграть со шрифтами и межстрочным интервалом. Это вы уже сделаете самостоятельно, если надо.

Поделиться ссылкой ВКонтакте
Просмотров: 1796 | Комментариев: 10

Метки: PHP, графика
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
токио (27.01.2024 в 12:58):
Японский рогатый демон
demos (16.03.2021 в 11:08):
Цитатасимпотная деваха, все натуральное
- это-ж /*бубль-гум*/ Cаша Грей...
NobootRecord (09.02.2021 в 17:14):
ManHunter, ну... в качестве результата может быть текстовый документ с картинкой
ManHunter (08.02.2021 в 22:03):
Сделать можно что угодно, но вот целесообразность? На PHP оно вроде логично, картинку в форму загрузил, обработал, в браузере посмотрел, отмасштабировал и т.п. А на FASM конечный результат какой должен получиться?
NobootRecord (08.02.2021 в 21:59):
Интересный генератор ASCII-картинок у вас получился, тем более на PHP.
А вы пробовали на других языках его реализовать? На FASM, например...
ManHunter (08.02.2021 в 21:37):
Нет, это не я. Когда я был в таком возрасте, то бумажное цветное фото было роскошью. Ну а про цифровое фото только в фантастических книжках читали.
doz.me (08.02.2021 в 20:51):
а в разборе AVS Photo Editor фото не её.
даже есть такое мнение, что это детская фото mh)
кодер (06.02.2021 в 02:25):
"нет смысла использовать классы там, где можно легко обойтись удобочитаемым линейным кодом."

жму руку, коллега. золотые слова.
ManHunter (04.02.2021 в 21:17):
Ну а что, симпотная деваха, все натуральное, никаких партаков не набито. Мне нравится. Я обычно использую ее фотки в качестве демонстрашек всяких манипуляций с графикой.
doz.me (04.02.2021 в 19:37):
ценителей ASCII-Art все меньше и меньше, имхо.
Сашка не в курсе, но походу она уже второй member of PCL)

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0045 сек.) / Память: 4.5 Mb
Наверх