<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: SHOTARO</title>
    <description>The latest articles on DEV Community by SHOTARO (@oshio_0bffeb2fb927538e835).</description>
    <link>https://dev.to/oshio_0bffeb2fb927538e835</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4142257%2F43d7beb3-61a0-4f4c-b3dc-3075df02a963.jpeg</url>
      <title>DEV Community: SHOTARO</title>
      <link>https://dev.to/oshio_0bffeb2fb927538e835</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oshio_0bffeb2fb927538e835"/>
    <language>en</language>
    <item>
      <title>I spent hours on App Store screenshots, so I built a tool that makes them</title>
      <dc:creator>SHOTARO</dc:creator>
      <pubDate>Fri, 25 Sep 2026 05:34:02 +0000</pubDate>
      <link>https://dev.to/oshio_0bffeb2fb927538e835/i-spent-hours-on-app-store-screenshots-so-i-built-a-tool-that-makes-them-6a9</link>
      <guid>https://dev.to/oshio_0bffeb2fb927538e835/i-spent-hours-on-app-store-screenshots-so-i-built-a-tool-that-makes-them-6a9</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Febrvim0rg3ynd08341i2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Febrvim0rg3ynd08341i2.png" alt=" " width="800" height="740"&gt;&lt;/a&gt;&lt;br&gt;
The most useful thing I learned building this: if you want an image model to&lt;br&gt;
work well with text, don't let it touch the text at all. Print the text first,&lt;br&gt;
then let the model paint around it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Watch it turn app screens into a full screenshot set
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/R9AWfuh9W9k" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;When my app was ready for the App Store, I thought the hard part was over. Then&lt;br&gt;
I got to the screenshots. Deciding what each one should say, finding a device&lt;br&gt;
frame, lining everything up, exporting at the exact size Apple wants. None of&lt;br&gt;
it was hard on its own, but it took me hours.&lt;/p&gt;

&lt;p&gt;So I built sukuji. You upload a few screens from your app and get five App&lt;br&gt;
Store screenshots back at 1290x2796, each with a headline, your screen in a&lt;br&gt;
device frame, and a designed background.&lt;/p&gt;

&lt;p&gt;Under the hood, Gemini plans the set and writes the headlines, and GPT Image&lt;br&gt;
paints the artwork. Getting those two to cooperate taught me a few things.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 1: Print the text before the model sees the canvas
&lt;/h2&gt;

&lt;p&gt;Image models have gotten much better at text, especially in English. But I&lt;br&gt;
still didn't want the model writing my headlines. I wanted the same typeface&lt;br&gt;
and size across all five images, a font I chose rather than one it picked, and&lt;br&gt;
text that doesn't change shape every time I regenerate. And a single wrong&lt;br&gt;
letter means redoing the whole image. So the headline was always typeset in&lt;br&gt;
code and added afterwards.&lt;/p&gt;

&lt;p&gt;That created a different problem. The model had no idea where the headline&lt;br&gt;
would go, so it happily put a floating object right where the words would&lt;br&gt;
land. Telling it to "leave the top of the image empty" helped a little, but not&lt;br&gt;
reliably.&lt;/p&gt;

&lt;p&gt;What worked was flipping the order. Now the headline is printed onto the canvas&lt;br&gt;
first, next to the phone, and only then does the model paint. It can see the&lt;br&gt;
words, so it works around them instead of guessing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 2: "Don't touch" means "right next to"
&lt;/h2&gt;

&lt;p&gt;Even with the text printed, objects kept crowding it. My prompt said nothing&lt;br&gt;
may touch the letters. The model obeyed: things stopped just short of the&lt;br&gt;
words, practically leaning on them.&lt;/p&gt;

&lt;p&gt;Technically, nothing touched. The fix was to stop describing a line and start&lt;br&gt;
describing a space: a clear zone around the text, measured out, with the rule&lt;br&gt;
that coming close counts as failing. Once "close" was defined as a failure, the&lt;br&gt;
crowding mostly stopped.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 3: "Entirely" means entirely
&lt;/h2&gt;

&lt;p&gt;For the opening image there's no phone, just the character from your app on a&lt;br&gt;
plain background. My prompt told the model to replace that plain background&lt;br&gt;
entirely with a scene.&lt;/p&gt;

&lt;p&gt;It did, headline and all. The text I had printed onto the canvas was gone. The&lt;br&gt;
fix was one sentence: the printed headline is the one exception, and it stays&lt;br&gt;
exactly as it is.&lt;/p&gt;

&lt;p&gt;All three lessons are the same lesson, really. Image models take your words&lt;br&gt;
literally, so the exceptions have to be spelled out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: headlines that say nothing
&lt;/h2&gt;

&lt;p&gt;Someone on Reddit pointed out that screenshot tools fail when the headline just&lt;br&gt;
restates the icon: "Track your habits" for a habit app. They were right.&lt;/p&gt;

&lt;p&gt;Now each headline has to come from something specific on that screen, and the&lt;br&gt;
model asks itself one question before keeping a line: would this work just as&lt;br&gt;
well for a competitor? If yes, it rewrites it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two weeks in
&lt;/h2&gt;

&lt;p&gt;I launched in Japan first and added English later. After two weeks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;about 960 visitors&lt;/li&gt;
&lt;li&gt;333 screenshot sets generated&lt;/li&gt;
&lt;li&gt;about $0.14 in image generation per run&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That cost is why it's limited to two runs a day. It's free for now, with no&lt;br&gt;
account needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://sukuji.com" rel="noopener noreferrer"&gt;https://sukuji.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'd love to hear where it falls short, especially if the headlines come out&lt;br&gt;
generic for your app.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>ios</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
