def compress(inputFile, outputFile): # Read the input file into a numpy array of 8-bit values # # The img.shape is a 3-type with rows,columns,channels, where # channels is the number of component in each pixel. The img.dtype # is 'uint8', meaning that each component is an 8-bit unsigned # integer. img = netpbm.imread(inputFile).astype('uint8') # Compress the image # # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY. # # Note that single-channel images will have a 'shape' with only two # components: the y dimensions and the x dimension. So you will # have to detect this and set the number of channels accordingly. # Furthermore, single-channel images must be indexed as img[y,x] # instead of img[y,x,1]. You'll need two pieces of similar code: # one piece for the single-channel case and one piece for the # multi-channel case. startTime = time.time() outputBytes = bytearray() for y in range(img.shape[0]): for x in range(img.shape[1]): for c in range(img.shape[2]): outputBytes.append(img[y, x, c]) endTime = time.time() # Output the bytes # # Include the 'headerText' to identify the type of file. Include # the rows, columns, channels so that the image shape can be # reconstructed. outputFile.write('%s\n' % headerText) outputFile.write('%d %d %d\n' % (img.shape[0], img.shape[1], img.shape[2])) outputFile.write(outputBytes) # Print information about the compression inSize = img.shape[0] * img.shape[1] * img.shape[2] outSize = len(outputBytes) sys.stderr.write('Input size: %d bytes\n' % inSize) sys.stderr.write('Output size: %d bytes\n' % outSize) sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize))) sys.stderr.write('Compression time: %.2f seconds\n' % (endTime - startTime))
def compress(inputFile, outputFile): # Read the input file into a numpy array of 8-bit values # # The img.shape is a 3-type with rows,columns,channels, where # channels is the number of component in each pixel. The img.dtype # is 'uint8', meaning that each component is an 8-bit unsigned # integer. img = netpbm.imread(inputFile).astype('uint8') # Compress the image # # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY. startTime = time.time() outputBytes = bytearray() for y in range(img.shape[0]): for x in range(img.shape[1]): for c in range(img.shape[2]): outputBytes.append(img[y, x, c]) endTime = time.time() # Output the bytes # # Include the 'headerText' to identify the type of file. Include # the rows, columns, channels so that the image shape can be # reconstructed. outputFile.write('%s\n' % headerText) outputFile.write('%d %d %d\n' % (img.shape[0], img.shape[1], img.shape[2])) outputFile.write(outputBytes) # Print information about the compression inSize = img.shape[0] * img.shape[1] * img.shape[2] outSize = len(outputBytes) sys.stderr.write('Input size: %d bytes\n' % inSize) sys.stderr.write('Output size: %d bytes\n' % outSize) sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize))) sys.stderr.write('Compression time: %.2f seconds\n' % (endTime - startTime))
def compress(inputFile, outputFile): # Read the input file into a numpy array of 8-bit values # # The img.shape is a 3-type with rows,columns,channels, where # channels is the number of component in each pixel. The img.dtype # is 'uint8', meaning that each component is an 8-bit unsigned # integer. img = netpbm.imread(inputFile).astype('uint8') # Compress the image # # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY. # # Note that single-channel images will have a 'shape' with only two # components: the y dimensions and the x dimension. So you will # have to detect this and set the number of channels accordingly. # Furthermore, single-channel images must be indexed as img[y,x] # instead of img[y,x,1]. You'll need two pieces of similar code: # one piece for the single-channel case and one piece for the # multi-channel case. startTime = time.time() # outputBytes = [] outputBytes = bytearray() diff = [] # it's a single-channel image if len(img.shape) == 2: for y in range(img.shape[0]): for x in range(img.shape[1]): # Predictive encoding prediction = int( img[y - 1, x]) + (int(img[y, x - 1]) - int(img[y - 1, x - 1])) / 2 diff.append(int(img[y, x]) - int(prediction)) else: # it's a multi-channel image for y in range(img.shape[0]): for x in range(img.shape[1]): for c in range(img.shape[2]): # Predictive encoding prediction = int(img[y - 1, x, c]) + ( int(img[y, x - 1, c]) - int(img[y - 1, x - 1, c])) / 2 diff.append(int(img[y, x, c]) - int(prediction)) # print(diff) # construct initial dictionary dict_size = 256 dictionary = { struct.pack("h", i): i + 256 for i in xrange(-dict_size, dict_size) } # LZW encode the diff array s = '' for i in range(len(diff)): x = struct.pack('h', diff[i]) temp = s + x if temp in dictionary: s = temp else: s_in = dictionary[s] s1 = s_in >> 8 s2 = s_in & 255 outputBytes.append(s1) outputBytes.append(s2) if len(dictionary) < 65536: dictionary[temp] = dict_size dict_size += 1 s = x # encode the last s s_in = dictionary[s] s1 = s_in >> 8 s2 = s_in & 255 outputBytes.append(s1) outputBytes.append(s2) # print(dictionary) endTime = time.time() # Output the bytes # # Include the 'headerText' to identify the type of file. Include # the rows, columns, channels so that the image shape can be # reconstructed. outputFile.write('%s\n' % headerText) outputFile.write('%d %d %d\n' % (img.shape[0], img.shape[1], img.shape[2])) outputFile.write(str(outputBytes)) # Print information about the compression inSize = img.shape[0] * img.shape[1] * img.shape[2] outSize = len(outputBytes) sys.stderr.write('Input size: %d bytes\n' % inSize) sys.stderr.write('Output size: %d bytes\n' % outSize) sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize))) sys.stderr.write('Compression time: %.2f seconds\n' % (endTime - startTime))
def compress(inputFile, outputFile): # Read the input file into a numpy array of 8-bit values # # The img.shape is a 3-type with rows,columns,channels, where # channels is the number of components in each pixel. The img.dtype # is 'uint8', meaning that each component is an 8-bit unsigned # integer. img = netpbm.imread(inputFile).astype('uint8') # Compress the image # # # Note that single-channel images will have a 'shape' with only two # components: the y dimensions and the x dimension. So you will # have to detect this and set the number of channels accordingly. # Furthermore, single-channel images must be indexed as img[y,x] # instead of img[y,x,1]. You'll need two pieces of similar code: # one piece for the single-channel case and one piece for the # multi-channel case. startTime = time.time() outputBytes = bytearray() # initialize dictionary d = {} counter = 256 for i in range(-counter, counter): d[str(i)] = i # Set Dictionary limit # Make a list to hold bytes tempBytes = [] # A counter for the number of bytes numBytes = 0 multichannel = True # for a single channel image if (len(img.shape) == 2): multichannel = False # Go through whole image for y in range(img.shape[0]): for x in range(img.shape[1]): # Initialize prediction to image value prediction = img[y][x] #""" # Modify prediction to show the difference between prior pixels and current pixel if (x != 0): prediction = prediction - img[y][x - 1] elif (y != 0): prediction = prediction - img[y - 1][x] else: prediction = prediction - (img[y][x - 1] / 3 + img[y - 1][x] / 3 + img[y - 1][x - 1] / 3) #""" # Add the predicted value to the bytestream tempBytes.append(prediction) numBytes += 1 # Multi-Channel else: # Go through whole image and channels for y in range(img.shape[0]): for x in range(img.shape[1]): for c in range(img.shape[2]): # Do predictive encoding # Initialize prediction to image value prediction = img[y][x][c] # Modify prediction to show the difference between prior pixels and current pixel #"""" if (x != 0): prediction = prediction - img[y][x - 1][c] elif (y != 0): prediction = prediction - img[y - 1][x][c] else: prediction = prediction - (img[y][x - 1][c] / 3 + img[y - 1][x][c] / 3 + img[y - 1][x - 1][c] / 3) #"""" # Add the predicted value to the bytestream tempBytes.append(prediction) numBytes += 1 # Using a string variable as it allows for concatenation s = "" # Set s to the first value of the bytestream s = str(tempBytes[0]) # Go through all bytes for i in range(1, numBytes): # Do LZW encoding # If trying to add entry larger than max size of the dictionary reinitialize the dictionary if (counter >= twoBytes): counter = 256 d = {} for i in range(-counter, counter): d[str(i)] = i # Add the next byte to the current string. Uses a delimeter to distinguish numbers w = s + "|" + str(tempBytes[i]) # Checking if it has been seen before if w in d: s = w else: # Output bytes by splitting integer into two bytes, this allows for a larger dictionary outputBytes.append((int(d[s]) >> 8) & 0xFF) outputBytes.append(int(d[s]) & 0xFF) # Add to dictionarry d[w] = counter counter += 1 s = str(int(tempBytes[i])) # Check if the last byte was added or not if s in d: outputBytes.append((int(d[s]) >> 8) & 0xFF) outputBytes.append(int(d[s]) & 0xFF) endTime = time.time() # Output the bytes # # Include the 'headerText' to identify the type of file. Include # the rows, columns, channels so that the image shape can be # reconstructed. outputFile.write('%s\n' % headerText) if (multichannel): outputFile.write('%d %d %d\n' % (img.shape[0], img.shape[1], img.shape[2])) else: one = 1 outputFile.write('%d %d %d\n' % (img.shape[0], img.shape[1]), one) outputFile.write(outputBytes) # Print information about the compression if (multichannel): inSize = img.shape[0] * img.shape[1] * img.shape[2] else: inSize = img.shape[0] * img.shape[1] outSize = len(outputBytes) sys.stderr.write('Input size: %d bytes\n' % inSize) sys.stderr.write('Output size: %d bytes\n' % outSize) sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize))) sys.stderr.write('Compression time: %.2f seconds\n' % (endTime - startTime))
def compress(inputFile, outputFile): # Read the input file into a numpy array of 8-bit values # # The img.shape is a 3-type with rows,columns,channels, where # channels is the number of component in each pixel. The img.dtype # is 'uint8', meaning that each component is an 8-bit unsigned # integer. img = netpbm.imread(inputFile).astype('uint8') # Compress the image # # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY. # # Note that single-channel images will have a 'shape' with only two # components: the y dimensions and the x dimension. So you will # have to detect this and set the number of channels accordingly. # Furthermore, single-channel images must be indexed as img[y,x] # instead of img[y,x,1]. You'll need two pieces of similar code: # one piece for the single-channel case and one piece for the # multi-channel case. startTime = time.time() # outputBytes = np.array([],dtype = np.uint16) tempBytes = [] channels = 0 # -256 - 0 maps to 0 - 256, 1-255 mapps to 257 - 511 baseDict = genDict() if len(img.shape) == 2: channels = 1 elif len(img.shape) == 3: channels = 3 else: print("unrecognized image format") return pArray = [] # if 1 channel, loop through every pixel if (channels == 1): for x in range(img.shape[0]): for y in range(img.shape[1]): # initial pixel, don't make prediction if (x == 0 and y == 0): pArray.append(int(img[0, 0])) else: # make prediction using previous pixel if x == 0: pArray.append(int(img[x, y]) - int(img[x, y - 1])) else: pArray.append(int(img[x, y]) - int(img[x - 1, y])) # Image has 3 channels, loop through all pixels and channels else: for x in range(img.shape[0]): for y in range(img.shape[1]): for c in range(img.shape[2]): # Initial pixel, no prediction if (x == 0 and y == 0): pArray.append(int(img[0, 0, c])) else: if x == 0: pArray.append( int(img[x, y, c]) - int(img[x, y - 1, c])) else: pArray.append( int(img[x, y, c]) - int(img[x - 1, y, c])) # number of symbols to encode numSymbols = img.shape[0] * img.shape[1] * channels # LZW Compression s = str(pArray[0]) nextDictIndex = len(baseDict) for i in range(1, numSymbols): x = str(pArray[i]) if s + "," + x in baseDict: s = s + "," + x else: tempBytes.append(baseDict[s]) baseDict[s + "," + x] = np.uint16(nextDictIndex) nextDictIndex += 1 s = x tempBytes.append(baseDict[s]) outputBytes = np.array(tempBytes, dtype=np.uint16) endTime = time.time() # Output the bytes # # Include the 'headerText' to identify the type of file. Include # the rows, columns, channels so that the image shape can be # reconstructed. stringImgShape = [] for num in img.shape: stringImgShape.append(str(num)) outputFile.write('%s\n' % headerText) outputFile.write(' '.join(stringImgShape) + '\n') outputFile.write(outputBytes) # Print information about the compression inSize = numSymbols outSize = len(outputBytes) sys.stderr.write('Input size: %d bytes\n' % inSize) sys.stderr.write('Output size: %d bytes\n' % outSize) sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize))) sys.stderr.write('Compression time: %.2f seconds\n' % (endTime - startTime))
def compress( inputFile, outputFile ): # Read the input file into a numpy array of 8-bit values # # The img.shape is a 3-type with rows,columns,channels, where # channels is the number of component in each pixel. The img.dtype # is 'uint8', meaning that each component is an 8-bit unsigned # integer. img = netpbm.imread( inputFile ).astype('uint8') # Compress the image # # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY. # # Note that single-channel images will have a 'shape' with only two # components: the y dimensions and the x dimension. So you will # have to detect this and set the number of channels accordingly. # Furthermore, single-channel images must be indexed as img[y,x] # instead of img[y,x,1]. You'll need two pieces of similar code: # one piece for the single-channel case and one piece for the # multi-channel case. startTime = time.time() outputBytes = bytearray() # Initialize dictionary maxsize = 65536 dict_size = 256 d = initializeDictionary(dict_size) s = '' for y in range(img.shape[0]): for x in range(img.shape[1]): for c in range(img.shape[2]): fp = 0 if(len(img.shape) > 2): #fp = getprediction(img,x,y,c,True) if(x > 0): fp = img[y,x-1,c] e = img[y,x,c] - fp else: #fp = getprediction(img,x,y,0,False) if(x > 0): fp = img[y,x-1] e = img[y,x] - fp if(s + chr(e) in d): s += chr(e) else: #sq = convertchar2num(d[s]) sq = d[s] if(len(sq) < 2): sq = chr(0) + sq outputBytes.append(sq[0]) outputBytes.append(sq[1]) d[s + chr(e)] = convertnum2char(dict_size) dict_size += 1 if(dict_size > maxsize): dict_size = 256 d = initializeDictionary(dict_size) s = chr(e) sq = d[s] if(len(sq) < 2): sq = chr(0) + sq outputBytes.append(sq[0]) outputBytes.append(sq[1]) endTime = time.time() # Output the bytes # # Include the 'headerText' to identify the type of file. Include # the rows, columns, channels so that the image shape can be # reconstructed. outputFile.write( '%s\n' % headerText ) if len(img.shape) > 2: outputFile.write( '%d %d %d\n' % (img.shape[0], img.shape[1], img.shape[2]) ) else: outputFile.write( '%d %d\n' % (img.shape[0], img.shape[1])) outputFile.write( outputBytes ) # Print information about the compression if len(img.shape) > 2: inSize = img.shape[0] * img.shape[1] * img.shape[2] else: inSize = img.shape[0]*img.shape[1] outSize = len(outputBytes) sys.stderr.write( 'Input size: %d bytes\n' % inSize ) sys.stderr.write( 'Output size: %d bytes\n' % outSize ) sys.stderr.write( 'Compression factor: %.2f\n' % (inSize/float(outSize)) ) sys.stderr.write( 'Compression time: %.2f seconds\n' % (endTime - startTime) )
def compress(inputFile, outputFile): # Read the input file into a numpy array of 8-bit values # # The img.shape is a 3-type with rows,columns,channels, where # channels is the number of component in each pixel. The img.dtype # is 'uint8', meaning that each component is an 8-bit unsigned # integer. img = netpbm.imread(inputFile).astype('uint8') # Compress the image # # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY. # # Note that single-channel images will have a 'shape' with only two # components: the y dimensions and the x dimension. So you will # have to detect this and set the number of channels accordingly. # Furthermore, single-channel images must be indexed as img[y,x] # instead of img[y,x,1]. You'll need two pieces of similar code: # one piece for the single-channel case and one piece for the # multi-channel case. startTime = time.time() dimensions = len(img.shape) # if single channel if dimensions == 2: # Empty dictionary d = {} # Current dictionary index dict_index = 0 # Previous value prev = 0 for i in range(-255, 256): # Stores the binary value d[(struct.pack('>h', i))] = i + 255 dict_index = i + 255 outputBytes = bytearray() # p is the byte pattern that will be passed into the dictionary p = "" p_c = "" for y in range(img.shape[0]): for x in range(img.shape[1]): # c is the current byte being analyzed c = int(img[y][x]) - int(prev) prev = img[y][x] bc = struct.pack('>h', c) p_c = p + bc # if the character c is already in the dictionary add it to the present character stream if p_c in d: p = p_c else: val = struct.pack('>H', d[p]) b1, b2 = struct.unpack('>BB', val) outputBytes.append(b1) outputBytes.append(b2) if dict_index < 65535: dict_index += 1 d[p_c] = dict_index p = bc outputFile.write('%d %d\n' % (img.shape[0], img.shape[1])) outputBytes.append(img[y, x]) # if multichannel elif dimensions > 2: # Empty dictionary d = {} # Current dictionary index dict_index = 0 # Previous values prev = [] for i in range(img.shape[2]): prev.append(0) for i in range(-255, 256): # Stores the binary value d[(struct.pack('>h', i))] = i + 255 dict_index = i + 255 outputBytes = bytearray() # p is the byte pattern that will be passed into the dictionary p = "" p_c = "" for y in range(img.shape[0]): for x in range(img.shape[1]): for channel in range(img.shape[2]): # c is the current byte being analyzed c = int(img[y][x][channel]) - int(prev[channel]) prev[channel] = img[y][x][channel] bc = struct.pack('>h', c) p_c = p + bc # if the character c is already in the dictionary add it to the present character stream if p_c in d: p = p_c else: val = struct.pack('>H', d[p]) b1, b2 = struct.unpack('>BB', val) outputBytes.append(b1) outputBytes.append(b2) if dict_index < 65535: dict_index += 1 d[p_c] = dict_index p = bc outputFile.write('%d %d %d\n' % (img.shape[0], img.shape[1], img.shape[2])) outputBytes.append(img[y, x, channel]) # Output the bytes # # Include the 'headerText' to identify the type of file. Include # the rows, columns, channels so that the image shape can be # reconstructed. outputFile.write('%s\n' % headerText) outputFile.write(outputBytes) # Print information about the compression inSize = img.shape[0] * img.shape[1] outSize = len(outputBytes) endTime = time.time() sys.stderr.write('Input size: %d bytes\n' % inSize) sys.stderr.write('Output size: %d bytes\n' % outSize) sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize))) sys.stderr.write('Compression time: %.2f seconds\n' % (endTime - startTime))
def compress(inputFile, outputFile): # Read the input file into a numpy array of 8-bit values # # The img.shape is a 3-type with rows,columns,channels, where # channels is the number of component in each pixel. The img.dtype # is 'uint8', meaning that each component is an 8-bit unsigned # integer. img = netpbm.imread(inputFile).astype('uint8') # Compress the image # # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY. # # Note that single-channel images will have a 'shape' with only two # components: the y dimensions and the x dimension. So you will # have to detect this and set the number of channels accordingly. # Furthermore, single-channel images must be indexed as img[y,x] # instead of img[y,x,1]. You'll need two pieces of similar code: # one piece for the single-channel case and one piece for the # multi-channel case. startTime = time.time() outputBytes = bytearray() diff_image = [] # create diffrence array if len(img.shape) != 3: # single-channel image num_of_channels = 1 for y in range(img.shape[0]): for x in range(img.shape[1]): if x == 0: # first pixel diff_image.append(img[y][x]) else: diff_image.append(img[y][x] - img[y][x - 1]) else: # not single-channel image num_of_channels = img.shape[2] for y in range(img.shape[0]): for x in range(img.shape[1]): for c in range(img.shape[2]): # include colour if x == 0: # first pixel diff_image.append(img[y][x][c]) else: diff_image.append(img[y][x][c] - img[y][x - 1][c]) init_dict = {} # initialize dictionary dict_size = (255 * 2) for i in range(dict_size + 1): init_dict[str(i - 255) + ","] = i # initialize all possible diffrences (no negative) dict_copy = init_dict.copy() sub_string = "" for element in diff_image: if dict_size >= 65536: # if larger than max allowed size dict_copy = init_dict.copy() dict_size = (255 * 2) sub_string += str(element) + "," if not sub_string in dict_copy: dict_size += 1 dict_copy[sub_string] = dict_size append_key = ",".join(sub_string.split(",")[:-2]) + "," byte_one = dict_copy[append_key] // ( 2**8) # get first byte value (from int) byte_two = dict_copy[ append_key] & 0b11111111 # get second byte value (from int) outputBytes.append(byte_one) outputBytes.append(byte_two) sub_string = str(element) + "," byte_one = dict_copy[sub_string] // (2**8) byte_two = dict_copy[sub_string] & 0b11111111 outputBytes.append(byte_one) outputBytes.append(byte_two) endTime = time.time() # Output the bytes # # Include the 'headerText' to identify the type of file. Include # the rows, columns, channels so that the image shape can be # reconstructed. print num_of_channels outputFile.write('%s\n' % headerText) outputFile.write('%d %d %d\n' % (img.shape[0], img.shape[1], num_of_channels)) outputFile.write(outputBytes) # Print information about the compression if len(img.shape) == 3: inSize = img.shape[0] * img.shape[1] * img.shape[2] outSize = len(outputBytes) sys.stderr.write('Input size: %d bytes\n' % inSize) sys.stderr.write('Output size: %d bytes\n' % outSize) sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize))) sys.stderr.write('Compression time: %.2f seconds\n' % (endTime - startTime)) else: inSize = img.shape[0] * img.shape[1] * num_of_channels outSize = len(outputBytes) sys.stderr.write('Input size: %d bytes\n' % inSize) sys.stderr.write('Output size: %d bytes\n' % outSize) sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize))) sys.stderr.write('Compression time: %.2f seconds\n' % (endTime - startTime))
def compress(inputFile, outputFile): # Read the input file into a numpy array of 8-bit values # # The img.shape is a 3-type with rows,columns,channels, where # channels is the number of component in each pixel. The img.dtype # is 'uint8', meaning that each component is an 8-bit unsigned # integer. img = netpbm.imread(inputFile).astype('uint8') # Compress the image # # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY. # # Note that single-channel images will have a 'shape' with only two # components: the y dimensions and the x dimension. So you will # have to detect this and set the number of channels accordingly. # Furthermore, single-channel images must be indexed as img[y,x] # instead of img[y,x,1]. You'll need two pieces of similar code: # one piece for the single-channel case and one piece for the # multi-channel case. startTime = time.time() outputBytes = bytearray() index = 256 # create initial dict for LZW compression containing all possible differences dictionary = dict((chr(i), i) for i in xrange(index)) difs = [] # loop through each channel of each pixel and compute the predictive difference for y in range(img.shape[0]): for x in range(1, img.shape[1]): for c in range(img.shape[2]): dif = 0 if (img.shape[2] == 1): # single channel dif = abs(int(img[y, x]) - int(img[y, x - 1])) else: # more channels dif = abs(int(img[y, x, c]) - int(img[y, x - 1, c])) difs.append(dif) # for testing to check the similarity between uncompressed differences after decoding unencoded = open('unencoded.txt', 'w') for d in difs: unencoded.write(str(d) + '\n') unencoded.close() s = '' # loop through the differences and perform LZW compression for x in difs: sx = s + chr(x) if sx in dictionary: s = sx else: # turn index into 2 bytes b = struct.pack('H', dictionary[s]) for byte in b: outputBytes.append(byte) # keep dictionary size below 65535 to enforce 2 byte indices if len(dictionary) < 65535: dictionary[sx] = index + 1 index += 1 s = chr(x) endTime = time.time() # Output the bytes # # Include the 'headerText' to identify the type of file. Include # the rows, columns, channels so that the image shape can be # reconstructed. outputFile.write('%s\n' % headerText) outputFile.write('%d %d %d\n' % (img.shape[0], img.shape[1], img.shape[2])) outputFile.write(outputBytes) # Print information about the compression inSize = img.shape[0] * img.shape[1] * img.shape[2] outSize = len(outputBytes) sys.stderr.write('Input size: %d bytes\n' % inSize) sys.stderr.write('Output size: %d bytes\n' % outSize) sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize))) sys.stderr.write('Compression time: %.2f seconds\n' % (endTime - startTime))
def compress(inputFile, outputFile): # Read the input file into a numpy array of 8-bit values # # The img.shape is a 3-type with rows,columns,channels, where # channels is the number of component in each pixel. The img.dtype # is 'uint8', meaning that each component is an 8-bit unsigned # integer. img = netpbm.imread(inputFile).astype('uint8') # Compress the image # # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY. # # Note that single-channel images will have a 'shape' with only two # components: the y dimensions and the x dimension. So you will # have to detect this and set the number of channels accordingly. # Furthermore, single-channel images must be indexed as img[y,x] # instead of img[y,x,1]. You'll need two pieces of similar code: # one piece for the single-channel case and one piece for the # multi-channel case. startTime = time.time() outputBytes = bytearray() baseDict = {} for i in range(512): baseDict[str(i)] = i pixelValues = [] if (len(img.shape) == 2): channels = 1 for x in range(img.shape[0]): for y in range(img.shape[1]): pixelValues.append(img[x, y]) elif (len(img.shape) == 3): channels = 3 for x in range(img.shape[0]): for y in range(img.shape[1]): for c in range(img.shape[2]): pixelValues.append(img[x, y, c]) else: print("invalid image format, exiting") quit() predictions = [] predictions.append(pixelValues.pop(0) + 255) for i in pixelValues: predictions.append(int(pixelValues[i]) - int(pixelValues[i - 1]) + 255) numSymbols = img.shape[0] * img.shape[1] * channels nextIndex = len(baseDict) s = "" for i in range(numSymbols): x = str(predictions[i]) if s + x in baseDict: s = s + x else: outputBytes.append((int(baseDict[s]) >> 8) & 0xFF) outputBytes.append(int(baseDict[s]) & 0xFF) baseDict[s + x] = nextIndex nextIndex += 1 s = x endTime = time.time() # Output the bytes # # Include the 'headerText' to identify the type of file. Include # the rows, columns, channels so that the image shape can be # reconstructed. outputFile.write('%s\n' % headerText) if (channels == 1): outputFile.write('%d %d\n' % (img.shape[0], img.shape[1])) else: outputFile.write('%d %d %d\n' % (img.shape[0], img.shape[1], img.shape[2])) outputFile.write(outputBytes) # Print information about the compression inSize = img.shape[0] * img.shape[1] * channels outSize = len(outputBytes) sys.stderr.write('Input size: %d bytes\n' % inSize) sys.stderr.write('Output size: %d bytes\n' % outSize) sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize))) sys.stderr.write('Compression time: %.2f seconds\n' % (endTime - startTime))
def compress(inputFile, outputFile): # Read the input file into a numpy array of 8-bit values # # The img.shape is a 3-type with rows,columns,channels, where # channels is the number of component in each pixel. The img.dtype # is 'uint8', meaning that each component is an 8-bit unsigned # integer. img = netpbm.imread(inputFile).astype('uint8') # Compress the image # # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY. # # Note that single-channel images will have a 'shape' with only two # components: the y dimensions and the x dimension. So you will # have to detect this and set the number of channels accordingly. # Furthermore, single-channel images must be indexed as img[y,x] # instead of img[y,x,1]. You'll need two pieces of similar code: # one piece for the single-channel case and one piece for the # multi-channel case. startTime = time.time() outputBytes = bytearray() # detect shape and set channels accordingly if len(img.shape) == 2: channels = [img.flatten()] elif len(img.shape) == 3: channels = [img[:, :, i].flatten() for i in range(img.shape[2])] # loop through each channel to encode each individually for chnl in channels: lzwD, i = initLZWD() #initialize counters to keep track of previous value and previous sequence for LZW prevP = 0 prevS = () for p in chnl: pDiff = p - prevP currS = prevS + (pDiff, ) # if sequence not in dict, write to stream if currS not in lzwD: # stop at max 16 bit size -1 = 65535 if i < 65535: lzwD[currS] = i i += 1 # get value that was prevS val = lzwD[prevS] # encode into bytes smallB = val % 256 bigB = val / 256 # append bytes to output outputBytes.append(bigB) outputBytes.append(smallB) # reset prevS to new previous sequence prevS = (pDiff, ) # sequence in dict, don't write new sequence, add to existing sequence else: # onto next sequence prevS = currS prevP = p # finish LZW by encoding end data if len(prevS) > 1: # same as 'if sequence not in dict' val = lzwD[prevS] smallB = val % 256 bigB = val / 256 outputBytes.append(bigB) outputBytes.append(smallB) # end flags outputBytes.append(255) outputBytes.append(255) endTime = time.time() # Output the bytes # # Include the 'headerText' to identify the type of file. Include # the rows, columns, channels so that the image shape can be # reconstructed. outputFile.write('%s\n' % headerText) outputFile.write('%d %d %d\n' % (img.shape[0], img.shape[1], len(channels))) outputFile.write(outputBytes) # Print information about the compression inSize = img.shape[0] * img.shape[1] * len(channels) outSize = len(outputBytes) sys.stderr.write('Input size: %d bytes\n' % inSize) sys.stderr.write('Output size: %d bytes\n' % outSize) sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize))) sys.stderr.write('Compression time: %.2f seconds\n' % (endTime - startTime))
def compress( inputFile, outputFile ): # Read the input file into a numpy array of 8-bit values # # The img.shape is a 3-type with rows,columns,channels, where # channels is the number of component in each pixel. The img.dtype # is 'uint8', meaning that each component is an 8-bit unsigned # integer. img = netpbm.imread( inputFile ).astype('uint8') # Compress the image # # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY. startTime = time.time() dictionary = {} # create a dictionary dictsize = 0 for i in range(-255, 256): dictionary[str(i)] = dictsize dictsize += 1 channelsN = img.shape[2] outputlist = [] outputBytes = bytearray() listSize = 0 for y in range(img.shape[0]): for x in range(img.shape[1]): for c in range(channelsN): outputlist.append(img[y,x,c]) listSize += 1 print listSize, sys.getsizeof(outputlist) lastStr = '' current = outputlist[0] lastStr = str(int(current)) for i in range(1, listSize): if dictsize >= 65536: dictionary = {} # create a dictionary dictsize = 0 for i in range(-255, 256): dictionary[str(i)] = dictsize dictsize += 1 current = outputlist[i] entry = lastStr+","+str(int(current)) if entry in dictionary: lastStr = entry else: outBits = dictionary[lastStr] outLow = outBits & 0xFF outHigh = (outBits >> 8) & 0xFF outputBytes.append(outLow) outputBytes.append(outHigh) dictionary[entry] = dictsize dictsize += 1 lastStr = str(int(current)) if lastStr in dictionary: outBits = dictionary[lastStr] outLow = outBits & 0xFF outHigh = (outBits >> 8) & 0xFF outputBytes.append(outLow) outputBytes.append(outHigh) endTime = time.time() # Output the bytes # # Include the 'headerText' to identify the type of file. Include # the rows, columns, channels so that the image shape can be # reconstructed. outputFile.write( '%s\n' % headerText ) outputFile.write( '%d %d %d\n' % (img.shape[0], img.shape[1], img.shape[2]) ) outputFile.write( outputBytes ) inSize = img.shape[0] * img.shape[1] * img.shape[2] outSize = len(outputBytes) sys.stderr.write( 'Input size: %d bytes\n' % inSize ) sys.stderr.write( 'Output size: %d bytes\n' % outSize ) sys.stderr.write( 'Compression factor: %.2f\n' % (inSize/float(outSize)) ) sys.stderr.write( 'Compression time: %.2f seconds\n' % (endTime - startTime) )