Create binary PBM/PGM/PPM

不羁的心 提交于 2019-12-05 15:11:16

I'm sure there's lots of room for improvement here, (in terms of efficiency) but does this work correctly?

import struct
def create_pbm(size,lst):
    out = ['P4\n'+' '.join(map(str,size))+'\n'] #header
    for j in xrange(0,len(lst),size[1]):
        #single row of data
        row = lst[j:j+size[1]]
        #padded string which can be turned into a number with `int`
        s = ''.join(map(str,row))+'0000000'
        #Turn the string into a number and pack it (into unsigned int) using struct. 
        vals = [struct.pack('B',int(s[i*8:(i+1)*8],2)) for i in xrange(size[0]//8+1) ]
        out.append(''.join(vals))
    return ''.join(out)

a = [1]*25 #flat black image.
print repr(create_pbm((5,5),a))

EDIT

As for reading, this seems to work:

def read_pbm(fname):
    with open(fname) as f:
        data = [x for x in f if not x.startswith('#')] #remove comments
    p_whatever = data.pop(0)  #P4 ... don't know if that's important...
    dimensions = map(int,data.pop(0).split())
    arr = []
    col_number = 0
    for c in data.pop(0):
        integer = struct.unpack('B',c)[0]
        col_number += 8
        bits = map(int,bin(integer)[2:])
        arr.extend(bits[:min(8,dimensions[0]-col_number)])
        if(col_number > dimensions[0]):
            col_number = 0 

    return (dimensions, arr)

Do these file formats need to be square? that seems unlikely. It's quite possible that I got rows/columns mixed up in the dimensions portion. Feel free to check that ;-).

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!