Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- # img2py: Convert a black and white image to a pyimage.
- # Copyright (C) 2022 Jeffry Johnston
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <https://www.gnu.org/licenses/>.
- import sys
- from PIL import Image
- # Parse command line arguments
- if len(sys.argv) != 3:
- sys.exit(f"Usage: {sys.argv[0]} B&W_IMAGE.png VAR_NAME")
- filename = sys.argv[1]
- var_name = sys.argv[2]
- # Convert every 7 image pixels to one ASCII character
- with Image.open(filename) as im:
- width, height = im.size
- value = 0
- bits = 0
- original_data: list[int] = [1, width, height]
- for y in range(height):
- for x in range(width):
- data = im.getpixel((x, y)) # type: ignore
- pixel = int(
- (data[0] if type(data) is tuple else data) == 0 # type: ignore
- )
- # This "backward" bit order was chosen for a few reasons:
- # 1) Trivial to decode with & and >>
- # 2) Any needed padding bits at the end of the image are automatic
- # and their presence can be completely ignored by the decoder
- # 3) No special case when the last character is padded and repeated
- value |= pixel << bits
- bits += 1
- if bits >= 7:
- original_data.append(value)
- value = 0
- bits = 0
- if bits > 0:
- original_data.append(value)
- # Determine which bytes are used
- dist: dict[int, int] = {}
- for i in range(128):
- dist[i] = False
- for i in original_data:
- dist[i] = True
- used = [i for i in dist if dist[i]]
- # Add an offset to each byte in the hopes of avoiding restricted characters
- for offset in range(128):
- invalid = False
- for i in [0, 10, 13, 34, 92]:
- if i in used:
- invalid = True
- break
- if not invalid:
- break
- for j in range(len(used)):
- used[j] = (used[j] + 1) % 128
- else:
- sys.exit("Failed to find a valid offset")
- # Convert data to a Python string
- offset_data = "".join([chr((i + offset) % 128) for i in original_data])
- var_str = f"{var_name}=b\"{offset_data}\""
- # Write output
- sys.stdout.buffer.write(var_str.encode("latin1"))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement