对于我的图像压缩,我正在使用枕头库来获取rgb中的每个像素(例如:(100,0,200)。使用霍夫曼编码,我已经转换为二进制以减少位数。现在,我必须将位序列保存到文本或二进制文件中,压缩文件要始终小于原始文件,但现在我的txt文件大于原始文件,我该怎么办?之后,我该如何读取文件并解压缩。这是一条指令:
您的代码应读入图像文件,计算固定长度编码需要多少位然后应用压缩算法来创建较小的编码-您需要实施压缩,则不能使用压缩库。您应该输出以压缩格式存储图像所需的位数以及所达到的压缩率。当谈到要保存压缩的图像,您将无法将其保存为标准图像格式,因为您将已经创建了自己的编码,但是您可以将位序列保存到文本或二进制文件中。
您的代码还应该能够提示用户输入包含压缩文件的文本文件的文件名位序列,然后将该文件解压缩为原始图像–您可以假设该文件使用与上次压缩的文件相同的压缩格式。因此,例如,如果您将pacificat.bmp压缩为存储在pacificat.txt中的一系列位,然后用户要求您对alt_encode.txt进行解压缩,则可以假设alt_pacificat.txt使用与encode.txt相同的压缩数据结构(例如,它可能是原始图像中数据的子集。)
有许多库可以帮助您将格式化的数据从Python存储到文件中。如果您研究这些选项并找到一种将压缩数据结构存储到文件中的方法,以便用户可以选择位文件和数据结构文件,然后使用该数据结构对位文件进行解压缩]
仅使用我当前的图像:flag2.bmp
这是我的代码
from PIL import Image
import sys, string
import copy
import time
codes = {}
def sortFreq (freqs) :
letters = freqs.keys()
tuples = []
for let in letters :
tuples.append((freqs[let],let))
tuples.sort()
return tuples
def buildTree(tuples) :
while len(tuples) > 1 :
leastTwo = tuple(tuples[0:2]) # get the 2 to combine
theRest = tuples[2:] # all the others
combFreq = leastTwo[0][0] + leastTwo[1][0] # the branch points freq
tuples = theRest + [(combFreq,leastTwo)] # add branch point to the end
tuples.sort() # sort it into place
return tuples[0] # Return the single tree inside the list
def trimTree (tree) :
# Trim the freq counters off, leaving just the letters
p = tree[1] # ignore freq count in [0]
if type(p) == type("") : return p # if just a leaf, return it
else : return (trimTree(p[0]), trimTree(p[1])) # trim left then right and recombine
def assignCodes(node, pat=''):
global codes
if type(node) == type("") :
codes[node] = pat # A leaf. set its code
else : #
assignCodes(node[0], pat+"0") # Branch point. Do the left branch
assignCodes(node[1], pat+"1") # then do the right branch.
start = time.time()
dictionary = {}
table = {}
image = Image.open('flag2.bmp')
#image.show()
width, height = image.size
px= image.load()
totalpixel = width*height
print("Total pixel: "+ str(totalpixel))
for x in range(width):
for y in range(height):
# print(px[x, y])
for i in range(3):
if dictionary.get(str(px[x, y][i])) is None:
dictionary[str(px[x, y][i])] = 1
else:
dictionary[str(px[x, y][i])] = dictionary[str(px[x, y][i])] +1
table = copy.deepcopy(dictionary)
def encode2 (str) :
global codes
output = ""
for ch in str : output += codes[ch]
return output
def decode (tree, str) :
output = ""
p = tree
for bit in str :
if bit == '0' : p = p[0] # Head up the left branch
else : p = p[1] # or up the right branch
if type(p) == type("") :
output += p # found a character. Add to output
p = tree # and restart for next character
return output
combination = len(dictionary)
for value in table:
table[value] = table[value] / (totalpixel * combination) * 100
print(table)
print(dictionary)
sortdic = sortFreq(dictionary)
tree = buildTree(sortdic)
print("tree")
print(tree)
trim = trimTree(tree)
print("trim")
print(trim)
print("assign 01")
assignCodes(trim)
print(codes)
empty_tuple = ()
f = open("answer.txt","w")
for x in range(width):
for y in range(height):
list = []
list.append(codes[str(px[x, y][0])])
list.append(codes[str(px[x, y][1])])
list.append(codes[str(px[x, y][2])])
print(str(px[x, y]) + ": " +str(list))
f.write(str(list))
print("decode test:", str(decode (trim, "1100")))
stop = time.time()
times = (stop - start) * 1000
print("Run time takes %d miliseconds" % times)
[flag2.bmp][1]
对于我的图像压缩,我正在使用枕头库来获取rgb中的每个像素(例如:(100,0,200)。使用霍夫曼编码,我已经转换为二进制以减少位数。现在, ...