我正在尝试了解如何创建二进制PBM/PGM/PPM文件.据我所知,每种格式有两种类型:普通格式和原始格式.例如,黑色PBM 5x5的结构如下所示:
P1
# This is a comment
5 5
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
Run Code Online (Sandbox Code Playgroud)
所以你看它很简单:白色是0,黑色是1.但是,PBM有原始版本,如下所示:
'P4\n# This is a comment\n5 5\n\xf8\xf8\xf8\xf8\xf8'
Run Code Online (Sandbox Code Playgroud)
我该怎么做?PBM格式的描述说:
A raster of Height rows, in order from top to bottom. Each row is Width bits, packed 8 to a byte, with don't care bits to fill out the last byte in the row. Each bit represents a pixel: 1 is black, 0 is white. The order of the pixels is left to right. The order of their storage within each file byte is most significant bit to least significant bit. The order of the file bytes is from the beginning of the file toward the end of the file.
A row of an image is horizontal. A column is vertical. The pixels in the image are square and contiguous.
我不明白我需要做什么; 我怀疑我可能需要使用struct或array.array,但我不确定.我需要你的帮助; 你能举一个Python的例子来创建这样的文件吗?
>>> size = (5, 5)
>>> array = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
>>> create_pbm(size, array)
'P4\n5 5\n\xf8\xf8\xf8\xf8\xf8'
Run Code Online (Sandbox Code Playgroud)
我需要一个很好的速度,因为我需要处理更大的图像(例如2000x5000).但问题是我需要使用纯Python,没有ctypes和库.请帮助我,并举例说明如何创建二进制PBM文件?
如果你能告诉我二进制PGM和PPM处理,那将会更加惊人.
谢谢!
我相信这里有很大的改进空间(就效率而言),但这是否正常?
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))
Run Code Online (Sandbox Code Playgroud)
编辑
至于阅读,这似乎工作:
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)
Run Code Online (Sandbox Code Playgroud)
这些文件格式是否需要是正方形的?这似乎不太可能.我很可能在尺寸部分混合了行/列.随意检查;-).
| 归档时间: |
|
| 查看次数: |
3752 次 |
| 最近记录: |