Created
March 26, 2022 07:24
-
-
Save rocket-pig/c8e29296fa7f462d7fd8e8fe642ad5c2 to your computer and use it in GitHub Desktop.
Quickly convert arbitrary data into/out of .png format. Example: https://i.ibb.co/qgSsgmp/out.png (is an MP3)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
# Updated and stripped ver of https://github.com/ESultanik/bin2png Evan Sultanik | |
#Quickly convert arbitrary data into/out of .png format. Example: https://i.ibb.co/qgSsgmp/out.png (is an MP3) | |
import math | |
from PIL import Image | |
import sys | |
# print usage, if no arguments are given | |
if len(sys.argv) < 2: | |
print("Usage: %s <input file> <output file>" % sys.argv[0]) | |
print("if <input file> is a file, will convert to png.") | |
print("if <input file> is a png, will convert back to file") | |
sys.exit(1) | |
def choose_file_dimensions(infile): | |
with open(infile, 'rb') as f: | |
data = f.read() | |
num_bytes = len(data) | |
num_pixels = int(math.ceil(float(num_bytes) / 3.0)) | |
sqrt = math.sqrt(num_pixels) | |
sqrt_max = int(math.ceil(sqrt)) | |
return(sqrt_max, sqrt_max) | |
def png_to_file(infile, outfile, no_progress=True, verbose=False): | |
img = Image.open(infile) | |
with open(outfile, 'wb') as outfile: | |
rgb_im = img.convert('RGB') | |
pix_buffer = 0 | |
for row in range(img.size[1]): | |
if not no_progress: | |
percent = float(((row + 1) // img.size[1]) * 100) | |
sys.stderr.write("\r%s%s" % (round(percent, 2), "%")) | |
for col in range(img.size[0]): | |
pixel = rgb_im.getpixel((col, row)) | |
for segment in pixel: | |
if segment == 0: | |
pix_buffer += 1 | |
else: | |
if pix_buffer != 0: | |
for color in range(pix_buffer): | |
# flush the cache to the file if a non-null byte was detected | |
if sys.version_info.major >= 3: | |
outfile.write(bytes([0])) | |
else: | |
outfile.write(chr(0)) | |
pix_buffer = 0 | |
if sys.version_info.major >= 3: | |
outfile.write(bytes([segment])) | |
else: | |
outfile.write(chr(segment)) | |
if not no_progress: | |
sys.stderr.write("\n") | |
if pix_buffer != 0 and verbose: | |
length = pix_buffer | |
if length == 1: | |
sys.stderr.write("Omitting %s zero from end of file\n" % pix_buffer) | |
else: # Why not... | |
sys.stderr.write("Omitting %s zeroes from end of file\n" % pix_buffer) | |
def file_to_png(infile, outfile): | |
reader = open(infile, 'rb') | |
dimensions = choose_file_dimensions(infile) | |
dim = (int(dimensions[0]), int(dimensions[1])) | |
img = Image.new('RGB', dim) | |
pixels = img.load() | |
row = 0 | |
column = -1 | |
while True: | |
b = reader.read(3) | |
if not b: | |
break | |
column += 1 | |
if column >= img.size[0]: | |
column = 0 | |
row += 1 | |
if row >= img.size[1]: | |
raise Exception("Error: row %s is greater than maximum rows in image, %s." % (row, img.size[1])) | |
color = [b[0], 0, 0] | |
if len(b) > 1: | |
color[1] = b[1] | |
if len(b) > 2: | |
color[2] = b[2] | |
if not row >= img.size[1]: | |
pixels[column, row] = tuple(color) | |
img.save(outfile, format="PNG") | |
reader.close() | |
#if name is main: | |
if __name__ == "__main__": | |
# if argv[1] is a png, convert it to a file | |
if sys.argv[1].endswith(".png"): | |
png_to_file(sys.argv[1], sys.argv[2]) | |
# if argv[1] is a file, convert it to a png | |
else: | |
file_to_png(sys.argv[1], sys.argv[2]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A minified version (via https://python-minifier.com/) in only 58 lines:
https://gist.github.com/rocket-pig/bff10850d03806c571184dc542250a05