Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Тяпничная текстовая картинка / 25 сообщений из 51, страница 1 из 3
27.03.2015, 13:18
    #38918959
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
Здарова челы!

Мои читуны тяпничных загадок. Хакатон-щики.
Фанаты сей. Рыцари крестов и Асма.
И прочие geeks.

Сегодня - особый тикет .

Дано - текстовая консоль. Какая? А вот такая. Как в линуксе. Или как cmd в Винде.
Дан - графический файлик. Маленький. Надо отобразить этот графический
файлик цветом в текстовой консоли. Максимально правдоподобно.

Пример:



P.S. Hardcore & Hardcode приветствуется! Mua-haha!

P.P.S. #include <ncurses.h> вам в помощь!

Go! Go!
...
Рейтинг: 0 / 0
27.03.2015, 14:18
    #38919075
m_Sla
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
Делаем ресайз bmp из исходного разрешения в 80*25. Потом выводим.
...
Рейтинг: 0 / 0
27.03.2015, 14:35
    #38919104
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
m_SlaПотом выводим.
А с цветами что делать?
...
Рейтинг: 0 / 0
27.03.2015, 14:54
    #38919149
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
maytonА с цветами что делать?
До 16 уменьшить. Или сколько там консоль умеет показывать.
...
Рейтинг: 0 / 0
27.03.2015, 15:07
    #38919179
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
Библиотека ncurses различает 8 цветовых констант. Но что-то мне подсказывает что
можно сымитировать больше.
...
Рейтинг: 0 / 0
27.03.2015, 15:24
    #38919202
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
maytonБиблиотека ncurses различает 8 цветовых констант. Но что-то мне подсказывает что
можно сымитировать больше.
Можно псевдографику задействовать, тогда каждый "пиксель" станет 2х2, но с цветами такого пикселя тогда поизвращаться надо.
...
Рейтинг: 0 / 0
27.03.2015, 15:32
    #38919207
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
Предлагаю не мелочиться и сразу видео отображать.
...
Рейтинг: 0 / 0
27.03.2015, 15:34
    #38919216
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
Go!Go! Давайте хотяб преведмир.
...
Рейтинг: 0 / 0
27.03.2015, 15:35
    #38919218
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
Dima TmaytonБиблиотека ncurses различает 8 цветовых констант. Но что-то мне подсказывает что
можно сымитировать больше.
Можно псевдографику задействовать, тогда каждый "пиксель" станет 2х2, но с цветами такого пикселя тогда поизвращаться надо.
Там хитрые символы есть. Прямоугольник. Со штриховкой.
...
Рейтинг: 0 / 0
27.03.2015, 16:04
    #38919271
RWolf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
quick&dirty.c
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
#include <stdio.h>
#include <windows.h>   // WinApi header

int main()
{
  HANDLE  hConsole;
  int w, h, k;

  FILE *f = fopen("c.bmp", "rb");
  fseek(f, 0x12, 0);
  fread(&w, sizeof(w), 1, f);
  fread(&h, sizeof(h), 1, f);

  hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

  // you can loop k higher to see more color choices
  for(int y = 0; y < h; y++)
  {
    fseek(f, 0x36+(h-y-1)*w*4, 0);
    for(int x = 0; x < w; x++)
    {
      int color, r, g, b;
      fread(&color, sizeof(color), 1, f);
      r = color & 0xFF;
      g = (color>>8) & 0xFF;
      b = (color>>16) & 0xFF;
      r >>= 7;
      g >>= 7;
      b >>= 7;
      int k = b<<2 | g<<1 | r;
      SetConsoleTextAttribute(hConsole, k);
      printf("Ы");
    }
    printf("\n");
  }

  getchar();  // wait
  return 0;
}


...
Рейтинг: 0 / 0
27.03.2015, 16:38
    #38919314
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
Р-Волк. Круть. Давай цветов больше.
...
Рейтинг: 0 / 0
27.03.2015, 17:44
    #38919405
RWolf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
mayton,

В принципе, без усилий добавляется 8 градаций яркости знакоместа (две родных консольных и четыре символами штриховки). С цветностью сложнее, в консольи под r,g,b отведено всего по одному биту. Можно что-то получить из смешивания цвета символа и фона теми же символами.
...
Рейтинг: 0 / 0
27.03.2015, 20:41
    #38919545
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
В табличке 866 есть несколько интересных букв.



Пробел (0x20), 0xB0, 0xB1, 0xB2, 0xDB. Можно используя цвет шрифта и (если есть backgroud)
добиться большего количества.
...
Рейтинг: 0 / 0
27.03.2015, 22:41
    #38919661
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
Код: plaintext
1.
2.
3.
4.
5.
#define FILL_0   0x20
#define FILL_25  0xB0
#define FILL_50  0xB1
#define FILL_75  0xB2
#define FILL_100 0xDB
...
Рейтинг: 0 / 0
28.03.2015, 17:56
    #38919916
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
Вот такое вот гониво вышло... Пока черно-белое.

