aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar jonas <himself@jonasgunz.de> 2019-04-29 01:31:48 +0200
committerGravatar jonas <himself@jonasgunz.de> 2019-04-29 01:31:48 +0200
commit4aa0cf5afc35509ccbfc23c722672c5a7a89001c (patch)
treedd6301ccd40db774e3fa7083c070551802e5512c
parent1beb7e77df6a630894243f5a29475e17b2b84096 (diff)
downloadAsciiMap-4aa0cf5afc35509ccbfc23c722672c5a7a89001c.tar.gz
Fixed color mode
-rw-r--r--main.c191
1 files changed, 140 insertions, 51 deletions
diff --git a/main.c b/main.c
index 0de32f7..3b9b69c 100644
--- a/main.c
+++ b/main.c
@@ -13,23 +13,6 @@
#define DEBUG_PRINTF(...) { }
#endif
-#define _HEADER_SIZE 54 //Fileheader + infoheader
-#define IDENTIFIER 0x424d //BM BitMap identifier
-
-//Address Definitions
-#define BF_TYPE 0x00
-#define BF_SIZE 0x02
-#define BF_OFF_BITS 0x0a
-
-#define BI_SIZE 0x0e
-#define BI_WIDTH 0x12
-#define BI_HEIGHT 0x16
-#define BI_BIT_COUNT 0x1c
-#define BI_COMPRESSION 0x1e
-#define BI_SIZE_IMAGE 0x22
-#define BI_CLR_USED 0x2e
-#define BI_CLR_IMPORTANT 0x32
-
#define CHAR_SIZE_X 2 //How many pixels should form one ASCII char?
#define CHAR_SIZE_Y (2 * CHAR_SIZE_X)
@@ -38,21 +21,49 @@ struct prog_param
char *filename;
unsigned int charsize_x;
unsigned int charsize_y;
+ uint8_t color;
};
-struct prog_param parse_args(int argc, char *argv[]);
+struct console_color
+{
+ uint8_t R;
+ uint8_t G;
+ uint8_t B;
-void print_help( void );
+ unsigned int no;
+};
+struct console_color colors[] = { //Insert the console's config here
+ {0,0,0,30}, //Black
+ {178,24,24,31}, //red
+ {24,178,24,32}, //Green
+ {178,104,24,33}, //Brown
+ {24,24,178,34}, //blue
+ {178,24,178,35}, //Magenta
+ {24,178,178,36}, //Cyan
+ {255,255,255,37} //White
+};
+
+//Both maps produce very different results
const char map[] = {' ', ' ', '.', ',', '`', '-', '~', '"', '*', ':', ';', '<', '!', '/', '?', '%', '&', '=', '$', '#'};
//const char map[] = {' ', '`', '.', ',', ':', ';', '\"', '+', '#', '@'};
+struct prog_param parse_args(int argc, char *argv[]);
+
+void print_help( void );
+
//Calculate average
-char avg(int argc, char *argv);
+uint8_t avg(int argc, uint8_t *argv);
+
+//Distance of 2 3d vectors
+float distance(uint8_t _1[3], uint8_t _2[3]);
-//Calculate luminance from rgb_avg
+//Calculate luminance
//Order LSB first: BGR
-char rgb_avg(uint8_t R, uint8_t G, uint8_t B);
+uint8_t rgb_avg(uint8_t R, uint8_t G, uint8_t B);
+
+//Get nearest printable color in console
+unsigned int calc_col(uint8_t R, uint8_t G, uint8_t B);
//Select Char based on 1B brightness Value
char calc_char(uint8_t _c, uint8_t _min, uint8_t _max);
@@ -61,18 +72,17 @@ int main(int argc, char *argv[])
{
struct prog_param args = parse_args(argc, argv);
- char **ascii_buff;
+ uint8_t **ascii_buff;
+ unsigned int **col_buff;
uint8_t b_max = 0x00;
uint8_t b_min = 0xff;
struct bitmap_pixel_data bitmap;
-
bitmap = bitmap_read(args.filename);
- if(bitmap.error)
- {
+ if(bitmap.error) {
printf("Error reading file\n");
return 1;
}
@@ -82,34 +92,62 @@ int main(int argc, char *argv[])
size_x = bitmap.x / args.charsize_x;
size_y = bitmap.y / args.charsize_y;
- DEBUG_PRINTF("Creating ASCII File %u x %u\n", size_x, size_y);
+ DEBUG_PRINTF("Output size: %u x %u\n", size_x, size_y);
+ //Where the chars are stored
ascii_buff = malloc(sizeof(*ascii_buff) * size_x);
- for (int i = 0; i < size_x; i++)
- {
+ for (int i = 0; i < size_x; i++) {
ascii_buff[i] = malloc(sizeof(ascii_buff[i]) * size_y);
}
+ //Where the color is stored, if activated
+ if(args.color) {
+ col_buff = malloc(sizeof(*col_buff) * size_x);
+ for (int i = 0; i < size_x; i++)
+ {
+ col_buff[i] = malloc(sizeof(col_buff[i]) * size_y);
+ }
+ }
+
//Nest thine Lööps
- for(int x = 0; x < size_x; x++)
- {
- for(int y = 0; y < size_y; y++)
- {
- char b[args.charsize_x][args.charsize_y];
+ //Very not optimal Variable names!!!!!!!!!!!!!
+ //
+ //For every Pixel-char: calculate average values of pixel blocks
+ for(unsigned int x = 0; x < size_x; x++) {
+ for(unsigned int y = 0; y < size_y; y++) {
+ uint8_t brightness [ args.charsize_x ][ args.charsize_y ]; //Average brightness of every pixels
+ uint8_t cc[ 3 ][ args.charsize_x * args.charsize_y ]; //RGB Values of block
+ unsigned int cc_counter = 0;
+
+ //Iterate through Pixel block
+ for(unsigned int row_c = 0; row_c < args.charsize_y; row_c++) {
+ unsigned int row = y * args.charsize_y + row_c; //Actual position in Bitmap
+
+ for(unsigned int col_c = 0; col_c < args.charsize_x; col_c++) {
+ unsigned int col = x * args.charsize_x + col_c; //Actual position in bitmap
+
+ brightness[col_c][row_c] = rgb_avg( bitmap.R[col][row],
+ bitmap.G[col][row],
+ bitmap.B[col][row] );
+
+ if(args.color) {
+ cc[0][cc_counter] = bitmap.R[col][row];
+ cc[1][cc_counter] = bitmap.G[col][row];
+ cc[2][cc_counter] = bitmap.B[col][row];
+ cc_counter++;
+ }
+ }
+ }
- for(int r = 0; r < args.charsize_y; r++)
+ ascii_buff[x][y] = avg(args.charsize_x * args.charsize_y, *brightness);
+ if(args.color)
{
- int row = y * args.charsize_y + r;
- for(int c = 0; c < args.charsize_x; c++)
- {
- int col = x * args.charsize_x + c;
- //b[c][r] = avg(3, (char*)&bitmap_buff[row][col]);
- b[c][r] = rgb_avg(bitmap.R[col][row],bitmap.G[col][row],bitmap.B[col][row]);
- }
+ col_buff[x][y] = calc_col(
+ (uint8_t)avg(args.charsize_x * args.charsize_y, cc[0]),
+ (uint8_t)avg(args.charsize_x * args.charsize_y, cc[1]),
+ (uint8_t)avg(args.charsize_x * args.charsize_y, cc[2]) );
}
- ascii_buff[x][y] = avg(args.charsize_x * args.charsize_y, (char*)&b);
-
if((uint8_t)ascii_buff[x][y] < b_min)
b_min = ascii_buff[x][y];
if((uint8_t)ascii_buff[x][y] > b_max)
@@ -118,13 +156,16 @@ int main(int argc, char *argv[])
}
DEBUG_PRINTF("Brightness Values: Min: %u Max: %u\n", b_min, b_max);
-
+ if(args.color)
+ printf("\e[0m");//Default colors
for(int y = 0; y<size_y; y++)
{
for(int x = 0; x < size_x; x++)
{
- printf("%c", calc_char(ascii_buff[x][y], b_min, b_max));
+ if(args.color)
+ printf("\e[%um", col_buff[x][y]);
+ printf("%c", calc_char(ascii_buff[x][y], 0,255));//b_min, b_max));
}
printf("\n");
}
@@ -150,9 +191,9 @@ int main(int argc, char *argv[])
}//main
-char avg(int argc, char *argv)
+uint8_t avg(int argc, uint8_t *argv)
{
- char ret = 0;
+ uint8_t ret = 0;
uint64_t sum = 0;
for(int i = 0; i < argc; i++)
@@ -169,9 +210,9 @@ char calc_char(uint8_t _c , uint8_t _min, uint8_t _max)
return map [(int)((sizeof(map)-1) * (c))];
}
-char rgb_avg(uint8_t R, uint8_t G, uint8_t B)
+uint8_t rgb_avg(uint8_t R, uint8_t G, uint8_t B)
{
- char ret;
+ uint8_t ret;
ret = sqrt( 0.299*pow(R,2) + 0.587*pow(G,2) + 0.114*pow(B,2) ); //(char)(R+R+B+G+G+G)/6;
@@ -185,6 +226,7 @@ struct prog_param parse_args(int argc, char *argv[])
ret.filename = NULL;
ret.charsize_x = CHAR_SIZE_X;
ret.charsize_y = 0;
+ ret.color = 0;
for (int i = 1; i < argc; i++)
{
@@ -209,6 +251,9 @@ struct prog_param parse_args(int argc, char *argv[])
i++;
ret.charsize_y = atoi(argv[i]);
break;
+ case 'c':
+ ret.color = 1;
+ break;
default:
printf("Unrecognized Option\n");
print_help();
@@ -247,5 +292,49 @@ void print_help( void )
printf("ASCIIMap\n(c) 2019 Jonas Gunz, github.com/kompetenzbolzen/AsciiMap\n");
printf("ASCIIMap prints a ASCII representation of a bitmap image\n\nUsage: [OPTIONS] FILENAME\n");
printf("Options:\n -h: Print this help message\n -x VAL: set the width of block wich makes up one character. Default: %i\n", CHAR_SIZE_X);
- printf(" -y VAL: set the height of block wich makes up one character. Default: 2*x\n\n");
+ printf(" -y VAL: set the height of block wich makes up one character. Default: 2*x\n -c: Print in color mode. Default: OFF\n");
+}
+
+unsigned int calc_col(uint8_t R, uint8_t G, uint8_t B)
+{
+ DEBUG_PRINTF("%u %u %u\n", R, G, B);
+
+ unsigned int nearest_num = 0;
+ uint8_t a2[3];
+ a2[0] = colors[0].R;
+ a2[1] = colors[0].G;
+ a2[2] = colors[0].B;
+
+ uint8_t a1[] = {R,G,B};
+
+ //Normalize the color
+ /*while(a1[0] < 255 && a1[1] < 255 && a1[2] < 255)
+ {
+ a1[0]++;
+ a1[1]++;
+ a1[2]++;
+ }*/
+
+ float nearest_val = distance( a1, a2 );
+
+ for( unsigned int i = 1; i < sizeof(colors) / sizeof(struct console_color); i++)
+ {
+ a2[0] = colors[i].R;
+ a2[1] = colors[i].G;
+ a2[2] = colors[i].B;
+
+ float dist = distance(a1, a2);
+ if(dist < nearest_val){
+ nearest_num = i;
+ nearest_val = dist;
+ }
+ }
+ DEBUG_PRINTF("Nearest: %u %f\n", nearest_num, nearest_val);
+ return colors[nearest_num].no;
+}
+
+float distance(uint8_t _1[3], uint8_t _2[3])
+{
+ return fabs(sqrt( pow((double)_1[0], 2) + pow((double)_1[1],2) + pow((double)_1[2],2) )
+ - sqrt( pow((double)_2[0], 2) + pow((double)_2[1],2) + pow((double)_2[2],2) ) );
}