DEV Community

Om Prakash
Om Prakash

Posted on • Originally published at pixelapi.dev

Fixing bad lighting in photos with an API (and why I stopped dreading product photography)

I've been building a small e-commerce tool for independent sellers — the kind of people who photograph their products on a kitchen table with whatever light is coming through the window. The photos are real, but they're often a mess. Harsh noon shadows, washed-out backgrounds, backlit disasters where the product is essentially a silhouette.

For a while I was telling sellers to just... reshoot. Which is terrible advice that nobody follows. Then I started integrating PixelAPI's photo relight endpoint into the pipeline, and it changed what I was able to offer.

The actual problem

Backlighting is the most common issue. Someone holds up a mug in front of a window, the camera exposes for the bright background, and the mug itself goes dark. The shape is there, the details aren't. You can try to recover this in post with a curves adjustment, but you're fighting noise and blown highlights at the same time — it usually looks worse.

Underexposure on product shots is almost as bad. A candle photographed in a dim studio-wannabe setup where the shadows are muddy and the colors are flat. You can brighten it, but you can't manufacture light direction that wasn't there.

These are the two cases I kept running into. The relight API handles both.

How I integrated it

The API takes an image and applies AI-driven relighting — essentially it figures out the geometry of the scene and re-illuminates it. You get back a photo that looks like it was shot with proper lighting, not just a brightened version of the original.

Here's the basic call I'm using in my Node.js pipeline:

import fs from "fs";

async function relightProductPhoto(imagePath) {
  const imageBuffer = fs.readFileSync(imagePath);
  const base64Image = imageBuffer.toString("base64");

  const response = await fetch("https://pixelapi.dev/api/relight", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.PIXELAPI_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      image: base64Image,
      lighting_preset: "studio",
    }),
  });

  const result = await response.json();

  fs.writeFileSync(
    imagePath.replace(".jpg", "_relit.jpg"),
    Buffer.from(result.image, "base64")
  );

  return result;
}
Enter fullscreen mode Exit fullscreen mode

I run this as part of an upload handler — when a seller drops in a new product photo, it goes through relight automatically before hitting the product listing. The seller never has to think about it. They just see better photos on their store.

The selfie case

I also wired this up for a profile photo feature I added. Users upload a headshot, and if it looks backlit or underexposed, the pipeline flags it and runs relight. I'm not doing face detection to decide this — I'm just running every profile upload through it and letting the API figure out if there's meaningful work to do. The results on backlit selfies have been genuinely good: faces that were in shadow come out looking like they were shot with a softbox, without that over-processed look you get from just cranking up exposure in a photo editor.

What the workflow actually looks like end-to-end

For the e-commerce tool, the full flow is:

  1. Seller uploads photo via drag-and-drop
  2. My backend sends it to the relight API
  3. Both versions (original and relit) are stored
  4. The seller sees both and picks one — the relit version is pre-selected
  5. About 80% of the time, they keep the relit version without changing anything

That last number surprised me. I expected sellers to be precious about their original photos. Instead, most of them don't know what good product lighting looks like until they see it side by side, and then they immediately prefer the fixed version.

The cases where it's less useful

I want to be honest: if the photo is genuinely unusable — severe motion blur, extreme compression artifacts, or the subject is barely distinguishable — relighting won't save it. You still need a shootable source image. The API is doing real work with geometry and light simulation, not magic content generation.

Also, if a seller has an intentional moody dark aesthetic, running everything through studio-preset relighting will fight their brand. I added a toggle so sellers can opt out per-photo.

Why I built this into the product instead of making it manual

The core reason is that manual tools require the person to know they have a problem, know how to fix it, and have time to do it. Most sellers I work with fail at least one of those three. Building it into the upload pipeline means the fix happens whether or not the seller is technically savvy.

The API fits cleanly into an async job queue — upload triggers the job, job calls PixelAPI, result gets stored, UI updates when it's ready. Latency is acceptable for a background job, and the quality is high enough that I've had zero sellers complain about over-processing.

If you're building anything where user-generated photos matter — marketplace listings, profile photos, portfolio uploads, food delivery menus — this is worth adding. The integration is maybe two hours of work, and the payoff in photo quality is immediate.

The free tier on PixelAPI gives you enough credits to build the integration and test it against your real data before you commit to anything. That's how I started, and the results on actual seller photos were convincing enough that I kept going.

Top comments (0)