transfer

Source: transfer.js:43

Ghostyle Transfer Lab

Project Objective

The goal of this browser-only experiment is to let a user capture a painted visual style from one face and preview it on another face without sending images to a server. Instead of treating the transfer as a black box, the page exposes the practical stages of the process: choosing source and target images, marking face regions, extracting a transparent paint matte, previewing that matte, and compositing the result with adjustable blend controls.

Technical Stack

The module is written in JavaScript and uses the DOM for the control surface, the Canvas 2D API for pixel extraction, matte generation, preview drawing, affine triangle warping, and final compositing, and @vladmandic/face-api for optional 68-point landmark detection. All image processing happens in the browser runtime.

Interface Model

The UI is organized around three upload slots: an optional before image, a required painted after image, and a required target image. Each slot renders a fitted preview canvas where the user draws a face box in image coordinates. A side matte preview shows the extracted paint layer, while the result panel displays the final target composite and enables download once a transfer has completed.

Functional Workflow

The transfer starts in a setup state until the after and target slots both have images and face boxes. Running the transfer normalizes the after face crop into a canonical square, subtracts either the matching before crop or a sampled reference color, feathers the resulting alpha plane, and then places the matte onto the target. When landmarks are available and mesh mode is enabled, corresponding face points are triangulated and the matte is warped triangle by triangle; otherwise the system falls back to direct box placement with a status note that explains which mode was used.


Instance Methods

byId(id: string): HTMLElement

Resolve a required DOM element by id.

Parameters

  • id (string) — DOM id.

Returns

  • HTMLElement — Matching element.

Throws

  • Error — When the expected element is missing from the page.

ctx2d(canvas: HTMLCanvasElement): CanvasRenderingContext2D

Resolve a canvas rendering context with a clear failure mode.

Parameters

  • canvas (HTMLCanvasElement) — Canvas to draw into.

Returns

  • CanvasRenderingContext2D — Two-dimensional context.

Throws

  • Error — When the browser cannot allocate a 2D context.

clamp(value: number, min: number, max: number): number

Clamp a numeric value to a closed interval.

Parameters

  • value (number) — Candidate value.
  • min (number) — Inclusive lower bound.
  • max (number) — Inclusive upper bound.

Returns

  • number — Clamped value.

setMessage( key: string, params?: Record.<string, (string|number)>, ): void

Change the currently displayed status message.

Parameters

  • key (string) — Translation key.
  • params (Record.<string, (string|number)>, optional) — Optional interpolation values.

Returns

  • void

setEngineState(key: string, ready: boolean): void

Change the engine availability badge.

Parameters

  • key (string) — Translation key for the badge text.
  • ready (boolean) — Whether to render the badge as ready.

Returns

  • void

renderModeNote(): void

Render the placement mode note. Wrapped modes read as "Placed using: {mode}", while setup states are shown directly.

Returns

  • void

setModeState( key: string, params?: Record.<string, (string|number)>, placed?: boolean, ): void

Change the placement mode note.

Parameters

  • key (string) — Translation key for the mode.
  • params (Record.<string, (string|number)>, optional) — Optional interpolation values.
  • placed (boolean, optional, default: false) — Whether to prefix with the placement wrapper.

Returns

  • void

renderResultEmpty(): void

Re-render the empty result placeholder.

Returns

  • void

refreshLocalizedState(): void

Re-apply locale-dependent runtime text that is not covered by static data-i18n attributes.

Returns

  • void

initFaceapi(): Promise.<void>

Load the optional landmark models. The transfer remains usable in box mode when the CDN or model download fails.

Returns

  • Promise.<void> — Resolves after the best-effort setup.

fitPreview(name: 'before' | 'after' | 'target'): void

Fit a source image into its square preview stage and bind box drawing to the generated canvas.

Parameters

  • name ('before' | 'after' | 'target') — Slot to render.

Returns

  • void

redrawSlot( name: 'before' | 'after' | 'target', canvas: HTMLCanvasElement, ): void

Draw a slot image and the current crop box into its preview canvas.

Parameters

  • name ('before' | 'after' | 'target') — Slot to draw.
  • canvas (HTMLCanvasElement) — Preview canvas.

Returns

  • void

attachBoxDrawing( name: 'before' | 'after' | 'target', canvas: HTMLCanvasElement, ): void

Attach pointer handlers that let the user draw a face box in image coordinates while seeing the box in preview coordinates.

Parameters

  • name ('before' | 'after' | 'target') — Slot being edited.
  • canvas (HTMLCanvasElement) — Interactive preview canvas.

Returns

  • void

refreshSlotNote(name: string): void

Update a single slot note from its current image and box state.

Parameters

  • name (string) — Slot name.

Returns

  • void

refreshState(): void

Recompute readiness and related user-facing prompts after image or box changes.

Returns

  • void

loadFile( name: 'before' | 'after' | 'target', file: File, ): Promise.<HTMLImageElement>

Load an image file selected or dropped by the user.

Parameters

  • name ('before' | 'after' | 'target') — Destination slot.
  • file (File) — Browser file object.

Returns

  • Promise.<HTMLImageElement> — Loaded image element.

loadURL( name: 'before' | 'after' | 'target', url: string, ): Promise.<HTMLImageElement>

Load an image URL into a slot. Exposed through window.GT for automated checks and demos.

Parameters

  • name ('before' | 'after' | 'target') — Destination slot.
  • url (string) — Image URL.

Returns

  • Promise.<HTMLImageElement> — Loaded image element.

boxToCanon( name: 'before' | 'after' | 'target', ): HTMLCanvasElement

Draw a slot crop into the canonical transfer coordinate space.

Parameters

  • name ('before' | 'after' | 'target') — Slot to crop.

Returns

  • HTMLCanvasElement — Canonical face-frame canvas.

extractMatte( threshold: number, feather: number, ): HTMLCanvasElement

Extract the painted pixels as an RGBA matte in canonical face coordinates. With a before image, RGB distance is measured against that before crop. When no before is present, a coarse median color approximation is used instead.

Parameters

  • threshold (number) — RGB distance threshold for paint extraction.
  • feather (number) — Blur radius for softening the matte alpha.

Returns

  • HTMLCanvasElement — Canonical paint matte.

medianColor(imageData: ImageData): RgbTuple

Approximate the dominant skin/reference color by sparse sampling.

Parameters

  • imageData (ImageData) — Canonical source image data.

Returns

boxBlur( alpha: Float32Array, width: number, height: number, radius: number, ): void

Apply two-pass box blur to a float alpha plane.

Parameters

  • alpha (Float32Array) — Alpha plane, mutated in place.
  • width (number) — Plane width.
  • height (number) — Plane height.
  • radius (number) — Blur radius.

Returns

  • void

detectLandmarks( name: 'after' | 'target', ): Promise.<(Array.<Point>|null)>

Detect 68 face landmarks inside a user-provided slot box, mapping the result back into original image coordinates.

Parameters

  • name ('after' | 'target') — Slot to analyze.

Returns

  • Promise.<(Array.<Point>|null)> — Landmark points, or null when detection fails.

landmarksToCanon(points: Array.<Point>, box: Box): Array.<Point>

Convert image-coordinate landmarks to canonical face-frame coordinates.

Parameters

  • points (Array.<Point>) — Source landmarks.
  • box (Box) — Face box used as canonical frame.

Returns

  • Array.<Point> — Canonical points.

triangulate(points: Array.<Point>): Array.<Array.<number>>

Build a Delaunay-like triangulation with Bowyer-Watson. This keeps the mesh dependency-free for a small 68-point landmark set.

Parameters

  • points (Array.<Point>) — Points to triangulate.

Returns

  • Array.<Array.<number>> — Triples of point indices.

warpTriangle( ctx: CanvasRenderingContext2D, source: HTMLCanvasElement, s0: Point, s1: Point, s2: Point, d0: Point, d1: Point, d2: Point, ): void

Warp the source canvas through a single affine triangle into the target rendering context.

Parameters

  • ctx (CanvasRenderingContext2D) — Target rendering context.
  • source (HTMLCanvasElement) — Source matte canvas.
  • s0 (Point) — First source point.
  • s1 (Point) — Second source point.
  • s2 (Point) — Third source point.
  • d0 (Point) — First destination point.
  • d1 (Point) — Second destination point.
  • d2 (Point) — Third destination point.

Returns

  • void

readParams(): Object

Read the current transfer controls as typed values.

Returns

  • Object — Transfer parameters.

drawMattePreview(matte: HTMLCanvasElement): void

Draw the extracted matte into the side preview canvas.

Parameters

  • matte (HTMLCanvasElement) — Canonical matte canvas.

Returns

  • void

transfer(): Promise.<string>

Run extraction and compositing, using mesh warping when landmarks are available and falling back to direct box placement otherwise.

Returns

  • Promise.<string> — Translation key for the mode used.

resetTransfer(): void

Reset images, boxes, previews, output, and controls that are derived from the last transfer.

Returns

  • void

setupTransferPage(): void

Wire DOM events for file loading, drag-and-drop, controls, commands, locale changes, and the lightweight test API.

Returns

  • void

Other

RgbTuple: Object

Two-dimensional point in image or canvas coordinates.

Properties

  • x (number) — Horizontal coordinate.
  • y (number) — Vertical coordinate.Rectangular face selection in original image coordinates.
  • x (number) — Left edge.
  • y (number) — Top edge.
  • w (number) — Width.
  • h (number) — Height.State tracked for one upload slot and its preview canvas.
  • img (HTMLImageElement) — Loaded source image, or null before load.
  • box (Box) — User-selected face box, or null until selected.
  • scale (number) — Ratio from preview pixels to original image pixels.
  • dispW (number) — Preview image width in CSS pixels.
  • dispH (number) — Preview image height in CSS pixels.Three-channel average color stored as red, green, and blue values.

slots: Record.<('before'|'after'|'target'), TransferSlot>