Сорц не совсем мой. Прости википедия...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <math.h>
#include "bitmap.h" /* Здесь определения заголовков BMP как было описано выше в этой статье (структуры должны быть упакованы на 2 байта!) */


#define PS_FILL_EMPTY  0x20
#define PS_FILL_FULL   0xDB
#define PS_FILL_DOWN   0xDC
#define PS_FILL_UP     0xDF

/////////////////////////

#define FILL_0   0x20
#define FILL_25  0xB0
#define FILL_50  0xB1
#define FILL_75  0xB2
#define FILL_100 0xDB


double value(int r,int g,int b){
        return (0.299*(r&0xFF) + 0.587*(g&0xFF) + 0.114*(b&0xFF)) / 255.0;
}

double distance(int r1,int g1,int b1,int r2,int g2,int b2){
	int dr = r1 - r2;
	int dg = g1 - g2;
	int db = b1 - b2;
	return sqrt( 0.299 * (double)dr * dr + 0.587 * (double)dg * dg + 0.114 * (double)db * db);
}

 
main(int argc, char *argv[])
{
    int  n, w, h, fd, size;
    unsigned char *data;
    BITMAPFILEHEADER bmp;
    BITMAPINFOHEADER inf;

    char* buf;
 
 
    if ((fd = open(argv[1], O_RDONLY)) == -1) {
        printf("Error open bitmap\n");
        exit(1);
    }

    

    read(fd, &bmp, sizeof(BITMAPFILEHEADER));

    read(fd, &inf,sizeof(BITMAPINFOHEADER));
 
    w = inf.biWidth;
    h = inf.biHeight;

    printf("Image size (pix) : %d,%d \n",w,h);
 
    /*if ((dis = XOpenDisplay(getenv("DISPLAY"))) == NULL) {
	printf("Can't connect X server: %s\n", strerror(errno));
	exit(1);
    }
 
    win = XCreateSimpleWindow(dis, RootWindow(dis, DefaultScreen(dis)), 0, 0, width, height, 5,
                   BlackPixel(dis, DefaultScreen(dis)), WhitePixel(dis, DefaultScreen(dis)));
 
    XSetStandardProperties(dis, win, argv[1], argv[0], None, argv, argc, NULL);
    gc = DefaultGC(dis, DefaultScreen(dis));*/
 
 /* Иногда в структуре это место не заполнено */

    int linesize = w * 3 + w % 4;

    if(inf.biSizeImage == 0)  {
    /* Вычислим размер */
      size = w * 3 + w % 4;
      size = size * h;
    } else {
      size = inf.biSizeImage;
     }
 
    buf = malloc(size);

    if(buf == NULL) {
	perror("malloc");
	exit(1);
    }

    printf("size = %d allocated\n", size);
 
     /* Сместимся на начало самого изображения */
    lseek(fd, bmp.bfOffBits, SEEK_SET);
 
    /* Читаем в буфер */
    n = read(fd, buf, size);

    printf("size = %d readed\n", n);
    int x;
    int y;
    for(y=0;y<h;y++){
       for(x=0;x<w;x++){

           byte *p = buf + x * 3 + (h - y - 1) * linesize;

           int r = *p++;
           int g = *p++;
           int b = *p++;

           double v = value(r,g,b);

	   if (v<0.2){
              printf("%c",FILL_0);
           } else if (v<0.4){
              printf("%c",FILL_25);
           } else if (v<0.6){
              printf("%c",FILL_50);
           } else if (v<0.8){
              printf("%c",FILL_75);
           } else {
              printf("%c",FILL_100);
           }
       }
       printf("\n");
    }
 
    //image = CreateImageFromBuffer(dis, buf, width, height);
 
    /* Удалим буфер - он нам больше не нужен */
    free(buf);
 
    /*XMapWindow(dis, win);
    XSelectInput(dis, win, ExposureMask | KeyPressMask);
    while (1) {
	XNextEvent(dis, &event);
	if (event.xany.window == win) {
	    switch (event.type) {
	    case Expose:
		XPutImage(dis, win, gc, image, 0, 0, 0, 0, image->width, image->height);
		break;
 
	    case KeyPress:
		if (XLookupKeysym(&event.xkey, 0) == XK_q) {
		    XDestroyImage(image);
		    XCloseDisplay(dis);
    	    	    close(fd);
		    exit(EXIT_SUCCESS);
		}
		break;
 
	    default:
		break;
	    }
	}
    }*/
}
 
