2013-11-23 34 views
0

我想将包含“1”和“0”的二进制等效文件重新转换为其JPG格式(或转换回二进制)将“1”和“0”转换为其二进制等效文件以生成JPG

即我已经包含了所有1和0,我使用下面的函数从JPG图像转换

def convert_binary(inpath, outpath): 
    byte2str = ["{:08b}".format(i) for i in range(256)] 
    with open(inpath, "rb") as fin: 
     with open(outpath, "w") as fout: 
      data = fin.read(1024) 
      while data: 
       for b in map(ord, data): 
        fout.write(byte2str[b]) 
       data = fin.read(1024) 

    convert_binary("image.jpg", "binary_file.txt") 

感谢Tim彼得斯文件

我现在想将其转换回(1和0)返回到它的原始图像,任何帮助将不胜感激。 P:我真的很抱歉这样的小问题,我是一个生物技术专业,python编程并不是我的专长。我正在为我的论文尝试一个应用程序,并陷入困境。

+0

我很困惑,什么是初始文件代表什么? JPG数据的实际位,或单色位图(或其他)? – Thomas

+0

@Thomas我最初有一个JPG图像,我转换为1和0(将JPEG的二进制形式转换为1和0所代表的形式) 现在这个文件代表1和0中图像的二进制,i想要将其转换为我使用的原始图像。 – Meet

+0

为了好奇,你对数据做了什么? –

回答

0

您可以使用int(x,2)来反转x = byte2str[b],也可以使用chr反转ord。您的.txt文件包含原始jpg每个字节的8个字符。所以,你的代码应该是这样的:

data = fin.read(1024) 
while data: 
    for i in range(0, len(data), 8): 
     fout.write(chr(int(data[i:i+8], 2))) 
    data = fin.read(1024) 

不幸的是read不能保证准确返回你要求的字节数,它允许返回较少。因此,我们需要使事情变得复杂:

data = fin.read(1024) 
while data: 
    if len(data) % 8 != 0: 
     # partial read 
     endidx = len(data) - len(data) % 8 
     leftover = data[endidx:] 
     data = data[:endidx] 
     if len(data) == 0: 
      raise ValueError('invalid file, length is not a multiple of 8') 
    for i in range(0, len(data), 8): 
     fout.write(chr(int(data[i:i+8], 2))) 
    data = leftover + fin.read(1024) 

有很多更好的方法来表示二进制文件作为文本虽然,例如base64编码。

+0

在循环之前...你可以执行'import os' ...'如果os.path.getsize(fin.name)%8!= 0' - 抱怨它...然后保留原来的代码... –

+0

嗯,这是我问你的答案是同样的事情。我写了这段代码就好像'read()'的行为像C'read',因此可以返回部分读取,因为没有明显的原因。这是因为我还没有在Python文档中找到它没有的保证。 'read'在有任何数据返回时立即返回,并且在没有阻塞的情况下返回尽可能多的数据。因此,如果文件名引用了异步I/O(可能是网络映射的驱动器或命名管道,无论操作系统支持哪种),那么它不一定会落在8字节倍数上。 –

+0

确实......但在这种情况下'getsize'将无法正常工作 - 请查看http://hg.python.org/cpython/file/08f282c96fd1/Objects/fileobject.c中的第1052行 - 代码说话比单词更响亮,然后你可以得出你自己的结论......看起来像是阻止,直到我们得到'n',如果我们不能很好地理解,提出异常,否则继续尝试,直到我们有n并返回它。 –

1

沿着同样的史蒂夫的回答是:

with open('input', 'rb', 1024) as fin, open('output', 'wb') as fout: 
    fout.writelines(chr(int(chunk, 2)) for chunk in iter(lambda: fin.read(8), '')) 
+0

编码器可以用'fout.writelines byte2str [ord(b)] for it in iter(fin.read(1),''))'。我担心的是,当read(8)'允许在文件中剩下8个字节时,在Python中返回7个字节,因为'fread'允许在C中执行?我的答案假设它是允许的,'io.RawIOBase'的文档只是说,“从对象中读取n个字节并返回它们。” –

+0

@SteveJessop确实......虽然你的方法胜出,但2参数'iter'和'writelines'的使用并不是很清楚。我只是“打”了一下你的代码以供将来参考... –

+0

@SteveJessop Yup - 允许读取返回小于请求的大小...但是,如果文件大小不能被8整除,那么我会说这是一个不同的问题... –

相关问题