<?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: maqiang ma</title>
    <description>The latest articles on DEV Community by maqiang ma (@collart).</description>
    <link>https://dev.to/collart</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%2F3989981%2Fa3768aa3-f96f-4c75-a899-df6fd13093e6.png</url>
      <title>DEV Community: maqiang ma</title>
      <link>https://dev.to/collart</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/collart"/>
    <language>en</language>
    <item>
      <title>A tiny JavaScript prompt builder for controlled AI image experiments</title>
      <dc:creator>maqiang ma</dc:creator>
      <pubDate>Mon, 26 Oct 2026 09:14:11 +0000</pubDate>
      <link>https://dev.to/collart/a-tiny-javascript-prompt-builder-for-controlled-ai-image-experiments-5550</link>
      <guid>https://dev.to/collart/a-tiny-javascript-prompt-builder-for-controlled-ai-image-experiments-5550</guid>
      <description>&lt;p&gt;When a visual draft misses the mark, changing the subject, style and lighting together makes it hard to understand which change helped. A small structured prompt makes your next experiment easier to compare.&lt;/p&gt;

&lt;p&gt;Here is a browser-independent JavaScript example. It creates two prompt strings; it does not call an image API or require a package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;subject&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;setting&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;style&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lighting&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;composition&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;an amber perfume bottle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;setting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;on travertine beside a blood orange&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editorial product photography&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;lighting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;warm side lighting&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;composition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;empty space on the left&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;experiments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;baseline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lighting-only&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;lighting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;soft overcast light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;change&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scene&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;change&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;experiments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Keep the comparison small
&lt;/h2&gt;

&lt;p&gt;Generate a baseline, then try the lighting-only prompt. Keep the same available aspect ratio and reference image, if you are using one. Save the prompt and result together, with a short note such as “bottle edges clearer” or “background too busy.” Change composition in a separate experiment.&lt;/p&gt;

&lt;p&gt;This is a way to organize creative exploration, not a guarantee of a controlled scientific result. Image generation can vary between runs, even when the written prompt stays the same. A prompt log tracks your instructions; it does not make the underlying generator deterministic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it in a browser
&lt;/h2&gt;

&lt;p&gt;We are sharing this workflow alongside FreeGenArt, our &lt;a href="https://freegen.art/" rel="noopener noreferrer"&gt;Free AI Image Generator — No Sign-Up&lt;/a&gt;. It supports text prompts and reference-image workflows online, with a daily free image allowance. Paste either prompt into the generator; this example is not an API integration.&lt;/p&gt;

&lt;p&gt;Before using a result, inspect lettering, reflections, object boundaries and any details that matter to your project. For reference-image experiments, use material you have permission to upload.&lt;/p&gt;

&lt;p&gt;You can extend the same object with a mood or color palette later. Start with a few fields you can compare meaningfully, then add detail when a particular direction needs it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclosure: this write-up and example were prepared with AI assistance. FreeGenArt is our product.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Lessons from Building an AI Video Cleanup Tool</title>
      <dc:creator>maqiang ma</dc:creator>
      <pubDate>Thu, 18 Jun 2026 02:48:27 +0000</pubDate>
      <link>https://dev.to/collart/lessons-from-building-an-ai-video-cleanup-tool-82l</link>
      <guid>https://dev.to/collart/lessons-from-building-an-ai-video-cleanup-tool-82l</guid>
      <description>&lt;p&gt;Disclosure: I work on Collart AI. This article shares some product and engineering lessons from building our AI video cleanup workflow:   &lt;a href="https://collart.ai/en/ai-tools/video-watermark-remover" rel="noopener noreferrer"&gt;Video Watermark Remover&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Removing something from a video sounds simple until you try to make the result look stable.&lt;/p&gt;

&lt;p&gt;For a still image, an object-removal model only has to reconstruct one frame. For video, the model has to solve a harder problem: every repaired frame needs to make sense next to the frames before and after it.&lt;/p&gt;

&lt;p&gt;That is where many “looks good in one frame” results break down.&lt;/p&gt;

&lt;p&gt;You might remove a watermark, logo, or text overlay successfully in frame 72, but by frame 73 the patched area shifts slightly. By frame 74 the texture changes again. At normal playback speed, those small differences become flicker.&lt;/p&gt;

&lt;p&gt;While working on a short-video cleanup tool, we ran into a few recurring lessons that may be useful to anyone building or evaluating AI-powered media tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real problem is not only removal
&lt;/h2&gt;

&lt;p&gt;When people describe watermark removal, they usually focus on the obvious task: detect or select the unwanted mark, then replace it with plausible background pixels.&lt;/p&gt;

&lt;p&gt;That is only part of the work.&lt;/p&gt;

&lt;p&gt;A usable video cleanup result also needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spatial consistency: the repaired area should match the surrounding frame&lt;/li&gt;
&lt;li&gt;Temporal consistency: the repair should remain stable over time&lt;/li&gt;
&lt;li&gt;Edge preservation: objects moving behind or near the mark should not become warped&lt;/li&gt;
&lt;li&gt;Compression tolerance: the output should still look acceptable after social-platform compression&lt;/li&gt;
&lt;li&gt;Reviewability: users need to inspect the result quickly before exporting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last point matters more than it sounds. AI tools are probabilistic. The workflow should assume users will review outputs, compare versions, and sometimes reject a result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Short clips are easier to make reliable
&lt;/h2&gt;

&lt;p&gt;One product decision we made was to optimize for short clips instead of trying to support long-form video immediately.&lt;/p&gt;

&lt;p&gt;That constraint is not just about infrastructure cost. It also improves user experience.&lt;/p&gt;

&lt;p&gt;Shorter clips are easier to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Upload&lt;/li&gt;
&lt;li&gt;Process&lt;/li&gt;
&lt;li&gt;Preview&lt;/li&gt;
&lt;li&gt;Re-run&lt;/li&gt;
&lt;li&gt;Manually verify&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They also reduce the chance that the tool has to handle too many scene changes, camera movements, lighting shifts, or occlusions in a single job.&lt;/p&gt;

&lt;p&gt;For many real-world cleanup cases, the problem area is only a few seconds long anyway: a draft watermark, an old campaign logo, a timestamp, or a text overlay that should no longer be in the final asset.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not all watermarks are equal
&lt;/h2&gt;

&lt;p&gt;Some cleanup tasks are much easier than others.&lt;/p&gt;

&lt;p&gt;A semi-transparent logo over a blurred background is usually more forgiving. A dense watermark over a face, hand, product label, or moving object is much harder.&lt;/p&gt;

&lt;p&gt;The background matters too. AI repair tends to work better when the covered area has predictable context:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sky&lt;/li&gt;
&lt;li&gt;Walls&lt;/li&gt;
&lt;li&gt;Fabric&lt;/li&gt;
&lt;li&gt;Desks&lt;/li&gt;
&lt;li&gt;Blurred backgrounds&lt;/li&gt;
&lt;li&gt;Simple gradients&lt;/li&gt;
&lt;li&gt;Static surfaces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It becomes more fragile around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faces&lt;/li&gt;
&lt;li&gt;Fingers&lt;/li&gt;
&lt;li&gt;Hair&lt;/li&gt;
&lt;li&gt;Text&lt;/li&gt;
&lt;li&gt;Fine product details&lt;/li&gt;
&lt;li&gt;Reflections&lt;/li&gt;
&lt;li&gt;Repeating patterns&lt;/li&gt;
&lt;li&gt;Fast camera movement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is one reason a good product should avoid promising perfect removal in every case. The honest promise is closer to: “This can save time on many cleanup tasks, but you still need to review the output.”&lt;/p&gt;

&lt;h2&gt;
  
  
  The UI should make responsible use obvious
&lt;/h2&gt;

&lt;p&gt;Watermark removal has an obvious misuse case: removing marks from media someone does not own.&lt;/p&gt;

&lt;p&gt;That means the product experience should not frame the tool as a way to take or republish other people’s work. The safer framing is asset repair.&lt;/p&gt;

&lt;p&gt;Legitimate use cases include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cleaning up your own draft exports&lt;/li&gt;
&lt;li&gt;Removing outdated branding from owned marketing assets&lt;/li&gt;
&lt;li&gt;Repairing internal review videos&lt;/li&gt;
&lt;li&gt;Updating licensed content after receiving the correct usage rights&lt;/li&gt;
&lt;li&gt;Removing temporary overlays from approved production assets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The UI copy, documentation, and examples should keep that boundary clear. This is not just legal hygiene. It shapes how users understand the tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preview quality matters more than feature count
&lt;/h2&gt;

&lt;p&gt;For this kind of tool, adding more controls is tempting: brush size, mask editing, frame range, export settings, batch mode, and so on.&lt;/p&gt;

&lt;p&gt;Those features can be useful, but the first experience should answer a simpler question:&lt;/p&gt;

&lt;p&gt;“Did it work on my clip?”&lt;/p&gt;

&lt;p&gt;That means the preview flow matters. Users need to quickly compare the original and cleaned version, especially around the repaired region.&lt;/p&gt;

&lt;p&gt;A basic review checklist can catch most bad outputs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the repaired area flicker?&lt;/li&gt;
&lt;li&gt;Are moving objects distorted?&lt;/li&gt;
&lt;li&gt;Does the texture look smeared?&lt;/li&gt;
&lt;li&gt;Are edges wobbling?&lt;/li&gt;
&lt;li&gt;Did the model remove anything it should have kept?&lt;/li&gt;
&lt;li&gt;Does the result still look good after download?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In AI media products, review is part of the workflow, not an optional final step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building for constraints can be a feature
&lt;/h2&gt;

&lt;p&gt;A lot of AI tools try to feel unlimited. In practice, constraints can make the tool more predictable.&lt;/p&gt;

&lt;p&gt;For our video cleanup workflow, we focused on short uploaded videos and a simple generation path. That keeps the tool understandable: upload, process, review, export.&lt;/p&gt;

&lt;p&gt;The goal is not to replace professional video editing software. It is to make small, common cleanup tasks faster when the user owns or is authorized to edit the footage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;AI video repair is still not magic. The hard part is not producing a plausible frame; it is producing a plausible sequence.&lt;/p&gt;

&lt;p&gt;For product teams building media tools, that means the engineering challenge and the UX challenge are tightly connected. You need models that can handle temporal consistency, but you also need product flows that encourage short inputs, clear previews, careful review, and responsible use.&lt;/p&gt;

&lt;p&gt;That combination is what turns a clever demo into something people can actually use in production.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>video</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
