Skip to content

Instantly share code, notes, and snippets.

@rocket-pig
Created March 26, 2022 07:24
Show Gist options
  • Save rocket-pig/c8e29296fa7f462d7fd8e8fe642ad5c2 to your computer and use it in GitHub Desktop.
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)
#!/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])
@rocket-pig
Copy link
Author

rocket-pig commented Mar 26, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment