<?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: celticgemini001</title>
    <description>The latest articles on DEV Community by celticgemini001 (@celticgemini001).</description>
    <link>https://dev.to/celticgemini001</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%2F4233848%2F296f5ea7-82c1-401c-a8f4-96364f651175.png</url>
      <title>DEV Community: celticgemini001</title>
      <link>https://dev.to/celticgemini001</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/celticgemini001"/>
    <language>en</language>
    <item>
      <title>Restore a blurry old family photo: scan, repair, sharpen, then print</title>
      <dc:creator>celticgemini001</dc:creator>
      <pubDate>Sun, 08 Nov 2026 18:05:13 +0000</pubDate>
      <link>https://dev.to/celticgemini001/restore-a-blurry-old-family-photo-scan-repair-sharpen-then-print-eic</link>
      <guid>https://dev.to/celticgemini001/restore-a-blurry-old-family-photo-scan-repair-sharpen-then-print-eic</guid>
      <description>&lt;p&gt;Old photos fail in two separate layers: physical damage (fading, scratches, tears, missing corners) and digital damage (blur, noise, blocking introduced by the scan itself). AI only touches the second layer. So the order is &lt;strong&gt;scan properly first, sharpen second&lt;/strong&gt; — reverse it and you are enlarging a bad scan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Classify the damage before touching anything
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Condition&lt;/th&gt;
&lt;th&gt;What to do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Blur only, print otherwise intact&lt;/td&gt;
&lt;td&gt;Scan at 600 DPI and sharpen — the best case there is&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Faded, washed-out, yellowed&lt;/td&gt;
&lt;td&gt;Sharpen first, correct white balance and contrast after&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scratches, dust, white specks&lt;/td&gt;
&lt;td&gt;Sharpen, then retouch — sharpening amplifies the scratches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Torn, missing corner, missing face&lt;/td&gt;
&lt;td&gt;Manual repair needed first; AI cannot rebuild a face that is gone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A photo of a photo&lt;/td&gt;
&lt;td&gt;Re-shoot it; two noise layers stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Framed portrait, old ID photo&lt;/td&gt;
&lt;td&gt;Accuracy over smoothness; go easy on denoising&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Row four is where expectations usually break. If part of the face is physically gone, AI will not recover it — it will only sharpen what survived.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scanning without adding blur
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3olmmsery6ytf2wym807.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3olmmsery6ytf2wym807.webp" alt="Portrait Studio: skin texture and eye detail preserved at 100% crop" width="600" height="900"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This decides about 70% of the result and is the step most people skip.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use a flatbed if you have one.&lt;/strong&gt; Photo face down, 600 DPI for a 4×6 inch print, 1200 DPI if it is smaller than 2.5×3.5 in or has a close face. Below 300 DPI there is no detail left to sharpen — the model has to invent it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If a phone is all you have&lt;/strong&gt;, do exactly four things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Daylight, indirect, beside a window. No direct sun, no overhead fluorescent tube.&lt;/li&gt;
&lt;li&gt;Phone parallel to the print, not angled. Prop books either side, or use a stand.&lt;/li&gt;
&lt;li&gt;Lock focus and exposure by long-pressing the print and dragging brightness down — old prints blow out easily.&lt;/li&gt;
&lt;li&gt;Shoot RAW or the highest-quality HEIC your camera offers.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Flatten the print first.&lt;/strong&gt; A curled print is sharp in the middle and soft at the edges, and every filter afterwards amplifies exactly that softness. Press it between two clean sheets of glass, or iron it through tracing paper on low heat.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dust with a microfibre cloth.&lt;/strong&gt; Avoid alcohol on modern dye prints — it can lift the ink layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The workflow, for the recoverable cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Crop and square up
&lt;/h3&gt;

&lt;p&gt;Crop the scanner border, and correct perspective if the print was skewed, using the crop/perspective tool in any editor. Do not run "auto enhance" here; it raises contrast and pushes grain forward.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Pick the mode by subject
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Portrait Studio&lt;/strong&gt; for any photo with a face. It rebuilds skin micro-texture and defines eyes, brows and lip edges — exactly what an old portrait needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ultra Crisp&lt;/strong&gt; for objects, buildings, documents, headstones, old signage. Avoid it on close faces, it engraves paper folds and scratches.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Social Denoise&lt;/strong&gt; for prints that have already been through WhatsApp or Facebook, or scans with heavy grain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Natural HD&lt;/strong&gt; when unsure, or for group shots where faces are small.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Enlarge by one step, not three
&lt;/h3&gt;

&lt;p&gt;A 600 DPI scan of a 4×6 in print is about 2400×3600 pixels. That is already enough for an 8×10 in reprint. Enlarging to 2K covers a 13×18 cm print, 4K covers A4. Past that you only add file size.&lt;/p&gt;

&lt;p&gt;Rule: never enlarge more than 2× per axis beyond the scan.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Inspect at 100%
&lt;/h3&gt;

&lt;p&gt;View at 100%, working left to right in bands. Check three things: eyes reduced to two black dots, hair fused into a solid mass, text turned into meaningless strokes. Any of those means back off the strength or change mode.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Grade colour last
&lt;/h3&gt;

&lt;p&gt;Now correct white balance, lift the shadows, cut the yellow. Old prints shift blue-yellow as the paper ages; pull temperature gently warm rather than chasing neutral white, or skin goes pale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four mistakes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Sharpening a 150 DPI scan.&lt;/strong&gt; With no detail, the model invents: faces come out as drawings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Shooting with flash.&lt;/strong&gt; Flash punches a hot spot into the centre and throws the phone's own shadow across the print.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Over-smoothing.&lt;/strong&gt; Pores vanish, faces go to wax, and the photo loses the age of the person in it. Old photos are appealing precisely because they carry that age.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Not keeping the untouched scan.&lt;/strong&gt; Always retain the raw scan. You will want to redo it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The identity check
&lt;/h2&gt;

&lt;p&gt;Run the finished photo side by side with the original at the same crop and compare three features: eye spacing, nose length, ear position. AI restoration can drift a face by a few percent on low-resolution input, and on a photo of someone who has died there is no one left to ask whether it is still them. If the drift is visible, reduce strength or switch to Natural HD and accept a softer result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Print size still has a limit
&lt;/h2&gt;

&lt;p&gt;Restored or not, print resolution caps enlargement:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;DPI&lt;/th&gt;
&lt;th&gt;Practical print size from a 2400×3600 scan&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;td&gt;8×12 in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;240&lt;/td&gt;
&lt;td&gt;10×15 in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;12×18 in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;150&lt;/td&gt;
&lt;td&gt;16×24 in (soft, wall distance only)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Print at 300 DPI for anything hand-held. The 2× rule from step 3 exists to keep you inside this table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping the original safe
&lt;/h2&gt;

&lt;p&gt;Scan once at the highest resolution you can, store that file untouched (it is your negative), and only ever work on copies. If the print is the only copy, do not crop the original physical print — crop the scan, and handle the print by the edges.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can a 1994 photo be printed at 8×10 after repair?&lt;/strong&gt;&lt;br&gt;
Yes, if the face is still legible in the scan and you scanned at 600 DPI or better. Fading is correctable with grading. Scratches need retouching. A missing face is not recoverable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should I crop the torn edge first?&lt;/strong&gt;&lt;br&gt;
Crop the scan, not the print — torn edges often carry writing or a date. Digitally crop after scanning, and keep the pre-crop file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can colourisation run in the same pass?&lt;/strong&gt;&lt;br&gt;
Do it after sharpening, on the clean file. Upscaling a colourised image bakes in whatever the colouriser guessed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does the scan lose EXIF?&lt;/strong&gt;&lt;br&gt;
Scans have no camera EXIF to begin with; keep a plain text note with the date, names and place instead. That note is the real archive value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if the print is curled and I cannot flatten it?&lt;/strong&gt;&lt;br&gt;
Photograph it against a vertical surface with the phone parallel, in indirect light, then correct perspective in the editor. A slight crop loss is better than a soft scan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with one photo
&lt;/h2&gt;

&lt;p&gt;Pick the least damaged print in the box, follow the order exactly, and look at the result at 100%. Once the workflow is in your hands, move on to the ones that matter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://upgolab.com" rel="noopener noreferrer"&gt;Open the Studio and sharpen the scan for free&lt;/a&gt; — no watermark, no card. If the background is stained and you want the subject lifted out, do that at the &lt;a href="https://upgolab.com" rel="noopener noreferrer"&gt;AI background remover&lt;/a&gt; after sharpening.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Related:&lt;/strong&gt; restore blurry old family photo, scan old prints for restoration, fix faded family photo, print restored photo, keep the original scan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Updated:&lt;/strong&gt; 2026-11-09&lt;/p&gt;

&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%2Fw70psmebw84r1thnzgzk.jpg" 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%2Fw70psmebw84r1thnzgzk.jpg" alt="Portrait Studio result at 100% crop" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>showdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>The ordering mistake in every upscaling workflow</title>
      <dc:creator>celticgemini001</dc:creator>
      <pubDate>Sun, 08 Nov 2026 18:04:09 +0000</pubDate>
      <link>https://dev.to/celticgemini001/the-ordering-mistake-in-every-upscaling-workflow-4abc</link>
      <guid>https://dev.to/celticgemini001/the-ordering-mistake-in-every-upscaling-workflow-4abc</guid>
      <description>&lt;h1&gt;
  
  
  The ordering mistake in every upscaling workflow
&lt;/h1&gt;

&lt;p&gt;Every upscaling guide starts with the enlargement. That single decision is why so many "restored" files look worse than the originals they came from.&lt;/p&gt;

&lt;p&gt;I learned it the slow way, building a browser upscaler while trying to save footage off a 2016 phone. This is the order that held up under testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why enlarging first is wrong
&lt;/h2&gt;

&lt;p&gt;Compression does not scatter random noise across a frame. It imposes a regular grid of blocks. Random grain belongs to the sensor; blocks belong to the encoder.&lt;/p&gt;

&lt;p&gt;An upscaler is a model that reconstructs plausible detail. Give it blocks and it will reconstruct plausible blocks — larger and crisper than the ones you started with. The result reads as sharp until you compare it to the source.&lt;/p&gt;

&lt;p&gt;Denoise first. The blocks have to be gone before anything is enlarged.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule nobody states: 2x per axis
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fke1jxautaz5kurabtduf.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fke1jxautaz5kurabtduf.webp" alt="Before and after: a compressed clip denoised, then upscaled 2x" width="600" height="900"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Past roughly 2× enlargement the model switches from reconstruction to invention. Skin turns waxy. Small text turns into strokes that look like letters and are not. At 2× on a 540p clip you reach 1080p, which is enough for anything watched on a screen.&lt;/p&gt;

&lt;p&gt;The marketing numbers — 4K, 8K, 16K — describe output resolution, not recovered information. A 480p source pushed to 4K is a bigger file with the same amount of real detail, plus a lot of invented detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspect at 100%, on the hair
&lt;/h2&gt;

&lt;p&gt;Never judge at fit-to-window. Fit-to-window downscales the artifacts you just created and hides them.&lt;/p&gt;

&lt;p&gt;Zoom to 100% on the hair edge. Hair is the first thing to fail: fuse the strands and the denoise was too strong, separate them and it held. Then read any small text in the frame — text is the fastest tell between reconstruction and invention. Finally check skin, which is the most forgiving and therefore the least useful test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contrast belongs after cleaning
&lt;/h2&gt;

&lt;p&gt;Raising contrast on a blocky frame makes the blocks louder. Grade once the surface is clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not everything is recoverable
&lt;/h2&gt;

&lt;p&gt;Out-of-focus footage is gone. The sensor never recorded that detail and no model can know what it would have been — whatever an upscaler returns for a defocused face is a guess dressed as detail. Motion blur from a whip pan is nearly as lost.&lt;/p&gt;

&lt;p&gt;A quick test before starting: hold the original at 100%. If there is edge structure, it can probably be sharpened. If there is none, stop.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the pipeline actually looks like
&lt;/h2&gt;

&lt;p&gt;For clips over 30 seconds, cut at keyframes to avoid re-encoding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ffmpeg &lt;span class="nt"&gt;-ss&lt;/span&gt; 00:01:12 &lt;span class="nt"&gt;-to&lt;/span&gt; 00:01:38 &lt;span class="nt"&gt;-i&lt;/span&gt; input.mp4 &lt;span class="nt"&gt;-c&lt;/span&gt; copy damage.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then after processing, concatenate without a second encode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"file '%s'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; seg-&lt;span class="k"&gt;*&lt;/span&gt;.mp4 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; list.txt
ffmpeg &lt;span class="nt"&gt;-f&lt;/span&gt; concat &lt;span class="nt"&gt;-safe&lt;/span&gt; 0 &lt;span class="nt"&gt;-i&lt;/span&gt; list.txt &lt;span class="nt"&gt;-c&lt;/span&gt; copy output.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same four steps regardless of tool: denoise, enlarge ≤2×, inspect at 100%, grade.&lt;/p&gt;




&lt;p&gt;I built &lt;a href="https://upgolab.com" rel="noopener noreferrer"&gt;UpgoLAB&lt;/a&gt;, which runs this in a tab — free during launch, no card, no watermark. If you have a source type that breaks the order above, I would rather hear about it than not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results from each mode
&lt;/h2&gt;

&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%2Fw70psmebw84r1thnzgzk.jpg" 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%2Fw70psmebw84r1thnzgzk.jpg" alt="UpgoLAB upscale result 1" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&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%2F6v36scy5wblauq8n9xeg.jpg" 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%2F6v36scy5wblauq8n9xeg.jpg" alt="UpgoLAB upscale result 2" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&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%2Fb26pw91yadfdwvkipwxm.jpg" 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%2Fb26pw91yadfdwvkipwxm.jpg" alt="UpgoLAB upscale result 3" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&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%2Fea4ul6tpk6omvaay1n1r.jpg" 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%2Fea4ul6tpk6omvaay1n1r.jpg" alt="UpgoLAB upscale result 4" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&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%2Fuf2l91jyfkj4imvcak5c.jpg" 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%2Fuf2l91jyfkj4imvcak5c.jpg" alt="UpgoLAB upscale result 5" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&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%2Faws8udbhaz3i7t3r6hri.jpg" 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%2Faws8udbhaz3i7t3r6hri.jpg" alt="UpgoLAB upscale result 6" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&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%2F55sk4lcicuu41maj65jc.jpg" 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%2F55sk4lcicuu41maj65jc.jpg" alt="UpgoLAB upscale result 7" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All examples generated with &lt;a href="https://upgolab.com" rel="noopener noreferrer"&gt;UpgoLAB&lt;/a&gt; — free during launch, no card, no watermark.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>showdev</category>
      <category>performance</category>
    </item>
    <item>
      <title>Denoise before upscale: the ordering mistake, and why 2x is the ceiling</title>
      <dc:creator>celticgemini001</dc:creator>
      <pubDate>Sun, 08 Nov 2026 17:06:03 +0000</pubDate>
      <link>https://dev.to/celticgemini001/denoise-before-upscale-the-ordering-mistake-and-why-2x-is-the-ceiling-n7m</link>
      <guid>https://dev.to/celticgemini001/denoise-before-upscale-the-ordering-mistake-and-why-2x-is-the-ceiling-n7m</guid>
      <description>&lt;p&gt;Most upscaling tutorials tell you to enlarge first. Do that and the model learns the compression blocks and enlarges them too, which is how you get a 4K file that looks worse than the 540p original.&lt;/p&gt;

&lt;p&gt;I built a browser upscaler while trying to rescue footage from an old phone, so this order is the one that survived testing rather than the one that reads well.&lt;/p&gt;

&lt;h2&gt;
  
  
  The order that works
&lt;/h2&gt;

&lt;p&gt;Denoise → enlarge ≤ 2× → inspect at 100% → grade.&lt;/p&gt;

&lt;p&gt;Four steps, and each one fails differently when skipped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Denoise first.&lt;/strong&gt; Compression does not add random noise, it adds regular blocks. Random grain is a property of the sensor; blocks are a property of the encoder. Feed blocks into an upscaler and you get larger, sharper blocks. Strip them first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cap at 2× per axis.&lt;/strong&gt; Past 2× the model stops reconstructing and starts inventing. Faces go waxy, small text becomes meaningless strokes. On a 540p source, 2× is 1080p and that is where I stop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inspect at 100%.&lt;/strong&gt; Not "looks fine at fit-to-window". 100% on the worst patch, specifically the hair edge and any text. If hair fuses into a solid mass, the denoise was too strong. If text resolves into nonsense, the enlargement was too far.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Grade last.&lt;/strong&gt; Contrast on a blocky file makes the blocks more visible, so grading belongs after cleaning, not before.&lt;/p&gt;

&lt;h2&gt;
  
  
  Splitting anything over 30 seconds
&lt;/h2&gt;

&lt;p&gt;The tool caps clips at 30 seconds. Cut at keyframes so the source is not re-encoded:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ffmpeg &lt;span class="nt"&gt;-ss&lt;/span&gt; 00:01:12 &lt;span class="nt"&gt;-to&lt;/span&gt; 00:01:38 &lt;span class="nt"&gt;-i&lt;/span&gt; input.mp4 &lt;span class="nt"&gt;-c&lt;/span&gt; copy damage.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;-c copy&lt;/code&gt; copies the bitstream instead of decoding it, so the cut is lossless. For batch work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; input.mp4 &lt;span class="nt"&gt;-c&lt;/span&gt; copy &lt;span class="nt"&gt;-f&lt;/span&gt; segment &lt;span class="nt"&gt;-segment_time&lt;/span&gt; 30 &lt;span class="nt"&gt;-reset_timestamps&lt;/span&gt; 1 seg-%03d.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And join the results without a second encode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"file '%s'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; seg-&lt;span class="k"&gt;*&lt;/span&gt;.mp4 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; list.txt
ffmpeg &lt;span class="nt"&gt;-f&lt;/span&gt; concat &lt;span class="nt"&gt;-safe&lt;/span&gt; 0 &lt;span class="nt"&gt;-i&lt;/span&gt; list.txt &lt;span class="nt"&gt;-c&lt;/span&gt; copy output.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If segments drift out of sync, drop &lt;code&gt;-c copy&lt;/code&gt; and encode once. Usually they do not, because &lt;code&gt;-c copy&lt;/code&gt; preserves the original timestamps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three things that failed
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Pushing 4K from a 480p source.&lt;/strong&gt; The file got four times bigger and did not get sharper. Faces went plastic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Denoising after upscaling.&lt;/strong&gt; The blocks had already been enlarged, so the denoiser had four times the pixels of block edge to fight and smeared the real detail along with it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One general model for everything.&lt;/strong&gt; Night grain and anime line art need opposite treatment. A single model averages them and does neither well. Per-content presets are worth the extra complexity: the denoise strength and the edge handling are simply different problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking the result without fooling yourself
&lt;/h2&gt;

