<?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: li jinxuan</title>
    <description>The latest articles on DEV Community by li jinxuan (@li_jinxuan_d7f471cccf75d6).</description>
    <link>https://dev.to/li_jinxuan_d7f471cccf75d6</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%2F4195813%2F9c8bfa1d-5fec-4e66-ba76-cb842d78e14a.jpg</url>
      <title>DEV Community: li jinxuan</title>
      <link>https://dev.to/li_jinxuan_d7f471cccf75d6</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/li_jinxuan_d7f471cccf75d6"/>
    <language>en</language>
    <item>
      <title>A reference-role pattern for multi-image prompts</title>
      <dc:creator>li jinxuan</dc:creator>
      <pubDate>Wed, 11 Nov 2026 13:19:57 +0000</pubDate>
      <link>https://dev.to/li_jinxuan_d7f471cccf75d6/a-reference-role-pattern-for-multi-image-prompts-4h8a</link>
      <guid>https://dev.to/li_jinxuan_d7f471cccf75d6/a-reference-role-pattern-for-multi-image-prompts-4h8a</guid>
      <description>&lt;p&gt;When an image-generation UI accepts several references, a list of filenames tells the model very little about their purpose. The same image could be a subject reference, a layout reference, or a palette reference. Naming those roles in the prompt makes the request easier to reason about and gives you a useful way to debug a surprising output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate sources from constraints
&lt;/h2&gt;

&lt;p&gt;Start with a short role map in the order the references appear in the interface. One reference can define the product, another the tabletop and background. Then describe the resulting scene and list the details that should remain stable. Avoid conflicting requests, such as using the exact perspective from two different photos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use a prompt you can revise
&lt;/h2&gt;

&lt;p&gt;Example: Reference 1 supplies the green desk lamp, including the base and shade. Reference 2 supplies the concrete wall and side lighting, but not its furniture. Compose a landscape image with the lamp on the right and empty space on the left. Keep the lamp green and retain the shape of the shade. No extra lamps or lettering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the output controls outside the prose
&lt;/h2&gt;

&lt;p&gt;Choose the aspect ratio and output format in the interface where the selected model supports them. A wider canvas is better than asking for empty space and then cropping a square. In AI Image Combiner, the available controls depend on the chosen model, so read the actual options before sending the request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evaluate by the original roles
&lt;/h2&gt;

&lt;p&gt;Review the lamp first: did the shape and color survive? Then check the surroundings, contact shadow, and spacing. If the lamp changed shape, strengthen the subject constraint rather than changing the background and lighting at the same time. A generated image is a new composition, so check exact logos and lettering separately before reuse.&lt;/p&gt;

&lt;p&gt;AI Image Combiner is a browser tool for trying this workflow with at least two images. Use references you are allowed to upload. The free path uses the slow queue and adds a watermark; the form describes current credit and output options.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project and localized interfaces:&lt;/strong&gt; &lt;a href="https://imagecombinerai.online/" rel="noopener noreferrer"&gt;English&lt;/a&gt; · &lt;a href="https://imagecombinerai.online/ar" rel="noopener noreferrer"&gt;العربية&lt;/a&gt; · &lt;a href="https://imagecombinerai.online/es" rel="noopener noreferrer"&gt;Español&lt;/a&gt; · &lt;a href="https://imagecombinerai.online/ja" rel="noopener noreferrer"&gt;日本語&lt;/a&gt; · &lt;a href="https://imagecombinerai.online/pt" rel="noopener noreferrer"&gt;Português&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How I Built a Video Object Remover with SAM3 and ProPainter</title>
      <dc:creator>li jinxuan</dc:creator>
      <pubDate>Tue, 20 Oct 2026 15:21:23 +0000</pubDate>
      <link>https://dev.to/li_jinxuan_d7f471cccf75d6/how-i-built-a-video-object-remover-with-sam3-and-propainter-2o13</link>
      <guid>https://dev.to/li_jinxuan_d7f471cccf75d6/how-i-built-a-video-object-remover-with-sam3-and-propainter-2o13</guid>
      <description>&lt;p&gt;A useful video can still contain one distracting object: a passerby in the background, an unwanted sign, or something that pulls attention away from the subject.&lt;/p&gt;

&lt;p&gt;I’m building &lt;a href="https://removeobjects.video/" rel="noopener noreferrer"&gt;removeobjects.video&lt;/a&gt;, a web app for removing unwanted objects from video. The project also includes a separate AI video repainting workflow, but this post focuses on object removal: how the editor works, how SAM3 and ProPainter fit together, and the practical limits of the approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  The editing workflow
&lt;/h2&gt;

&lt;p&gt;The object-removal flow is built around a short sequence of decisions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select a video and choose the segment to edit.&lt;/li&gt;
&lt;li&gt;Pick a frame where the target is clearly visible.&lt;/li&gt;
&lt;li&gt;Describe the target with a short phrase.&lt;/li&gt;
&lt;li&gt;Inspect the detected mask and confirm the processing option.&lt;/li&gt;
&lt;li&gt;Wait for the background job and download the result.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That mask preview matters. A description can sound obvious to a person while still matching the wrong region of an image. Showing the selection before processing the entire clip gives the user a chance to choose another frame or rewrite the description.&lt;/p&gt;

&lt;p&gt;For example, &lt;strong&gt;“the person wearing a red shirt”&lt;/strong&gt; gives the model a visual characteristic to follow. &lt;strong&gt;“the person on the left”&lt;/strong&gt; can become ambiguous when people move or the camera changes position. A short, distinctive description is usually a better starting point than a long instruction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two models, two responsibilities
&lt;/h2&gt;

&lt;p&gt;The core pipeline uses SAM3 for segmentation and ProPainter for video inpainting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SAM3 identifies the region to remove.&lt;/strong&gt; The editor uses a single-frame preview to help the user inspect the selection. After confirmation, the full-clip segmentation stage produces the masks needed for processing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ProPainter fills the masked regions.&lt;/strong&gt; Video inpainting has to reconstruct the background while keeping the sequence visually consistent over time. A region that looks plausible in one frame can still flicker or smear during playback.&lt;/p&gt;

&lt;p&gt;The full processing flow also includes preparing the clip, handling its audio, and storing the finished video. Segmentation and inpainting are the central model stages, but they are only part of the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping the editor usable during upload
&lt;/h2&gt;

&lt;p&gt;Video upload can take long enough to interrupt the editing experience.&lt;/p&gt;

&lt;p&gt;In the usual workflow, the browser keeps the selected video available locally so the user can work with the timeline while the full file uploads in the background. Selected preview frames are uploaded separately for recognition. The full video must finish uploading before the final processing job can proceed.&lt;/p&gt;

&lt;p&gt;This introduces a boundary the application has to handle carefully: the browser may have a usable local frame before the server has the complete video. The editor therefore tracks preparation, upload, and processing as separate states.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the background pipeline
&lt;/h2&gt;

&lt;p&gt;The application uses &lt;strong&gt;React Router 7&lt;/strong&gt; on &lt;strong&gt;Cloudflare Workers&lt;/strong&gt;, with &lt;strong&gt;R2&lt;/strong&gt; for video files and &lt;strong&gt;D1&lt;/strong&gt; for task records. &lt;strong&gt;Cloudflare Workflows&lt;/strong&gt; coordinates the longer processing steps, and an FFmpeg sidecar running in Cloudflare Containers handles media preparation and final processing. The object-removal models run through Replicate.&lt;/p&gt;

&lt;p&gt;Keeping task state separate from the page request helps the application represent a job that is waiting, processing, finished, or failed. It also makes recovery decisions more precise.&lt;/p&gt;

&lt;p&gt;One example is handling an interrupted provider response. When a prediction ID is already available, checking that existing prediction can be safer than immediately submitting another GPU job. A failed status check does not necessarily mean the original job failed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Details that affect the result
&lt;/h2&gt;

&lt;p&gt;Three parts of this workflow deserve particular attention:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mask coverage:&lt;/strong&gt; if the segmentation misses part of a moving object, inpainting cannot reliably remove the missing area. A single-frame preview is useful, but it does not guarantee correct coverage throughout the clip.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Geometry:&lt;/strong&gt; the source clip and its masks need matching dimensions and coordinates. Resizing either one without keeping them aligned can make an otherwise valid mask target the wrong pixels.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Processing limits:&lt;/strong&gt; duration, frame rate, and resolution affect memory requirements. Longer or larger clips can require downsampling, and some jobs can still fail.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These constraints are also why I would judge an edit by watching the resulting video, rather than looking only at a still frame or a successful API response. Motion, occlusion, and detailed backgrounds can expose problems that a thumbnail hides.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the current version supports
&lt;/h2&gt;

&lt;p&gt;The free object-removal mode supports clips up to &lt;strong&gt;6 seconds&lt;/strong&gt;, with target-area and resolution limits and a watermark. Paid object-removal clips can be up to &lt;strong&gt;50 seconds&lt;/strong&gt;. Processing may reduce resolution; preserving the original resolution is not guaranteed.&lt;/p&gt;

&lt;p&gt;A short clip with a clearly visible target is a useful starting point for evaluating the workflow. The editor provides a way to inspect the intended selection, while the finished video shows how well the removal holds up over time.&lt;/p&gt;

&lt;p&gt;I’d welcome feedback on the editing workflow, especially where target descriptions or mask previews could make the process easier to understand.&lt;/p&gt;

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