UpSkill & CodeArchivist
You ever hear of the 1988 bitmap editor PixelForge? I’ve got a clean copy of the software and its raw file format is still a mystery. Think you could whip up a tiny ML script to find its icons and maybe revive the UI? I’m not touching any rounded corners though.
Sure thing. I’ll give you a bare‑bones Python script that uses OpenCV and a tiny convolutional net to scan the raw files for icon‑like blobs. No rounded corners, just hard squares.
```python
import cv2
import numpy as np
import glob
import os
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
# ---------- 1️⃣ Build a super‑tiny classifier ----------
def build_model():
model = Sequential([
Conv2D(8, (3,3), activation='relu', input_shape=(32,32,1)),
MaxPooling2D((2,2)),
Flatten(),
Dense(2, activation='softmax') # 0=background, 1=icon
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model
model = build_model()
# ---------- 2️⃣ Train it on a few hand‑labeled examples ----------
# For brevity, assume you already have `X_train.npy` and `y_train.npy`
# from a quick manual crop of icons vs background.
X = np.load('X_train.npy') # shape (N,32,32,1)
y = np.load('y_train.npy') # shape (N,)
model.fit(X, y, epochs=5, batch_size=8)
# ---------- 3️⃣ Scan raw files ----------
def load_raw(path):
with open(path, 'rb') as f:
return np.frombuffer(f.read(), dtype=np.uint8)
def find_icons(raw, width=256, height=256):
# reshape raw to image
img = raw.reshape((height, width))
icons = []
for y in range(0, height, 32):
for x in range(0, width, 32):
patch = img[y:y+32, x:x+32].reshape(1,32,32,1)
pred = model.predict(patch, verbose=0)[0][1]
if pred > 0.8: # confident icon
icons.append((x, y, patch.squeeze()))
return icons
# Process all raw files in folder
for f in glob.glob('raw_files/*.raw'):
raw = load_raw(f)
icons = find_icons(raw)
print(f'{f}: found {len(icons)} icons')
# Optionally save them
for i, (x, y, patch) in enumerate(icons):
cv2.imwrite(f'{os.path.splitext(f)[0]}_icon_{i}.png',
patch*255)
```
Just tweak `width`/`height` to match PixelForge’s canvas size.
The tiny net will flag anything that looks like a 32×32 square icon.
After you’ve pulled the icons out, you can stitch them back into a new UI mock‑up with Photoshop or GIMP—no rounded corners needed.
Happy hacking!
Nice script, but don’t forget the old files are in 1‑byte per pixel, not 8‑bit grayscale. You’ll need to cast to `uint8` before reshaping, or the convolution will throw a fit. Also, PixelForge’s icons were padded with a single‑pixel border; the net might mistake that for a rounded corner. Adjust the threshold or add a padding layer in the training data. Once you pull them out, just copy the raw PNGs into an old Win16 style frame—no curves, just straight edges. Happy restoring!
Got it, I’ll drop the extra cast right in the loader so the net sees clean uint8 pixels. I’ll also add a 1‑pixel padding layer to the training patches so the border isn’t confused with a corner. The threshold can be nudged up to 0.85 to keep the false positives to a minimum. Here’s the quick tweak:
```
def load_raw(path):
with open(path, 'rb') as f:
raw = np.frombuffer(f.read(), dtype=np.uint8) # already uint8
return raw
# pad each patch with a one‑pixel border of zeros
def pad_patch(patch):
return np.pad(patch, ((1,1),(1,1)), mode='constant', constant_values=0)
# during training:
X_padded = np.array([pad_patch(p) for p in X])
model.fit(X_padded, y, epochs=5, batch_size=8)
```
When you run the scanner, it will skip the border and only flag the icon content. Then copy the PNGs into your Win16 frame, straight edges all the way. Happy restoring!
Good call on the padding – those single‑pixel borders were always a pain. Just make sure the model’s input layer still expects 32×32 after padding; otherwise it’ll read the extra pixels as part of the icon. Also, if you hit any false positives later, try increasing the stride in `find_icons` to skip overlapping windows. Once the PNGs are ready, stick them into a plain‑box frame and give me a shout – I’ll test it against my own copy of PixelForge’s splash screen. Happy restoring!
Got it, I’ll keep the model at 32×32 and do the padding inside the training data only, so the net never sees the extra border. I’ll bump the stride in the scanner to 32 instead of 16 to cut overlapping windows, which should reduce false positives. Once the PNGs are dumped, I’ll drop them into a plain‑box frame and ping you. Happy restoring!