RORK LABJP
RORKMAX — Rork Max builds native Swift apps instead of React Native, targeting iPhone, iPad, Apple Watch, Apple TV, Vision Pro, and iMessageNATIVE — Rork Max unlocks capabilities React Native can't reach: AR/LiDAR, Metal 3D, widgets, Dynamic Island, Live Activities, HealthKit, HomeKit, NFC, and Core MLPUBLISH — Two-click App Store publishing cuts the steps between generating an app and shipping itSIM — A browser-based streaming iOS simulator lets you test in a real Apple environment without Xcode or a MacSTANDARD — Standard Rork turns a plain-English description into working React Native (Expo) codePRICING — It's free to start, paid plans begin at $25/month, and Rork Max is $200/monthRORKMAX — Rork Max builds native Swift apps instead of React Native, targeting iPhone, iPad, Apple Watch, Apple TV, Vision Pro, and iMessageNATIVE — Rork Max unlocks capabilities React Native can't reach: AR/LiDAR, Metal 3D, widgets, Dynamic Island, Live Activities, HealthKit, HomeKit, NFC, and Core MLPUBLISH — Two-click App Store publishing cuts the steps between generating an app and shipping itSIM — A browser-based streaming iOS simulator lets you test in a real Apple environment without Xcode or a MacSTANDARD — Standard Rork turns a plain-English description into working React Native (Expo) codePRICING — It's free to start, paid plans begin at $25/month, and Rork Max is $200/month
Articles/App Dev
App Dev/2026-06-04Intermediate

How I Localized My Play Store Screenshots into 16 Languages — Swapping PSD Text with Python and Standardizing on Noto Fonts

An implementation log of localizing an Android wallpaper app's store screenshots into 16 languages: swapping PSD text layers per language with Python, auto-shrinking overflow, and assigning the right font per script — with the actual code and a font cheat sheet.

ASO27Localization8Google Play21PSDFontsIndie Dev36

Premium Article

"Make sixteen languages of store screenshots." It's one sentence to say, but the moment you pour translated copy into a finished design, you hit a dull wall: the layout breaks. German runs about 1.8× longer than Japanese and overflows the button. Arabic flows right-to-left and flips everything. Korean and Thai don't even have glyphs in the font you have on hand. I've been building iOS and Android wallpaper apps on my own since 2014 — they've grown past 50 million cumulative downloads — and this "make the final look right" stage is still what eats the most time.

I recently rebuilt the store screenshots for the Android app Beautiful Wallpapers (Beautiful Wallpapers on Google Play) into 16 languages: English, Spanish, French, German, and the rest. Instead of retyping 16 languages × 5 frames by hand in Photoshop, I switched to swapping the PSD's text layers per language with Python, and the job got noticeably lighter. This article is that implementation log. Not clean theory — the code I actually ran, the places I tripped, and the cheat sheet of which font I assigned to which language.

Why swap the text instead of baking it into pixels

Let me start with the approach. When people think "automate multilingual screenshots," the first idea is usually to render each language's text as an image and composite it onto the background (a transparent overlay PNG). I built that too. But it has a weakness: you can't change the font afterward.

With the overlay approach, the text is frozen into pixels the moment you generate it. If you later decide "the Korean heading should be a touch bolder," your only option is to re-run the script. As an indie dev, I want to do the final visual tweaks in Photoshop, by hand, to the very end.

So the approach I committed to was swapping only the string, per language, without rasterizing the text layer. I duplicate the original Japanese type layers, replace the string inside with the translation, and produce an "editable text PSD." Drag a language group onto the master and it lands in the exact same spot, with the font and size still fully editable in Photoshop. In practice, that single property was the biggest win.

For the record: I use none of this automation on the artwork itself (the wallpapers). The automation is strictly for the store-listing side — operations and promotion. I keep that line fixed.

Understand the source structure first

The source PSD was 1440 × 13333px with five artboards stacked vertically, each 1440 × 2560px (9:16). There are about 40 text layers total — title, subtitle, feature bullets, number badges — distributed across the artboards.

The first job is to make those text layers machine-pickable. With psd-tools you can recurse into groups and pull out only the layers where kind == 'type'.

from psd_tools import PSDImage
 
def find_types(layers):
    """Recurse through groups and yield only text layers."""
    for layer in layers:
        if layer.kind == 'type':
            yield layer
        if layer.is_group():
            yield from find_types(layer)
 
src = PSDImage.open("screenshot.psd")
for t in find_types(src):
    # layer.text is the visible string, layer.bbox is the coordinates
    print(repr(t.text), t.bbox)

layer.text gives the visible string and layer.bbox gives (left, top, right, bottom). By checking which artboard's range a layer's top falls into, you can mechanically decide "this line is the heading of screenshot 5." Keep a translation dictionary keyed on the original Japanese string (TR[japanese] = {"en": "...", "de": "...", ...}) and the layer matches its translation cleanly through layer.text.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
If you've been stuck where the translation is fine but the layout breaks every single time, you'll get a repeatable workflow that swaps PSD text per language and auto-shrinks overflow
You'll learn the real psd-tools code that edits text layers without rasterizing, plus a per-language cheat sheet of which Noto font to assign for Cyrillic, Hangul, Thai, and Arabic
You'll be able to mass-produce 16 languages of screenshots with a script instead of by hand, and apply the same flow to your own app's store presence
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

App Dev2026-07-09
You Only Need to Capture the 6.9-inch iPhone for App Store Screenshots
App Store Connect only requires two screenshot sizes: the 6.9-inch iPhone and the 13-inch iPad. Building on Apple auto-downscaling for smaller devices, here is how I use fastlane snapshot and frameit to cut the screenshot count for a multi-language app.
App Dev2026-03-22
The Complete App Store Visual Strategy — Icons, Screenshots, and Preview Videos
Comprehensive guide to all app store visual assets: icons, screenshots, feature graphics, and preview videos. Master ASO strategy, A/B testing, and the complete workflow from design to store launch.
App Dev2026-03-22
How to Create App Store Screenshots with Figma for iOS and Android
Master app store screenshot design for both App Store and Google Play. Learn Figma workflows, device mockups, export settings, and multi-language strategies from concept to publish-ready assets.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →