Как понять кодировку формата .bitmap. Преобразование 1-битных растровых изображений в изображения пером и бумагой - PullRequest
0 голосов
/ 29 июня 2018

Я изо всех сил пытаюсь истолковать и разобраться во многих параметрах формата растрового изображения, и мой вариант использования настолько прост, что я надеялся, что кто-то может указать мне правильное направление: как мне (мысленно, с помощью пера и -paper) преобразовать необработанный файл .bitmap в массив пикселей? Все остальные сайты, которые я мог найти, предоставляют либо функцию, либо библиотеку для вычислительного решения проблемы, или я не могу понять тонкое различие между различными вариантами форматирования (а также мою путаницу между .bmp и .bitmap).

Мое изображение было нарисовано с помощью пиксельной сетки "13 X 11" в GIMP, с индексной моделью, установленной на 1-бит, перед экспортом в файл .bitmap. Файл скопирован ниже вместе с двумя его представлениями ASCII: вы должны увидеть «73» в середине и несколько пикселей в верхней и нижней строке шаблона: 1101001000010.

#define seventythree_with_fibbonacci_spaces_pixels_width 13
#define seventythree_with_fibbonacci_spaces_pixels_height 11
static unsigned char seventythree_with_fibbonacci_spaces_pixels_bits[] = {
   0x4b, 0x08, 0x3e, 0x07, 0xa0, 0x04, 0x30, 0x04, 0x10, 0x07, 0x18, 0x04,
   0x0c, 0x04, 0x84, 0x04, 0x84, 0x03, 0x00, 0x00, 0x4b, 0x08 };
/*
1101001000010
0111110011100
0000010100100
0000110000100
0000100011100
0001100000100
0011000000100
0010000100100
0010000111000
0000000000000
1101001000010
*/

/*
@@ @  @    @ 
 @@@@@  @@@  
     @ @  @  
    @@    @  
    @   @@@  
   @@     @  
  @@      @  
  @    @  @  
  @    @@@   
@@ @  @    @ 
*/
// where a 1 or @ represents a black pixel square, 
// and a 0 or space is a white/blank square.

Теперь мой вопрос: какова точная математическая связь между этими 22 * ​​1006 * 8-битными словами [75, 8, 62, ...., 75, 8] и оригинальная картинка, которую я рисую в GIMP?

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

1 Ответ

0 голосов
/ 29 июня 2018

Полагаю, я решил это сейчас: посмотрите этот скрипт на питоне (я много комментировал, я знаю, что для некоторых это решение вроде мармита!). Я использовал python3 (3.6.5)

from sys import argv   # argument values
from math import ceil

"""
In GIMP, draw a WIDTH x HEIGHT Black & White picture:: Image/Mode >> Indexed...<use black and white (1 Bit) palette>:: export as .bitmap and choose the X10 format option.

This script can draw a simple ASCII image of it, or be used to get a binary

For testing, I  used:
    python3 convertBitMapX10_to_binary_grid.py Lev1_TD.bitmap
"""

if len(argv) > 2:
    saveFileName = argv[2]
else:
    saveFileName = "image_dump"

f = open(argv[1], "r")
l = [line for line in f.readlines()]
f.close()
## print(l[0])
## print(l[1])
## print(l[2])
# print(l[3])
# print(l[4])

WIDTH = int(l[0].split()[-1])
HEIGHT = int(l[1].split()[-1])

# l[3:] is our plan
l = l[3:]   # lines 0 and 1 were only useful for getting the image width (x) and height (y)
            # line 2 is just "static unsigned short Lev1_TD_bits[] = {" 



# print([l[-1]])
#       ['   0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x000f };\n']
l[-1] = l[-1].strip()[:-3]
# print(l[-1])

l = [line.strip() for line in l]

# print(l[0])  #0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x000f, 0xffff, 0xffff,
# print(l[-1])  #0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x000f 


l[-1] = l[-1] + ","
# Now every line has the same format (although l[-1] may have fewer elements)
#print(len(l[0]))  #71
#print(len(l[2]))  #71
#print(len(l[7]))  #71
#print(len(l[-1])) #55
### NOTICE ALL OF THESE ARE === -1  IN MODULO 8 -- that's because they are missing a ' ' char at the end
# (8 == len("0xffff, "), if you wondered where '8' came from)

l = [line + " " for line in l]


l = [line.split(", ")[:-1] for line in l]
# l is now a list of lists. most of these lists have lengths of 72/8 (9), except the last, which has 7
# the elements of each of these sublists is a string like "0xffff" or "0x0000"
## the '[:-1]' clause is to cut-out the last element, which by construction will be the empty string '' and we don't want it

l = [  [ bin(int(s, 16))[2:] for s in l[i]]   for i in range(len(l)) ]
# now the elements of these sublists are 16-bit strings such as "1111111111111111"


def mergelists(listOfLists):
    l = []
    for x in listOfLists:
        l += x
    return l

l = mergelists(l)

l = [i.zfill(16) for i in l]


def rev(s):
    x = ""
    for i in range(len(s)):
        x += s[-1-i]
    return x


n = ceil(WIDTH/16)
m = 16*n - WIDTH
assert len(l) == n*HEIGHT, "I believe this should always be true, else I've messed up somewhere; or maybe this isn't an X10 Format?"


def __aux_funct(l, n, i):
    s = ""
    for j in range(n):
        s += rev(l[n*i + j])
    return s


l = [ __aux_funct(l, n, i)  for i in range(HEIGHT) ]
l = [line[:-m] for line in l]



##for line in l:
##    print(line)
# seems to work just fine ^_^


f = open(saveFileName + ".binaryimage", "a")

BLACK_BOX = '#'


for line in l:
    # print(len(line)) ## they all seem to be the same width
    print("") # newline
    f.write(line + "\n")
    for bit in line:
        print(BLACK_BOX, end='') if bit == "1" else print(" ", end='')
print("")

f.write("\n\n")
f.close()
# Beautiful <3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...