...
Рейтинг: 0 / 0
28.03.2015, 18:30
    #38919928
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
maytonВот такое вот гониво вышло... Пока черно-белое.
Ты бы картинки показал "до" и "после", как RWolf сделал. Товар лицом посмотрел, после интересно и код глянуть. Не выйдет из тебя продавец :)
...
Рейтинг: 0 / 0
28.03.2015, 18:49
    #38919932
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
Да я не продаю пока. Значить о проблемах.

Я задал 5 уровней квантования для Value (цветовая яркость). Это мало. Т.к.
слабо-контрастные Ч-Б картинки могут попадать на границу 0.4 - 0.6.
Это хреново. Необходимо перед преобразованием определять границы
гистограммы светимости и авто-нормировать чтобы min max были соот 0.0 - 1.0.
При этом 0.0 подразумевает что выборка пикселов 0.0-0.2 достаточно велика.
Не один и не два. А ощутимо велика.
...
Рейтинг: 0 / 0
28.03.2015, 18:55
    #38919936
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
...
Рейтинг: 0 / 0
28.03.2015, 18:57
    #38919937
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
...
Рейтинг: 0 / 0
28.03.2015, 19:03
    #38919939
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
Неплохой результат. Можно еще поколдовать с палитрой. 16 цветов ограничение, но они же не фиксированные. В DOSе можно было палитру свою задать, в виндовсе - не знаю.
...
Рейтинг: 0 / 0
28.03.2015, 19:22
    #38919941
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
Касаемо виндовс.

Я полез в МСДН по ссылке на фунцию SetConsoleTextAttribute(...) которую использовал Р-Волк.

И оттуда вытянул следующее.
https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms682088(v=vs.85).aspx#_win32_character_attributes

Виндовс действительно управляет цветовыми атрибутами как ZX-Spectrum.
А именно (3 + 1) бита - активация системных цветов RGB + дополнительно интенсивность для беграунда.
И еще (3 + 1) бита для цвета шрифта на 1 знакоместе.

Итого 8 бит. Подозреваю что следующи битовые маски для этого предназначены.

Код: plaintext
1.
2.
3.
4.
5.
FOREGROUND_BLUE	Text color contains blue.
FOREGROUND_GREEN	Text color contains green.
FOREGROUND_RED	Text color contains red.
FOREGROUND_INTENSITY	Text color is intensified.
...



Не густо.... Ну что-ж попробуем.
...
Рейтинг: 0 / 0
28.03.2015, 19:35
    #38919945
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
Попробуй хотя бы эту в черно-серую превратить. Думаю лучше будет чем сине-голубая.
Мне кажется в данном случае перевод в оттенки серого должен дать более качественную картинку, чем пытаться цвет передать.
...
Рейтинг: 0 / 0
28.03.2015, 19:44
    #38919948
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
Сине-голубая это черно-белая. Которую я открыл в ФАР-е.
...
Рейтинг: 0 / 0
29.03.2015, 12:35
    #38920296
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
В первом приближении - работает.
...
Рейтинг: 0 / 0
29.03.2015, 12:44
    #38920298
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничная текстовая картинка
О проблемах:

1) Низкая контрастность исходных данных. Экспериментально я установил что лучший результат получался
когда картинка предварительно имеет высокий уровень контраста. Для этого я использовал графические
тулзы чтобы нормировать наиболее информативные участки гистограммы во весь спектр 0..255 уровней по
трем каналам.

2) Антизотропность . Псевдографический блок имеет плохие пропорции. На картинке с Джери видно что ее
лицо сжато по вертикали довольно значительно. Что с этим делать - я не знаю. Наверное ничего. Оставлю как есть.
Чуть позже доработаю фильтр масштабирования чтобы поправить разрешение исходного материала (автоматически)
с учётом набора блочной псевдографики ( gray1 - 200%, color2 - 200%, color1 - 60% (приблизительно)).

3) Несостоятельность фомулы цветовой дистанции которую я использовал. Возможно она неплохо подходит
для точных цветовых расчётов но в палитре 16 системных цветов она даёт парадоксальные результаты.
Например в градиенте между синим белым внезапо появляется пурпурный. Объяснить я это не могу.
Или у меня баг в коде. Не в самой формуле дистанции а где-то дальше по коду ее применения.

Код: plaintext
1.
2.
3.
4.
5.
6.
double distance(int r1,int g1,int b1,int r2,int g2,int b2){
	double dr = 0.299 * (r1 - r2);
	double dg = 0.587 * (g1 - g2);
	double db = 0.114 * (b1 - b2);
	return sqrt(dr * dr + dg * dg + db * db);
}
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Тяпничная текстовая картинка / 25 сообщений из 51, страница 1 из 3
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]