How to Upload Custom Images to Your GMK87 Keyboard
Personalize the built-in LCD display on your Zuoya GMK87 with custom images, photos, logos, or animated GIFs.
What the Display Supports
The GMK87 has a small LCD screen in the top-right corner of the keyboard. Here is what you need to know about it:
- Resolution 240 x 135 pixels — landscape orientation. Images are automatically resized to fit.
- Formats PNG, JPG, BMP, and GIF (including animated GIFs).
- Slots 2 image slots (slot 0 and slot 1). You can switch between them or show the clock.
- Animation Up to 36 total frames across both slots. For example, a 20-frame GIF in slot 0 and a 16-frame GIF in slot 1. Frames beyond 36 are automatically truncated.
- Display Three display modes: clock (default), slot 0, or slot 1.
Method 1: Using the Desktop App
The GMK87 Configurator app is the easiest way to upload images. It works on macOS, Windows, and Linux.
-
1
Download and open the app from the download section of the homepage.
-
2
Connect your GMK87 keyboard via USB. The app will detect it automatically.
-
3
Drag and drop your image onto the slot area (slot 0 or slot 1). The image will be resized and uploaded. You can also click the slot area to open a file picker.
-
4
Wait for the upload to finish. The display will show your image immediately after the upload completes.
Method 2: Using the CLI
The command-line interface gives you full control and is ideal for scripting or automation. Make sure you have Node.js 14+ installed.
Setup
git clone https://github.com/codedgar/gmk87-node.git
cd gmk87-node
npm install
Upload a single image to slot 0
npm run sendimage -- --file ./my-photo.png --slot 0
The image is automatically resized to 240x135 pixels. Any PNG, JPG, BMP, or GIF file works.
Upload a single image to slot 1
npm run sendimage -- --file ./logo.jpg --slot 1
Upload images to both slots at once
npm run sendimage -- --slot0 ./photo.png --slot1 ./logo.jpg
Uploading both slots at once is faster than uploading them separately because it only requires one USB upload session.
Upload an animated GIF
# Upload a GIF to slot 0 with default 100ms frame delay
npm run sendimage -- --file ./animation.gif --slot 0
# Upload with custom frame delay (150ms between frames)
npm run sendimage -- --file ./animation.gif --slot 0 --ms 150
# Upload GIFs to both slots with a shared frame delay
npm run sendimage -- --slot0 ./anim1.gif --slot1 ./anim2.gif --ms 120
The --ms flag sets the animation delay in milliseconds between frames. Minimum is 60ms. Default for GIFs is 100ms.
Control which slot is displayed
# When using --slot0/--slot1 mode, --show controls which slot to display after upload:
# 0 = show clock, 1 = show slot 0, 2 = show slot 1
npm run sendimage -- --slot0 ./photo.png --slot1 ./logo.jpg --show 2
Method 3: Using the Node.js API
You can integrate GMK87 image uploads into your own Node.js applications.
Install
npm install gmk87-hid-uploader
Upload a static image
import gmk87 from "gmk87-hid-uploader";
// Upload to slot 0 and display it
await gmk87.uploadImage("cat.png", 0, {
slot0File: "cat.png",
});
Upload images to both slots
import gmk87 from "gmk87-hid-uploader";
// Upload different images to each slot
await gmk87.uploadImage("cat.png", 0, {
slot0File: "cat.png",
slot1File: "dog.jpg",
});
Upload an animated GIF
import gmk87 from "gmk87-hid-uploader";
// Upload animated GIF with custom frame delay
await gmk87.uploadImage("nyan.gif", 0, {
slot0File: "nyan.gif",
frameDuration: 100, // ms between frames (min 60)
});
Switch the displayed slot
import gmk87 from "gmk87-hid-uploader";
// 0 = clock, 1 = slot 0, 2 = slot 1
await gmk87.showSlot(1); // Display slot 0
Image Tips
Optimal resolution
For the sharpest result, prepare your image at exactly 240 x 135 pixels before uploading. While any resolution works (images are auto-resized), starting at the native resolution avoids any scaling artifacts.
Aspect ratio
The display aspect ratio is roughly 16:9. Images with a different aspect ratio will be stretched to fit. If you want to avoid distortion, crop your image to 16:9 before uploading.
Transparency
The display does not support transparency. Transparent areas in PNG or GIF files will appear as black on the keyboard screen. If your image has a transparent background, add a solid background color before uploading.
Animated GIFs
The keyboard supports up to 36 total frames across both slots combined. If your GIF has more frames, they will be automatically truncated. For smooth animations, keep your GIF under 18 frames per slot if you are using both slots. Each frame uses about 32KB of flash storage.
Frame delay
The minimum animation delay is 60ms per frame. The default is 100ms (10 frames per second). You can set a custom delay with the --ms CLI flag or the frameDuration API option. The original GIF timing is not preserved — all frames use the same delay.
Color depth
The display uses RGB565 (16-bit color). Very subtle gradients may show visible banding. Bold, high-contrast images tend to look best on the small screen.