From 69eb7c9986074a978b606861893ac163abb41909 Mon Sep 17 00:00:00 2001 From: Jan-Henrik Bruhn Date: Sun, 21 Dec 2025 20:52:32 +0100 Subject: [PATCH] feature: Add RGB color matching for Brother thread identification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enhances the Brother color mapping to support exact RGB color matching in addition to catalog number matching. This follows the logic from the BrotherColor.FromColor method in the App codebase. Changes: - Added optional RGB matching to enhanceThreadWithBrotherColor function - RGB matching is enabled by default but can be disabled via options - Enhanced logging to show breakdown of matches (catalog vs RGB) - Matching priority: catalog number first, then RGB (both exact match only) Example: A thread with RGB(255,255,255) will now match Brother color "WHITE" (code 001) even if the catalog number is missing or doesn't match. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- src/formats/import/client.ts | 28 +++++++++++++++-- src/utils/brotherColors.ts | 59 ++++++++++++++++++++++++------------ 2 files changed, 64 insertions(+), 23 deletions(-) diff --git a/src/formats/import/client.ts b/src/formats/import/client.ts index 476c5c2..1bb99dc 100644 --- a/src/formats/import/client.ts +++ b/src/formats/import/client.ts @@ -204,9 +204,28 @@ class PatternConverterClient { "colors", ); - // Enhance thread data with Brother color mapping + // Enhance thread data with Brother color mapping (with RGB matching enabled) + let catalogMatches = 0; + let rgbMatches = 0; + const enhancedThreads = message.data.threads.map((thread) => { - const enhanced = enhanceThreadWithBrotherColor(thread); + const hadCatalog = !!thread.catalogNumber; + const hadBrotherBrand = thread.brand === "Brother Embroidery"; + + const enhanced = enhanceThreadWithBrotherColor(thread, { + matchByRGB: true, + }); + + // Track what type of match occurred + const isBrother = enhanced.brand === "Brother Embroidery"; + if (isBrother && !hadBrotherBrand) { + if (hadCatalog) { + catalogMatches++; + } else { + rgbMatches++; + } + } + return { color: thread.color, hex: enhanced.hex, @@ -220,7 +239,9 @@ class PatternConverterClient { // Also enhance unique colors const enhancedUniqueColors = message.data.uniqueColors.map( (color) => { - const enhanced = enhanceThreadWithBrotherColor(color); + const enhanced = enhanceThreadWithBrotherColor(color, { + matchByRGB: true, + }); return { color: color.color, hex: enhanced.hex, @@ -238,6 +259,7 @@ class PatternConverterClient { enhancedThreads.filter((t) => t.brand === "Brother Embroidery") .length, "Brother colors found", + `(${catalogMatches} by catalog, ${rgbMatches} by RGB)`, ); const result: PesPatternData = { diff --git a/src/utils/brotherColors.ts b/src/utils/brotherColors.ts index 18c03f6..ff91bf1 100644 --- a/src/utils/brotherColors.ts +++ b/src/utils/brotherColors.ts @@ -239,44 +239,63 @@ export function getAllBrotherThreads(): ThreadColorInfo[] { * Enhance thread data with Brother color mapping * * Takes thread data from a PES file and enhances it with Brother color information - * if the catalogNumber matches a Brother thread code. + * using exact matching by catalog number or RGB values. * - * This follows the logic from EmbroideryUtil.GetThreadColorListFromPesx: - * - If catalogNumber matches a Brother color code, use Brother data - * - Otherwise, preserve the original thread data + * This follows the logic from BrotherColor.FromColor and EmbroideryUtil.GetThreadColorListFromPesx: + * 1. If catalogNumber matches a Brother color code, use Brother data + * 2. Optionally, try exact RGB color matching + * 3. If no match, preserve the original thread data * * @param thread - Thread data from PES file + * @param options - Enhancement options + * @param options.matchByRGB - Enable exact RGB color matching (default: true) * @returns Enhanced thread data with Brother mapping if applicable */ -export function enhanceThreadWithBrotherColor(thread: { - color: number; - hex: string; - brand: string | null; - catalogNumber: string | null; - description: string | null; - chart: string | null; -}): ThreadColorInfo { - // If we have a catalog number, try to map it to a Brother color +export function enhanceThreadWithBrotherColor( + thread: { + color: number; + hex: string; + brand: string | null; + catalogNumber: string | null; + description: string | null; + chart: string | null; + }, + options: { + matchByRGB?: boolean; + } = {}, +): ThreadColorInfo { + const { matchByRGB = true } = options; + + // First, try to match by catalog number if (thread.catalogNumber) { const brotherInfo = mapThreadCode(thread.catalogNumber); if (brotherInfo) { - // Found a Brother color match - use Brother data + // Found a Brother color match by catalog number - use Brother data return brotherInfo; } } - // No Brother match - return thread data as-is + // Second, try exact RGB matching if enabled (replicates BrotherColor.FromColor logic) const cleanHex = thread.hex.replace("#", ""); + const r = parseInt(cleanHex.slice(0, 2), 16); + const g = parseInt(cleanHex.slice(2, 4), 16); + const b = parseInt(cleanHex.slice(4, 6), 16); + + if (matchByRGB) { + const brotherColor = findBrotherColorByRGB(r, g, b); + if (brotherColor) { + // Found exact RGB match - use Brother data + return brotherColorToThreadInfo(brotherColor); + } + } + + // No Brother match - return thread data as-is return { hex: thread.hex, brand: thread.brand, catalogNumber: thread.catalogNumber, description: thread.description, chart: thread.chart, - rgb: { - r: parseInt(cleanHex.slice(0, 2), 16), - g: parseInt(cleanHex.slice(2, 4), 16), - b: parseInt(cleanHex.slice(4, 6), 16), - }, + rgb: { r, g, b }, }; }