Created
May 1, 2025 16:08
-
-
Save patakk/4c85c99ba68429563790c1c0556c4654 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from PIL import Image | |
import struct | |
import os | |
import re | |
def gb2312_offset(char, size): | |
gb = char.encode('gb2312') | |
area = gb[0] - 0xA1 | |
index = gb[1] - 0xA1 | |
bytes_per_char = size * size // 8 | |
return (94 * area + index) * bytes_per_char | |
def read_bitmap(char, font_path, size): | |
bytes_per_char = size * size // 8 | |
offset = gb2312_offset(char, size) | |
file_size = os.path.getsize(font_path) | |
if offset + bytes_per_char > file_size: | |
raise ValueError("Offset out of bounds") | |
with open(font_path, 'rb') as f: | |
f.seek(offset) | |
data = f.read(bytes_per_char) | |
if not any(data): | |
raise ValueError("Bitmap is all zeros") | |
return data | |
def bitmap_to_pil(bitmap_bytes, size): | |
img = Image.new('1', (size, size), 0) | |
pixels = img.load() | |
row_bytes = size // 8 | |
for y in range(size): | |
for x in range(size): | |
byte_index = y * row_bytes + x // 8 | |
if byte_index >= len(bitmap_bytes): | |
continue | |
byte = bitmap_bytes[byte_index] | |
if byte & (1 << (7 - (x % 8))): | |
pixels[x, y] = 1 | |
return img | |
def concat_pil_images_horizontally(images): | |
widths, heights = zip(*(i.size for i in images)) | |
total_width = sum(widths) | |
max_height = max(heights) | |
new_image = Image.new('RGB', (total_width, max_height)) | |
x_offset = 0 | |
for img in images: | |
new_image.paste(img.convert('RGB'), (x_offset, 0)) | |
x_offset += img.width | |
return new_image | |
def infer_size_from_filename(name): | |
m = re.search(r'(\d+)', name) | |
return int(m.group(1)) if m else 16 | |
scale = 5 | |
font_dir = 'BitmapFont/font' | |
fonts = sorted(os.listdir(font_dir)) | |
for char in '他是一个老师': | |
font_samples = [] | |
for fontname in fonts: | |
path = os.path.join(font_dir, fontname) | |
try: | |
size = infer_size_from_filename(fontname.upper()) | |
print(size) | |
bitmap = read_bitmap(char, path, size) | |
img = bitmap_to_pil(bitmap, size) | |
img = img.resize((size*scale, size*scale), resample=Image.NEAREST) | |
font_samples.append(img) | |
except Exception as e: | |
print(f"Skipping {fontname}: {e}") | |
img_row = concat_pil_images_horizontally(font_samples) | |
#display(img_row) | |
img_row.save(f'output/{char}.png') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment