feature/event-customization-2024 #2
| @@ -1,5 +1,7 @@ | ||||
| # 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! | ||||
|  | ||||
| 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 | ||||
|     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)     | ||||
|  | ||||
|     pprint(display, "Engineering", 125, 56, 0) | ||||
|     pprint(display, "Offsite", 125, 66, 0) | ||||
|     pprint(display, "Brooklyn", 125, 76, 0) | ||||
|     pprint(display, "2022", 125, 86, 0) | ||||
|     pprint(display, "AWS Summit", 125, 56, 0) | ||||
|     pprint(display, "---", 125, 66, 0) | ||||
|     pprint(display, "Milan (Italy)", 125, 76, 0) | ||||
|     pprint(display, "2024", 125, 86, 0) | ||||
|  | ||||
| def render(): | ||||
|     display.pen(15) | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| https://getcensus.com/ | ||||
| Census | ||||
| * the leading reverse ETL | ||||
| * no more CSV files | ||||
| * sync data in real-time | ||||
| https://marianosciacco.it/publications/qrfuzz-paper/ | ||||
| Mariano Sciacco | ||||
| * IoT & Cloud Engineer | ||||
| * Vimar S.p.A. | ||||
| * (AWS Summit 2024) | ||||
|  | ||||
| Scan this code to learn | ||||
| more about Census. | ||||
| If You’re Scanning This, It’s Too Late!  | ||||
| @@ -226,10 +226,10 @@ def draw_border(display): | ||||
|     display.line(1,   1,   1,   127) | ||||
|     display.line(1,   127, 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((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): | ||||
|     return (((input - in_min) * (out_max - out_min)) / (in_max - in_min)) + out_min | ||||
|   | ||||
		Reference in New Issue
	
	Block a user