&lt;p&gt;Three tests, in this order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Toggle the comparison&lt;/strong&gt; at the same crop. If both versions look the same at 100%, the pass did nothing and the file is now larger for no reason.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Look at the hair edge&lt;/strong&gt;, not the face. Faces are forgiving because we expect faces to look smooth; hair falls apart first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read small text&lt;/strong&gt; if the frame has any. Text is the fastest tell between reconstruction and invention.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If all three are worse than the source, change the mode rather than increasing the strength. More strength mostly buys smoothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it still fails
&lt;/h2&gt;

&lt;p&gt;Out-of-focus footage is gone. Nothing recovers detail the sensor never recorded, and every tool's marketing quietly promises otherwise. Motion blur from a whip pan is nearly as bad; the model cannot know which direction the frame moved.&lt;/p&gt;

&lt;p&gt;If you are deciding whether to try: hold the original to your eye at 100%. If it looks like it could be sharpened into something, it can. If there is no edge structure at all, save the time.&lt;/p&gt;




&lt;p&gt;The tool I built is &lt;a href="https://upgolab.com" rel="noopener noreferrer"&gt;UpgoLAB&lt;/a&gt; — browser-based, free during launch, no card. Photos up to 4 MP, clips up to 30 seconds. Eight modes, and the two worth knowing are Social Denoise for compression damage and Portrait Studio for faces; the rest are variations on how much edge you want.&lt;/p&gt;

&lt;p&gt;Happy to answer questions about the pipeline, especially if you have a source type that breaks it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The eight modes, side by side
&lt;/h2&gt;

&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%2Fkm3f0qeijbg42bp0tcap.jpg" 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%2Fkm3f0qeijbg42bp0tcap.jpg" alt="Natural HD mode: balanced detail with the original colour kept" width="800" height="1200"&gt;&lt;/a&gt;&lt;br&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%2Ffnvfzib2njy4xlmgf1hw.jpg" 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%2Ffnvfzib2njy4xlmgf1hw.jpg" alt="Ultra Crisp mode: product edges and small text held sharp" width="800" height="1200"&gt;&lt;/a&gt;&lt;br&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%2F74oykgr24dra31vwjxet.jpg" 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%2F74oykgr24dra31vwjxet.jpg" alt="Social Denoise mode: platform compression blocks removed before upscaling" width="800" height="1200"&gt;&lt;/a&gt;&lt;br&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%2F77l2lnssq1mr8b6tiwjq.jpg" 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%2F77l2lnssq1mr8b6tiwjq.jpg" alt="Portrait Studio mode: skin micro-texture and eye detail preserved" width="800" height="1200"&gt;&lt;/a&gt;&lt;br&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%2Fizv6a56ws8v1rif9ikbr.jpg" 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%2Fizv6a56ws8v1rif9ikbr.jpg" alt="2D Animation mode: line art kept clean without stair-stepping" width="800" height="1200"&gt;&lt;/a&gt;&lt;br&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%2F4iwsokxe0l4de5dpb6bx.jpg" 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%2F4iwsokxe0l4de5dpb6bx.jpg" alt="Cinematic Vivid mode: deeper shadows and warmer highlights" width="800" height="1200"&gt;&lt;/a&gt;&lt;br&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%2F1zmdy1mfigmctsqnnjk9.jpg" 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%2F1zmdy1mfigmctsqnnjk9.jpg" alt="Sharp Reality mode: fast motion without ghosting" width="800" height="1200"&gt;&lt;/a&gt;&lt;br&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%2F4ncwaldyg60s981e9qyg.jpg" 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%2F4ncwaldyg60s981e9qyg.jpg" alt="True Texture mode: fabric and stone surfaces reconstructed" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

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