feature/event-customization-2024 #2
| @@ -1,5 +1,7 @@ | |||||||
| # Badger2040 System II | # Badger2040 System II | ||||||
|  |  | ||||||
|  | > Forked from https://github.com/oneearedrabbit/badger-system-ii | ||||||
|  |  | ||||||
| Tired of boring badges that just blend in with the crowd? You want to show off your quirky personality and love of retro technology? You are looking for a fun project to bond with your engineering team? Look no further than the programmable e-ink badge! | Tired of boring badges that just blend in with the crowd? You want to show off your quirky personality and love of retro technology? You are looking for a fun project to bond with your engineering team? Look no further than the programmable e-ink badge! | ||||||
|  |  | ||||||
| https://kruzenshtern.org/the-e-ink-badge-the-coolest-badge-you-didnt-know-you-needed/ | https://kruzenshtern.org/the-e-ink-badge-the-coolest-badge-you-didnt-know-you-needed/ | ||||||
|   | |||||||
							
								
								
									
										136
									
								
								scripts/convert.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								scripts/convert.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | |||||||
|  | #!/usr/bin/env python3 | ||||||
|  | """ | ||||||
|  | Converts images into a format suitable for display on Badger 2040. | ||||||
|  |  | ||||||
|  | Optionally resizes images to 296x128 to fit the display. | ||||||
|  |  | ||||||
|  | Crunches images down to dithered, 1bit colour depth. | ||||||
|  |  | ||||||
|  | Outputs either in raw binary format or as a .py file for embedding into MicroPython. | ||||||
|  |  | ||||||
|  | Output to py functionality is borrwed from data_to_py.py, Copyright (c) 2016 Peter Hinch | ||||||
|  | """ | ||||||
|  |  | ||||||
|  | import io | ||||||
|  | import argparse | ||||||
|  | from PIL import Image, ImageEnhance | ||||||
|  | from pathlib import Path | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PY_HEADER = """# Code generated by convert.py. | ||||||
|  | """ | ||||||
|  |  | ||||||
|  | PY_FOOTER = """_mvdata = memoryview(_data) | ||||||
|  |  | ||||||
|  | def data(): | ||||||
|  |     return _mvdata | ||||||
|  |  | ||||||
|  | """ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | parser = argparse.ArgumentParser(description='Converts images into the format used by Badger2040.') | ||||||
|  | parser.add_argument('file', nargs="+", help='input files to convert') | ||||||
|  | parser.add_argument('--out_dir', type=Path, default=None, help='output directory') | ||||||
|  | parser.add_argument('--binary', action="store_true", help='output binary file for MicroPython') | ||||||
|  | parser.add_argument('--py', action="store_true", help='output .py file for MicroPython embedding') | ||||||
|  | parser.add_argument('--resize', action="store_true", help='force images to 296x128 pixels') | ||||||
|  |  | ||||||
|  | options = parser.parse_args() | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class ByteWriter(object): | ||||||
|  |     bytes_per_line = 16 | ||||||
|  |  | ||||||
|  |     def __init__(self, stream, varname): | ||||||
|  |         self.stream = stream | ||||||
|  |         self.stream.write('{} =\\\n'.format(varname)) | ||||||
|  |         self.bytecount = 0  # For line breaks | ||||||
|  |  | ||||||
|  |     def _eol(self): | ||||||
|  |         self.stream.write("'\\\n") | ||||||
|  |  | ||||||
|  |     def _eot(self): | ||||||
|  |         self.stream.write("'\n") | ||||||
|  |  | ||||||
|  |     def _bol(self): | ||||||
|  |         self.stream.write("b'") | ||||||
|  |  | ||||||
|  |     # Output a single byte | ||||||
|  |     def obyte(self, data): | ||||||
|  |         if not self.bytecount: | ||||||
|  |             self._bol() | ||||||
|  |         self.stream.write('\\x{:02x}'.format(data)) | ||||||
|  |         self.bytecount += 1 | ||||||
|  |         self.bytecount %= self.bytes_per_line | ||||||
|  |         if not self.bytecount: | ||||||
|  |             self._eol() | ||||||
|  |  | ||||||
|  |     # Output from a sequence | ||||||
|  |     def odata(self, bytelist): | ||||||
|  |         for byt in bytelist: | ||||||
|  |             self.obyte(byt) | ||||||
|  |  | ||||||
|  |     # ensure a correct final line | ||||||
|  |     def eot(self):  # User force EOL if one hasn't occurred | ||||||
|  |         if self.bytecount: | ||||||
|  |             self._eot() | ||||||
|  |         self.stream.write('\n') | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def convert_image(img): | ||||||
|  |     if options.resize: | ||||||
|  |         img = img.resize((296, 128))  # resize | ||||||
|  |     try: | ||||||
|  |         enhancer = ImageEnhance.Contrast(img) | ||||||
|  |         img = enhancer.enhance(2.0) | ||||||
|  |     except ValueError: | ||||||
|  |         pass | ||||||
|  |     img = img.convert("1")  # convert to black and white | ||||||
|  |     return img | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def write_stream(header, footer, ip_stream, op_stream): | ||||||
|  |     op_stream.write(header) | ||||||
|  |     op_stream.write('\n') | ||||||
|  |     data = ip_stream.read() | ||||||
|  |     bw_data = ByteWriter(op_stream, '_data') | ||||||
|  |     bw_data.odata(data) | ||||||
|  |     bw_data.eot() | ||||||
|  |     op_stream.write(footer) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # create map of images based on input filenames | ||||||
|  | for input_filename in options.file: | ||||||
|  |     with Image.open(input_filename) as img: | ||||||
|  |         img = convert_image(img) | ||||||
|  |  | ||||||
|  |         image_name = Path(input_filename).stem | ||||||
|  |  | ||||||
|  |         w, h = img.size | ||||||
|  |  | ||||||
|  |         output_data = [~b & 0xff for b in list(img.tobytes())] | ||||||
|  |  | ||||||
|  |         if options.binary: | ||||||
|  |             if options.out_dir is not None: | ||||||
|  |                 output_filename = (options.out_dir / image_name).with_suffix(".bin") | ||||||
|  |             else: | ||||||
|  |                 output_filename = Path(input_filename).with_suffix(".bin") | ||||||
|  |             print(f"Saving to {output_filename}, {w}x{h}") | ||||||
|  |             with open(output_filename, "wb") as out: | ||||||
|  |                 out.write(bytearray(output_data)) | ||||||
|  |         elif options.py: | ||||||
|  |             if options.out_dir is not None: | ||||||
|  |                 output_filename = (options.out_dir / image_name).with_suffix(".py") | ||||||
|  |             else: | ||||||
|  |                 output_filename = Path(input_filename).with_suffix(".py") | ||||||
|  |             print(f"Saving to {output_filename}, {w}x{h}") | ||||||
|  |             with open(output_filename, "w") as out: | ||||||
|  |                 write_stream(PY_HEADER, PY_FOOTER, io.BytesIO(bytes(output_data)), out) | ||||||
|  |         else: | ||||||
|  |             image_code = '''\ | ||||||
|  | static const uint8_t {image_name}[{count}] = {{ | ||||||
|  |     {byte_data} | ||||||
|  | }}; | ||||||
|  |     '''.format(image_name=image_name, count=len(output_data), byte_data=", ".join(str(b) for b in output_data)) | ||||||
|  |  | ||||||
|  |             print(image_code) | ||||||
							
								
								
									
										
											BIN
										
									
								
								scripts/logo.bin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								scripts/logo.bin
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								scripts/logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								scripts/logo.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 767 B | 
							
								
								
									
										
											BIN
										
									
								
								scripts/mariano.jpeg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								scripts/mariano.jpeg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 74 KiB | 
							
								
								
									
										
											BIN
										
									
								
								scripts/vimar-logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								scripts/vimar-logo.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 2.4 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/images/logo.bin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/images/logo.bin
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								src/images/logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/images/logo.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 767 B | 
| @@ -34,13 +34,13 @@ def draw_about(): | |||||||
|          |          | ||||||
|     # logo |     # logo | ||||||
|     image = bytearray(int(32 * 32 / 8)) |     image = bytearray(int(32 * 32 / 8)) | ||||||
|     open("images/{}".format("census.bin"), "r").readinto(image) |     open("images/{}".format("logo.bin"), "r").readinto(image) | ||||||
|     display.image(image, 32, 32, 86, 56)     |     display.image(image, 32, 32, 86, 56)     | ||||||
|  |  | ||||||
|     pprint(display, "Engineering", 125, 56, 0) |     pprint(display, "AWS Summit", 125, 56, 0) | ||||||
|     pprint(display, "Offsite", 125, 66, 0) |     pprint(display, "---", 125, 66, 0) | ||||||
|     pprint(display, "Brooklyn", 125, 76, 0) |     pprint(display, "Milan (Italy)", 125, 76, 0) | ||||||
|     pprint(display, "2022", 125, 86, 0) |     pprint(display, "2024", 125, 86, 0) | ||||||
|  |  | ||||||
| def render(): | def render(): | ||||||
|     display.pen(15) |     display.pen(15) | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| https://getcensus.com/ | https://marianosciacco.it/publications/qrfuzz-paper/ | ||||||
| Census | Mariano Sciacco | ||||||
| * the leading reverse ETL | * IoT & Cloud Engineer | ||||||
| * no more CSV files | * Vimar S.p.A. | ||||||
| * sync data in real-time | * (AWS Summit 2024) | ||||||
|  |  | ||||||
| Scan this code to learn | If You’re Scanning This, It’s Too Late!  | ||||||
| more about Census. |  | ||||||
| @@ -226,10 +226,10 @@ def draw_border(display): | |||||||
|     display.line(1,   1,   1,   127) |     display.line(1,   1,   1,   127) | ||||||
|     display.line(1,   127, 295, 127) |     display.line(1,   127, 295, 127) | ||||||
|     display.line(295, 1,   295, 127) |     display.line(295, 1,   295, 127) | ||||||
|     display.image(bytearray((0xff, 0xff, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0xc0)), 8, 8, 0, 0) |     display.image(bytearray((0xff, 0xff, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0xc0)), 2, 2, 0, 0) | ||||||
|     display.image(bytearray((0xff, 0xff, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x03)), 8, 8, 288, 0) |     display.image(bytearray((0xff, 0xff, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x03)), 8, 8, 288, 0) | ||||||
|     display.image(bytearray((0x03, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0xff, 0xff)), 8, 8, 288, 120) |     display.image(bytearray((0x03, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0xff, 0xff)), 8, 8, 288, 120) | ||||||
|     display.image(bytearray((0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xff, 0xff)), 8, 8, 0, 120) |     display.image(bytearray((0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xff, 0xff)), 2, 2, 0, 120) | ||||||
|  |  | ||||||
| def map_value(input, in_min, in_max, out_min, out_max): | def map_value(input, in_min, in_max, out_min, out_max): | ||||||
|     return (((input - in_min) * (out_max - out_min)) / (in_max - in_min)) + out_min |     return (((input - in_min) * (out_max - out_min)) / (in_max - in_min)) + out_min | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user