1 回答

TA貢獻1829條經(jīng)驗 獲得超7個贊
您不需要將數(shù)據(jù)轉(zhuǎn)換為十六進制或二進制,只需將二進制數(shù)據(jù)(字節(jié)序列)轉(zhuǎn)換為二維數(shù)組即可。
問題是沒有任何一維數(shù)組可以重整為二維數(shù)組。
例如,如果字節(jié)數(shù)是素數(shù) = N,您將獲得 1xN 圖像(丑陋的單行或單列圖像)。
以下示例假設(shè)圖像尺寸必須為正方形,并根據(jù)需要使用填充來完成字節(jié)數(shù):
import numpy as np
from math import sqrt, ceil
import cv2
#Input file name (random file I found in my folder).
input_file_name = 'test_cython.cp36-win_amd64.pyd';
#Read the whole file to data
with open(input_file_name, 'rb') as binary_file:
data = binary_file.read()
# Data length in bytes
data_len = len(data)
# d is a verctor of data_len bytes
d = np.frombuffer(data, dtype=np.uint8)
# Assume image shape should be close to square
sqrt_len = int(ceil(sqrt(data_len))) # Compute square toot and round up
# Requiered length in bytes.
new_len = sqrt_len*sqrt_len
# Number of bytes to pad (need to add zeros to the end of d)
pad_len = new_len - data_len
# Pad d with zeros at the end.
# padded_d = np.pad(d, (0, pad_len))
padded_d = np.hstack((d, np.zeros(pad_len, np.uint8)))
# Reshape 1D array into 2D array with sqrt_len pad_len x sqrt_len (im is going to be a Grayscale image).
im = np.reshape(padded_d, (sqrt_len, sqrt_len))
# Save image
cv2.imwrite('im.png', im)
# Display image
cv2.imshow('im' ,im)
cv2.waitKey(0)
cv2.destroyAllWindows()
結(jié)果:
構(gòu)建可用于恢復原始文件的映像:
如果要獲取圖像,并恢復原始文件(字節(jié)相等,無填充),則需要恢復圖像中的原始數(shù)據(jù)長度。
(您也可以恢復填充的長度)。
以下實現(xiàn),將原始數(shù)據(jù)長度存儲在前 8 個像素中。
讀取圖像后,可以去除填充和存儲長度,恢復原始文件。
這是一個“編碼”和“解碼”的例子:
import numpy as np
from math import sqrt, ceil
import cv2
import struct
#Input file name
input_file_name = 'test_cython.cp36-win_amd64.pyd';
#Read the whole file to data
with open(input_file_name, 'rb') as binary_file:
data = binary_file.read()
# Data length in bytes
data_len = len(data)
# d is a verctor of data_len bytes
d = np.frombuffer(data, dtype=np.uint8)
data_len_as_bytes = np.frombuffer(struct.pack("Q", data_len), dtype=np.uint8) # Convert data_len to 8 bytes
data_len = data_len + len(data_len_as_bytes) #Update length to include the 8 bytes
# Set data_len as first 8 bytes of d
d = np.hstack((data_len_as_bytes, d))
# Assume image shape should be close to square
sqrt_len = int(ceil(sqrt(data_len))) # Compute square toot and round up
# Requiered length in bytes.
new_len = sqrt_len*sqrt_len
# Number of bytes to pad (need to add zeros to the end of d)
pad_len = new_len - data_len
# Pad d with zeros at the end.
# padded_d = np.pad(d, (0, pad_len))
padded_d = np.hstack((d, np.zeros(pad_len, np.uint8)))
# Reshape 1D array into 2D array with sqrt_len pad_len x sqrt_len (im is going to be a Grayscale image).
im = np.reshape(padded_d, (sqrt_len, sqrt_len))
# Save image
cv2.imwrite('im.png', im)
# Display image
#cv2.imshow('im' ,im)
#cv2.waitKey(0)
#cv2.destroyAllWindows()
# Restore original data:
##################################
input_file_name = 'test.bin'; #Output file name
im = cv2.imread('im.png', cv2.IMREAD_GRAYSCALE)
# Convert 2D to 1D
padded_d = im.flatten()
# Get original length
data_len_as_bytes = padded_d[0:8]
orig_data_len = struct.unpack("Q", data_len_as_bytes.tobytes())
# Crop the original data bytes (without the padding).
data = padded_d[8:8+orig_data_len[0]]
#Write d whole file to binary file
with open(input_file_name, 'wb') as binary_file:
binary_file.write(data)
現(xiàn)在您可以將任何(?。┪募鳛閳D像上傳到 Stack Overflow,并讓其他人恢復您的文件。
添加回答
舉報