bite-core 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
bite/__init__.py ADDED
@@ -0,0 +1,7 @@
1
+ from .bite import Bite
2
+
3
+ __all__ = [
4
+ "Bite"
5
+ ]
6
+
7
+ __version__ = "0.1.0"
bite/bite.py ADDED
@@ -0,0 +1,102 @@
1
+ class Bite:
2
+ def __init__(self, structures=None, palettes=None):
3
+ self.sprites = {}
4
+ self.palettes = {}
5
+
6
+ if structures is not None:
7
+ for sprite_id, structure in structures.items():
8
+ self.add_sprite(sprite_id, structure)
9
+
10
+ if palettes is not None:
11
+ for palette_id, colors in palettes.items():
12
+ self.add_palette(palette_id, **colors)
13
+
14
+ def add_sprite(self, sprite_id, structure):
15
+ if sprite_id in self.sprites:
16
+ raise ValueError(f"Sprite ID {sprite_id!r} already exists.")
17
+
18
+ sprite = Sprite(structure)
19
+ self.sprites[sprite_id] = sprite
20
+
21
+ return sprite
22
+
23
+ def get_sprite(self, sprite_id):
24
+ return self.sprites[sprite_id]
25
+
26
+ def add_palette(self, palette_id, foreground="black", background=""):
27
+ if palette_id in self.palettes:
28
+ raise ValueError(f"Palette ID {palette_id!r} already exists.")
29
+
30
+ palette = Palette(foreground, background)
31
+ self.palettes[palette_id] = palette
32
+
33
+ return palette
34
+
35
+ def get_palette(self, palette_id):
36
+ return self.palettes[palette_id]
37
+
38
+ class Sprite:
39
+ def __init__(self, structure):
40
+ if not structure or not structure[0]:
41
+ raise ValueError("The sprite cannot be empty.")
42
+
43
+ width = len(structure[0])
44
+
45
+ for row in structure:
46
+ if len(row) != width:
47
+ raise ValueError("All rows must have the same length.")
48
+
49
+ for pixel in row:
50
+ if type(pixel) is not int or pixel not in (0, 1):
51
+ raise ValueError("Pixels must be integers: 0 or 1.")
52
+
53
+ self.structure = [list(row) for row in structure]
54
+ self.width = width
55
+ self.height = len(structure)
56
+
57
+ def to_xbm(self):
58
+ values = []
59
+
60
+ for row in self.structure:
61
+ for start in range(0, self.width, 8):
62
+ byte = 0
63
+
64
+ for offset, pixel in enumerate(row[start:start + 8]):
65
+ byte |= pixel << offset
66
+
67
+ values.append(f"0x{byte:02x}")
68
+
69
+ return (
70
+ f"#define sprite_width {self.width}\n"
71
+ f"#define sprite_height {self.height}\n"
72
+ "static unsigned char sprite_bits[] = {\n"
73
+ + ", ".join(values)
74
+ + "\n};"
75
+ )
76
+
77
+ def resize(self, width, height):
78
+ if type(width) is not int or type(height) is not int:
79
+ raise ValueError("Width and height must be integers.")
80
+
81
+ if width <= 0 or height <= 0:
82
+ raise ValueError("Width and height must be greater than zero.")
83
+
84
+ structure = []
85
+
86
+ for y in range(height):
87
+ source_y = y * self.height // height
88
+ row = []
89
+
90
+ for x in range(width):
91
+ source_x = x * self.width // width
92
+ pixel = self.structure[source_y][source_x]
93
+ row.append(pixel)
94
+
95
+ structure.append(row)
96
+
97
+ return Sprite(structure)
98
+
99
+ class Palette:
100
+ def __init__(self, foreground="black", background=""):
101
+ self.foreground = foreground
102
+ self.background = background
@@ -0,0 +1,217 @@
1
+ Metadata-Version: 2.4
2
+ Name: bite-core
3
+ Version: 0.1.0
4
+ Summary: A lightweight library for managing binary sprites, palettes, resizing, and XBM conversion.
5
+ Author: Brianna Ladson
6
+ Keywords: bitmap,sprite,xbm,tkinter,pixel-art
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Operating System :: OS Independent
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Topic :: Multimedia :: Graphics
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Dynamic: license-file
15
+
16
+ # Bite v0.1.0
17
+
18
+ Bite is a lightweight Python library for managing binary sprites and color palettes, resizing sprites, and converting them into XBM data for use with Tkinter.
19
+
20
+ Define your sprites using 2D arrays of `0`s and `1`s, store them under unique IDs, and resize them to fit the pixel space you need.
21
+
22
+ ## Features
23
+
24
+ - Store multiple sprites under unique IDs.
25
+ - Define sprites using 2D arrays of binary integers.
26
+ - Store reusable foreground and background palettes.
27
+ - Resize sprites to an exact width and height using nearest-neighbor sampling.
28
+ - Convert sprite structures into XBM strings without writing XBM files.
29
+ - No third-party dependencies or Tkinter imports inside Bite.
30
+
31
+ Bite handles data. Your application creates and displays the images.
32
+
33
+ ## Setup
34
+
35
+ Place the package folder alongside your application:
36
+
37
+ - `bite/__init__.py`
38
+ - `bite/bite.py`
39
+ - `main.py`
40
+
41
+ Then import Bite:
42
+
43
+ ```python
44
+ from bite import Bite
45
+ ```
46
+
47
+ Bite itself uses standard Python features and requires no additional packages. The example below requires a Python installation with Tkinter available.
48
+
49
+ ## Quick Start
50
+
51
+ ```python
52
+ from bite import Bite
53
+
54
+ sprite_manager = Bite(
55
+ structures={
56
+ "house": [
57
+ [0, 0, 1, 0, 0],
58
+ [0, 1, 1, 1, 0],
59
+ [1, 1, 1, 1, 1],
60
+ [0, 1, 0, 1, 0],
61
+ [0, 1, 1, 1, 0],
62
+ ],
63
+ },
64
+ palettes={
65
+ "parchment": {
66
+ "foreground": "#69432b",
67
+ "background": "#f3dfac",
68
+ },
69
+ },
70
+ )
71
+
72
+ sprite = sprite_manager.get_sprite("house")
73
+ palette = sprite_manager.get_palette("parchment")
74
+
75
+ resized_sprite = sprite.resize(width=150, height=150)
76
+ bitmap_data = resized_sprite.to_xbm()
77
+ ```
78
+
79
+ ## Using Bite with Tkinter
80
+
81
+ This complete example creates a sprite, applies a palette, and displays a resized bitmap on a canvas.
82
+
83
+ ```python
84
+ from tkinter import Tk, Canvas, BitmapImage, BOTH
85
+ from bite import Bite
86
+
87
+ root = Tk()
88
+ root.title("Bite Demo")
89
+
90
+ canvas = Canvas(root, width=500, height=500)
91
+ canvas.pack(fill=BOTH, expand=True)
92
+
93
+ sprite_manager = Bite()
94
+
95
+ sprite_manager.add_sprite("house", [
96
+ [0, 0, 1, 0, 0],
97
+ [0, 1, 1, 1, 0],
98
+ [1, 1, 1, 1, 1],
99
+ [0, 1, 0, 1, 0],
100
+ [0, 1, 1, 1, 0],
101
+ ])
102
+
103
+ sprite_manager.add_palette(
104
+ "parchment",
105
+ foreground="#69432b",
106
+ background="#f3dfac",
107
+ )
108
+
109
+ sprite = sprite_manager.get_sprite("house")
110
+ palette = sprite_manager.get_palette("parchment")
111
+ resized_sprite = sprite.resize(150, 150)
112
+
113
+ image = BitmapImage(
114
+ master=root,
115
+ data=resized_sprite.to_xbm(),
116
+ foreground=palette.foreground,
117
+ background=palette.background,
118
+ )
119
+
120
+ canvas.create_image(250, 250, image=image)
121
+
122
+ root.mainloop()
123
+ ```
124
+
125
+ Keep a Python reference to each `BitmapImage` while it is displayed. For multiple images, you can store references in a list or dictionary.
126
+
127
+ ## Sprite Structures
128
+
129
+ Each inner list represents one row. All rows must have the same length, and every value must be the integer `0` or `1`.
130
+
131
+ - `1` uses the image's foreground color.
132
+ - `0` uses the image's background color.
133
+
134
+ Empty structures, uneven rows, and values other than integer `0` or `1` raise `ValueError`.
135
+
136
+ Bite copies the supplied rows when creating a sprite, so later changes to the original input array do not change the stored sprite.
137
+
138
+ ## Palettes
139
+
140
+ Palettes store color strings independently of sprites. The same sprite can be displayed with multiple palettes, and the same palette can be used with multiple sprites.
141
+
142
+ ```python
143
+ sprite_manager.add_palette(
144
+ "night",
145
+ foreground="lightblue",
146
+ background="midnightblue",
147
+ )
148
+
149
+ sprite_manager.add_palette(
150
+ "transparent",
151
+ foreground="darkgreen",
152
+ background="",
153
+ )
154
+ ```
155
+
156
+ Use an empty background string for transparent `0` pixels in Tkinter. Colors are passed through unchanged; Tkinter validates them when they are applied to an image.
157
+
158
+ To change an existing Tkinter image's palette:
159
+
160
+ ```python
161
+ palette = sprite_manager.get_palette("night")
162
+
163
+ image.configure(
164
+ foreground=palette.foreground,
165
+ background=palette.background,
166
+ )
167
+ ```
168
+
169
+ Palette colors are supplied separately to `BitmapImage`; they are not embedded in the XBM string. Changing a stored palette does not automatically update existing images.
170
+
171
+ ## Resizing
172
+
173
+ ```python
174
+ sprite = sprite_manager.get_sprite("house")
175
+ resized_sprite = sprite.resize(width=200, height=100)
176
+ ```
177
+
178
+ `resize()` returns a new sprite and leaves the original unchanged. Width and height must be positive integers.
179
+
180
+ The sprite is stretched to exactly the requested dimensions. Each axis scales independently, so the original aspect ratio is not automatically preserved. Nearest-neighbor sampling keeps all pixels binary, although shrinking can remove small details.
181
+
182
+ For repeated resizing, start from the original sprite rather than a previously resized version.
183
+
184
+ ## API Reference
185
+
186
+ ### Bite
187
+
188
+ | Method | Description |
189
+ | --- | --- |
190
+ | `Bite(structures=None, palettes=None)` | Create a manager, optionally with dictionaries of sprite structures and palette settings. |
191
+ | `add_sprite(sprite_id, structure)` | Create, store, and return a sprite. |
192
+ | `get_sprite(sprite_id)` | Return a stored sprite. |
193
+ | `add_palette(palette_id, foreground="black", background="")` | Create, store, and return a palette. |
194
+ | `get_palette(palette_id)` | Return a stored palette. |
195
+
196
+ Sprite IDs must be unique within `sprites`; palette IDs must be unique within `palettes`. The same ID can appear in both collections. Duplicate IDs raise `ValueError`; requesting a missing ID raises `KeyError`.
197
+
198
+ ### Sprite
199
+
200
+ Sprite objects are created and returned by Bite.
201
+
202
+ | Attribute or method | Description |
203
+ | --- | --- |
204
+ | `structure` | The stored 2D array of binary pixels. |
205
+ | `width` | Width of the sprite in pixels. |
206
+ | `height` | Height of the sprite in pixels. |
207
+ | `resize(width, height)` | Return a new sprite at the requested dimensions. |
208
+ | `to_xbm()` | Return an XBM-formatted string for the sprite. |
209
+
210
+ ### Palette
211
+
212
+ Palette objects are created and returned by Bite.
213
+
214
+ | Attribute | Description |
215
+ | --- | --- |
216
+ | `foreground` | Color used for `1` pixels. Defaults to `"black"`. |
217
+ | `background` | Color used for `0` pixels. Defaults to `""`. |
@@ -0,0 +1,7 @@
1
+ bite/__init__.py,sha256=XRwgDss8fY_Uz0B9qNqFyPK9EWAJdsc7BMqgJliJLp4,74
2
+ bite/bite.py,sha256=bQNtTByxxByPBGiLZ3_i1CXkVBHfvOfTyHLWZDj1a-0,2702
3
+ bite_core-0.1.0.dist-info/licenses/LICENSE,sha256=zVxpmR7YCpe1B2Z4rb9TdaHHM1SG_OJgRwexIcxJWfo,1071
4
+ bite_core-0.1.0.dist-info/METADATA,sha256=njO8XLNd5M-YkdRYHrfrQD9DJ8HTSEraBQRErGezbbw,6660
5
+ bite_core-0.1.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
6
+ bite_core-0.1.0.dist-info/top_level.txt,sha256=IT7j9yoYj5TGqEkIDx1s46OPJzrQsLtd42Hy66J6ybQ,5
7
+ bite_core-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Brianna Ladson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ bite