mirror of
https://github.com/jhbruhn/respira.git
synced 2026-01-27 02:13:41 +00:00
Merge pull request #25 from jhbruhn/feature/brother-color-mapping
Some checks are pending
Build, Test, and Lint / Build, Test, and Lint (push) Waiting to run
Draft Release / Draft Release (push) Waiting to run
Draft Release / Build Web App (push) Blocked by required conditions
Draft Release / Build Release - macos-latest (push) Blocked by required conditions
Draft Release / Build Release - ubuntu-latest (push) Blocked by required conditions
Draft Release / Build Release - windows-latest (push) Blocked by required conditions
Draft Release / Upload to GitHub Release (push) Blocked by required conditions
Some checks are pending
Build, Test, and Lint / Build, Test, and Lint (push) Waiting to run
Draft Release / Draft Release (push) Waiting to run
Draft Release / Build Web App (push) Blocked by required conditions
Draft Release / Build Release - macos-latest (push) Blocked by required conditions
Draft Release / Build Release - ubuntu-latest (push) Blocked by required conditions
Draft Release / Build Release - windows-latest (push) Blocked by required conditions
Draft Release / Upload to GitHub Release (push) Blocked by required conditions
Feature: brother color mapping
This commit is contained in:
commit
93ca7ea406
4 changed files with 915 additions and 1 deletions
|
|
@ -422,7 +422,13 @@ export function PatternCanvas() {
|
|||
.join(" ");
|
||||
|
||||
// Secondary metadata: chart and description
|
||||
const secondaryMetadata = [color.chart, color.description]
|
||||
// Only show chart if it's different from catalogNumber
|
||||
const secondaryMetadata = [
|
||||
color.chart && color.chart !== color.catalogNumber
|
||||
? color.chart
|
||||
: null,
|
||||
color.description,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
|
||||
|
|
|
|||
546
src/data/BrotherColor.json
Normal file
546
src/data/BrotherColor.json
Normal file
|
|
@ -0,0 +1,546 @@
|
|||
[
|
||||
{
|
||||
"ColorCode": "001",
|
||||
"BrandCode": 13,
|
||||
"R": 240,
|
||||
"G": 240,
|
||||
"B": 240,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "WHITE"
|
||||
},
|
||||
{
|
||||
"ColorCode": "843",
|
||||
"BrandCode": 13,
|
||||
"R": 239,
|
||||
"G": 227,
|
||||
"B": 185,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "BEIGE"
|
||||
},
|
||||
{
|
||||
"ColorCode": "010",
|
||||
"BrandCode": 13,
|
||||
"R": 255,
|
||||
"G": 255,
|
||||
"B": 179,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "CREAM BROWN"
|
||||
},
|
||||
{
|
||||
"ColorCode": "027",
|
||||
"BrandCode": 13,
|
||||
"R": 227,
|
||||
"G": 243,
|
||||
"B": 91,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "FRESH GREEN"
|
||||
},
|
||||
{
|
||||
"ColorCode": "542",
|
||||
"BrandCode": 13,
|
||||
"R": 168,
|
||||
"G": 221,
|
||||
"B": 196,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "SEACREST"
|
||||
},
|
||||
{
|
||||
"ColorCode": "017",
|
||||
"BrandCode": 13,
|
||||
"R": 168,
|
||||
"G": 222,
|
||||
"B": 235,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "LIGHT BLUE"
|
||||
},
|
||||
{
|
||||
"ColorCode": "804",
|
||||
"BrandCode": 13,
|
||||
"R": 178,
|
||||
"G": 175,
|
||||
"B": 212,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "LAVENDER"
|
||||
},
|
||||
{
|
||||
"ColorCode": "124",
|
||||
"BrandCode": 13,
|
||||
"R": 253,
|
||||
"G": 217,
|
||||
"B": 222,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "FLESH PINK"
|
||||
},
|
||||
{
|
||||
"ColorCode": "079",
|
||||
"BrandCode": 13,
|
||||
"R": 252,
|
||||
"G": 187,
|
||||
"B": 196,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "SALMON PINK"
|
||||
},
|
||||
{
|
||||
"ColorCode": "399",
|
||||
"BrandCode": 13,
|
||||
"R": 216,
|
||||
"G": 204,
|
||||
"B": 198,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "WARM GRAY"
|
||||
},
|
||||
{
|
||||
"ColorCode": "307",
|
||||
"BrandCode": 13,
|
||||
"R": 254,
|
||||
"G": 227,
|
||||
"B": 197,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "LINEN"
|
||||
},
|
||||
{
|
||||
"ColorCode": "005",
|
||||
"BrandCode": 13,
|
||||
"R": 168,
|
||||
"G": 168,
|
||||
"B": 168,
|
||||
"ColorName": "SILVER"
|
||||
},
|
||||
{
|
||||
"ColorCode": "812",
|
||||
"BrandCode": 13,
|
||||
"R": 255,
|
||||
"G": 240,
|
||||
"B": 141,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "CREAM YELLOW"
|
||||
},
|
||||
{
|
||||
"ColorCode": "202",
|
||||
"BrandCode": 13,
|
||||
"R": 240,
|
||||
"G": 249,
|
||||
"B": 112,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "LEMON YELLOW"
|
||||
},
|
||||
{
|
||||
"ColorCode": "502",
|
||||
"BrandCode": 13,
|
||||
"R": 158,
|
||||
"G": 214,
|
||||
"B": 125,
|
||||
"ColorName": "MINT GREEN"
|
||||
},
|
||||
{
|
||||
"ColorCode": "509",
|
||||
"BrandCode": 13,
|
||||
"R": 102,
|
||||
"G": 186,
|
||||
"B": 73,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "LEAF GREEN"
|
||||
},
|
||||
{
|
||||
"ColorCode": "019",
|
||||
"BrandCode": 13,
|
||||
"R": 37,
|
||||
"G": 132,
|
||||
"B": 187,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "SKY BLUE"
|
||||
},
|
||||
{
|
||||
"ColorCode": "612",
|
||||
"BrandCode": 13,
|
||||
"R": 145,
|
||||
"G": 95,
|
||||
"B": 172,
|
||||
"ColorName": "LILAC"
|
||||
},
|
||||
{
|
||||
"ColorCode": "810",
|
||||
"BrandCode": 13,
|
||||
"R": 228,
|
||||
"G": 154,
|
||||
"B": 203,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "LIGHT LILAC"
|
||||
},
|
||||
{
|
||||
"ColorCode": "085",
|
||||
"BrandCode": 13,
|
||||
"R": 249,
|
||||
"G": 147,
|
||||
"B": 188,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "PINK"
|
||||
},
|
||||
{
|
||||
"ColorCode": "086",
|
||||
"BrandCode": 13,
|
||||
"R": 246,
|
||||
"G": 74,
|
||||
"B": 138,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "DEEP ROSE"
|
||||
},
|
||||
{
|
||||
"ColorCode": "348",
|
||||
"BrandCode": 13,
|
||||
"R": 208,
|
||||
"G": 166,
|
||||
"B": 96,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "KHAKI"
|
||||
},
|
||||
{
|
||||
"ColorCode": "817",
|
||||
"BrandCode": 13,
|
||||
"R": 135,
|
||||
"G": 135,
|
||||
"B": 135,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "GRAY"
|
||||
},
|
||||
{
|
||||
"ColorCode": "126",
|
||||
"BrandCode": 13,
|
||||
"R": 254,
|
||||
"G": 179,
|
||||
"B": 67,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "PUMPKIN"
|
||||
},
|
||||
{
|
||||
"ColorCode": "205",
|
||||
"BrandCode": 13,
|
||||
"R": 255,
|
||||
"G": 255,
|
||||
"B": 0,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "YELLOW"
|
||||
},
|
||||
{
|
||||
"ColorCode": "513",
|
||||
"BrandCode": 13,
|
||||
"R": 112,
|
||||
"G": 188,
|
||||
"B": 31,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "LIME GREEN"
|
||||
},
|
||||
{
|
||||
"ColorCode": "534",
|
||||
"BrandCode": 13,
|
||||
"R": 0,
|
||||
"G": 135,
|
||||
"B": 119,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "TEAL GREEN"
|
||||
},
|
||||
{
|
||||
"ColorCode": "420",
|
||||
"BrandCode": 13,
|
||||
"R": 9,
|
||||
"G": 91,
|
||||
"B": 166,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "ELECTRIC BLUE"
|
||||
},
|
||||
{
|
||||
"ColorCode": "607",
|
||||
"BrandCode": 13,
|
||||
"R": 104,
|
||||
"G": 106,
|
||||
"B": 176,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "WISTERIA VIOLET"
|
||||
},
|
||||
{
|
||||
"ColorCode": "620",
|
||||
"BrandCode": 13,
|
||||
"R": 145,
|
||||
"G": 54,
|
||||
"B": 151,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "MAGENTA"
|
||||
},
|
||||
{
|
||||
"ColorCode": "807",
|
||||
"BrandCode": 13,
|
||||
"R": 247,
|
||||
"G": 56,
|
||||
"B": 102,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "CARMINE"
|
||||
},
|
||||
{
|
||||
"ColorCode": "339",
|
||||
"BrandCode": 13,
|
||||
"R": 209,
|
||||
"G": 84,
|
||||
"B": 0,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "CLAY BROWN"
|
||||
},
|
||||
{
|
||||
"ColorCode": "328",
|
||||
"BrandCode": 13,
|
||||
"R": 186,
|
||||
"G": 152,
|
||||
"B": 0,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "BRASS"
|
||||
},
|
||||
{
|
||||
"ColorCode": "704",
|
||||
"BrandCode": 13,
|
||||
"R": 79,
|
||||
"G": 85,
|
||||
"B": 86,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "PEWTER"
|
||||
},
|
||||
{
|
||||
"ColorCode": "209",
|
||||
"BrandCode": 13,
|
||||
"R": 254,
|
||||
"G": 158,
|
||||
"B": 50,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "TANGERINE"
|
||||
},
|
||||
{
|
||||
"ColorCode": "206",
|
||||
"BrandCode": 13,
|
||||
"R": 255,
|
||||
"G": 217,
|
||||
"B": 17,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "HARVEST GOLD"
|
||||
},
|
||||
{
|
||||
"ColorCode": "515",
|
||||
"BrandCode": 13,
|
||||
"R": 47,
|
||||
"G": 126,
|
||||
"B": 32,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "MOSS GREEN"
|
||||
},
|
||||
{
|
||||
"ColorCode": "507",
|
||||
"BrandCode": 13,
|
||||
"R": 0,
|
||||
"G": 103,
|
||||
"B": 62,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "EMERALD GREEN"
|
||||
},
|
||||
{
|
||||
"ColorCode": "405",
|
||||
"BrandCode": 13,
|
||||
"R": 10,
|
||||
"G": 85,
|
||||
"B": 163,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "BLUE"
|
||||
},
|
||||
{
|
||||
"ColorCode": "070",
|
||||
"BrandCode": 13,
|
||||
"R": 75,
|
||||
"G": 107,
|
||||
"B": 175,
|
||||
"ColorName": "CORNFLOWER BLUE"
|
||||
},
|
||||
{
|
||||
"ColorCode": "869",
|
||||
"BrandCode": 13,
|
||||
"R": 119,
|
||||
"G": 1,
|
||||
"B": 118,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "ROYAL PURPLE"
|
||||
},
|
||||
{
|
||||
"ColorCode": "107",
|
||||
"BrandCode": 13,
|
||||
"R": 199,
|
||||
"G": 1,
|
||||
"B": 86,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "DARK FUCHSIA"
|
||||
},
|
||||
{
|
||||
"ColorCode": "030",
|
||||
"BrandCode": 13,
|
||||
"R": 254,
|
||||
"G": 55,
|
||||
"B": 15,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "VERMILLION"
|
||||
},
|
||||
{
|
||||
"ColorCode": "330",
|
||||
"BrandCode": 13,
|
||||
"R": 125,
|
||||
"G": 111,
|
||||
"B": 0,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "RUSSET BROWN"
|
||||
},
|
||||
{
|
||||
"ColorCode": "707",
|
||||
"BrandCode": 13,
|
||||
"R": 41,
|
||||
"G": 49,
|
||||
"B": 51,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "DARK GRAY"
|
||||
},
|
||||
{
|
||||
"ColorCode": "214",
|
||||
"BrandCode": 13,
|
||||
"R": 232,
|
||||
"G": 169,
|
||||
"B": 0,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "DEEP GOLD"
|
||||
},
|
||||
{
|
||||
"ColorCode": "208",
|
||||
"BrandCode": 13,
|
||||
"R": 254,
|
||||
"G": 186,
|
||||
"B": 53,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "ORANGE"
|
||||
},
|
||||
{
|
||||
"ColorCode": "517",
|
||||
"BrandCode": 13,
|
||||
"R": 67,
|
||||
"G": 86,
|
||||
"B": 7,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "DARK OLIVE"
|
||||
},
|
||||
{
|
||||
"ColorCode": "415",
|
||||
"BrandCode": 13,
|
||||
"R": 19,
|
||||
"G": 74,
|
||||
"B": 70,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "PEACOCK BLUE"
|
||||
},
|
||||
{
|
||||
"ColorCode": "406",
|
||||
"BrandCode": 13,
|
||||
"R": 11,
|
||||
"G": 61,
|
||||
"B": 145,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "ULTRA MARINE"
|
||||
},
|
||||
{
|
||||
"ColorCode": "614",
|
||||
"BrandCode": 13,
|
||||
"R": 78,
|
||||
"G": 41,
|
||||
"B": 144,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "PURPLE"
|
||||
},
|
||||
{
|
||||
"ColorCode": "613",
|
||||
"BrandCode": 13,
|
||||
"R": 106,
|
||||
"G": 28,
|
||||
"B": 138,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "VIOLET"
|
||||
},
|
||||
{
|
||||
"ColorCode": "333",
|
||||
"BrandCode": 13,
|
||||
"R": 181,
|
||||
"G": 76,
|
||||
"B": 100,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "AMBER RED"
|
||||
},
|
||||
{
|
||||
"ColorCode": "800",
|
||||
"BrandCode": 13,
|
||||
"R": 237,
|
||||
"G": 23,
|
||||
"B": 31,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "RED"
|
||||
},
|
||||
{
|
||||
"ColorCode": "337",
|
||||
"BrandCode": 13,
|
||||
"R": 209,
|
||||
"G": 92,
|
||||
"B": 0,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "REDDISH BROWN"
|
||||
},
|
||||
{
|
||||
"ColorCode": "900",
|
||||
"BrandCode": 13,
|
||||
"R": 0,
|
||||
"G": 0,
|
||||
"B": 0,
|
||||
"ColorName": "BLACK"
|
||||
},
|
||||
{
|
||||
"ColorCode": "058",
|
||||
"BrandCode": 13,
|
||||
"R": 42,
|
||||
"G": 19,
|
||||
"B": 1,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "DARK BROWN"
|
||||
},
|
||||
{
|
||||
"ColorCode": "323",
|
||||
"BrandCode": 13,
|
||||
"R": 178,
|
||||
"G": 118,
|
||||
"B": 36,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "LIGHT BROWN"
|
||||
},
|
||||
{
|
||||
"ColorCode": "519",
|
||||
"BrandCode": 13,
|
||||
"R": 19,
|
||||
"G": 43,
|
||||
"B": 26,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "OLIVE GREEN"
|
||||
},
|
||||
{
|
||||
"ColorCode": "808",
|
||||
"BrandCode": 13,
|
||||
"R": 0,
|
||||
"G": 56,
|
||||
"B": 34,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "DEEP GREEN"
|
||||
},
|
||||
{
|
||||
"ColorCode": "007",
|
||||
"BrandCode": 13,
|
||||
"R": 14,
|
||||
"G": 31,
|
||||
"B": 124,
|
||||
"brandName": "Brother Embroidery",
|
||||
"ColorName": "PRUSSIAN BLUE"
|
||||
}
|
||||
]
|
||||
|
|
@ -2,6 +2,7 @@ import type { WorkerMessage, WorkerResponse } from "./worker";
|
|||
import PatternConverterWorker from "./worker?worker";
|
||||
import { decodePenData } from "../pen/decoder";
|
||||
import type { DecodedPenData } from "../pen/types";
|
||||
import { enhanceThreadWithBrotherColor } from "../../utils/brotherColors";
|
||||
|
||||
export type PyodideState = "not_loaded" | "loading" | "ready" | "error";
|
||||
|
||||
|
|
@ -203,8 +204,68 @@ class PatternConverterClient {
|
|||
"colors",
|
||||
);
|
||||
|
||||
// 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 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,
|
||||
brand: enhanced.brand,
|
||||
catalogNumber: enhanced.catalogNumber,
|
||||
description: enhanced.description,
|
||||
chart: enhanced.chart,
|
||||
};
|
||||
});
|
||||
|
||||
// Also enhance unique colors
|
||||
const enhancedUniqueColors = message.data.uniqueColors.map(
|
||||
(color) => {
|
||||
const enhanced = enhanceThreadWithBrotherColor(color, {
|
||||
matchByRGB: true,
|
||||
});
|
||||
return {
|
||||
color: color.color,
|
||||
hex: enhanced.hex,
|
||||
brand: enhanced.brand,
|
||||
catalogNumber: enhanced.catalogNumber,
|
||||
description: enhanced.description,
|
||||
chart: enhanced.chart,
|
||||
threadIndices: color.threadIndices,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
console.log(
|
||||
"[PatternConverter] Enhanced threads with Brother color mapping:",
|
||||
enhancedThreads.filter((t) => t.brand === "Brother Embroidery")
|
||||
.length,
|
||||
"Brother colors found",
|
||||
`(${catalogMatches} by catalog, ${rgbMatches} by RGB)`,
|
||||
);
|
||||
|
||||
const result: PesPatternData = {
|
||||
...message.data,
|
||||
threads: enhancedThreads,
|
||||
uniqueColors: enhancedUniqueColors,
|
||||
penData,
|
||||
penStitches,
|
||||
};
|
||||
|
|
|
|||
301
src/utils/brotherColors.ts
Normal file
301
src/utils/brotherColors.ts
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
/**
|
||||
* Brother Color Mapping Utilities
|
||||
*
|
||||
* This module provides utilities for mapping thread colors to official Brother
|
||||
* embroidery thread colors with their proper names and chart codes.
|
||||
*
|
||||
* Based on the Brother Embroidery thread catalog, this mapping ensures accurate
|
||||
* color identification for embroidery patterns.
|
||||
*
|
||||
* The mapping logic follows the implementation in Asura.Core.Models.EmbroideryUtil.GetThreadColorListFromPesx
|
||||
*/
|
||||
|
||||
import brotherColorData from "../data/BrotherColor.json";
|
||||
|
||||
/**
|
||||
* Brother thread color data structure
|
||||
*/
|
||||
export interface BrotherColor {
|
||||
/** RGB red value (0-255) */
|
||||
R: number;
|
||||
/** RGB green value (0-255) */
|
||||
G: number;
|
||||
/** RGB blue value (0-255) */
|
||||
B: number;
|
||||
/** Brother thread chart code (e.g., "001", "843") */
|
||||
ColorCode: string;
|
||||
/** Color name (e.g., "WHITE", "BEIGE") */
|
||||
ColorName: string;
|
||||
/** Brand code (13 for Brother Embroidery) */
|
||||
BrandCode: number;
|
||||
/** Brand name */
|
||||
brandName?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread color information with Brother mapping
|
||||
*/
|
||||
export interface ThreadColorInfo {
|
||||
/** RGB color as hex string */
|
||||
hex: string;
|
||||
/** Brand name (e.g., "Brother Embroidery") */
|
||||
brand: string | null;
|
||||
/** Color catalog/chart code (e.g., "001", "843") */
|
||||
catalogNumber: string | null;
|
||||
/** Color description/name (e.g., "WHITE", "BEIGE") */
|
||||
description: string | null;
|
||||
/** Chart code (same as catalogNumber for Brother) */
|
||||
chart: string | null;
|
||||
/** RGB values */
|
||||
rgb: {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
};
|
||||
}
|
||||
|
||||
// Type-safe Brother color data
|
||||
const brotherColors = brotherColorData as BrotherColor[];
|
||||
|
||||
/**
|
||||
* Convert RGB values to hex color string
|
||||
*/
|
||||
function rgbToHex(r: number, g: number, b: number): string {
|
||||
return `#${((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1).toUpperCase()}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pad a color code to 3 digits with leading zeros
|
||||
* e.g., "5" -> "005", "43" -> "043", "900" -> "900"
|
||||
*
|
||||
* This replicates the logic:
|
||||
* ```csharp
|
||||
* if (int.TryParse(threadCode, NumberStyles.Number, CultureInfo.InvariantCulture, out result))
|
||||
* threadCode = $"{result:000}";
|
||||
* ```
|
||||
*/
|
||||
function padColorCode(code: string | number): string {
|
||||
const codeStr = typeof code === "number" ? code.toString() : code;
|
||||
const parsed = parseInt(codeStr, 10);
|
||||
if (!isNaN(parsed)) {
|
||||
return parsed.toString().padStart(3, "0");
|
||||
}
|
||||
return codeStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find Brother color by color code (exact match only)
|
||||
*
|
||||
* This replicates:
|
||||
* ```csharp
|
||||
* IEnumerable<BrotherColor> source2 = BrotherColor.Colors.Where<BrotherColor>((c => c.ColorCode == threadCode));
|
||||
* ```
|
||||
*
|
||||
* @param colorCode - Brother thread code (e.g., "001", "5", 843)
|
||||
* @returns Brother color data or undefined if not found
|
||||
*/
|
||||
export function findBrotherColorByCode(
|
||||
colorCode: string | number,
|
||||
): BrotherColor | undefined {
|
||||
const paddedCode = padColorCode(colorCode);
|
||||
return brotherColors.find((c) => c.ColorCode === paddedCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find Brother color by RGB values (exact match only)
|
||||
*
|
||||
* @param r - Red value (0-255)
|
||||
* @param g - Green value (0-255)
|
||||
* @param b - Blue value (0-255)
|
||||
* @returns Brother color data or undefined if no exact match found
|
||||
*/
|
||||
export function findBrotherColorByRGB(
|
||||
r: number,
|
||||
g: number,
|
||||
b: number,
|
||||
): BrotherColor | undefined {
|
||||
return brotherColors.find((c) => c.R === r && c.G === g && c.B === b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Brother color to ThreadColorInfo
|
||||
*
|
||||
* This replicates:
|
||||
* ```csharp
|
||||
* threadColor1.BrandName = brotherColor.BrandName;
|
||||
* threadColor1.BrandCode = brotherColor.BrandCode;
|
||||
* threadColor1.ColorName = brotherColor.ColorName;
|
||||
* threadColor1.ColorCode = brotherColor.ColorCode;
|
||||
* threadColor1.R = brotherColor.R;
|
||||
* threadColor1.G = brotherColor.G;
|
||||
* threadColor1.B = brotherColor.B;
|
||||
* ```
|
||||
*
|
||||
* @param brotherColor - Brother color data
|
||||
* @returns Thread color information
|
||||
*/
|
||||
export function brotherColorToThreadInfo(
|
||||
brotherColor: BrotherColor,
|
||||
): ThreadColorInfo {
|
||||
return {
|
||||
hex: rgbToHex(brotherColor.R, brotherColor.G, brotherColor.B),
|
||||
brand: brotherColor.brandName || "Brother Embroidery",
|
||||
catalogNumber: brotherColor.ColorCode,
|
||||
description: brotherColor.ColorName,
|
||||
chart: brotherColor.ColorCode,
|
||||
rgb: {
|
||||
r: brotherColor.R,
|
||||
g: brotherColor.G,
|
||||
b: brotherColor.B,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a thread color code to full Brother thread information
|
||||
*
|
||||
* This is the main mapping function that replicates the logic from
|
||||
* EmbroideryUtil.GetThreadColorListFromPesx in the C# app.
|
||||
*
|
||||
* Returns null if the color code doesn't match any Brother color (exact match only).
|
||||
*
|
||||
* @param threadCode - Thread code from pattern file (can be string or number)
|
||||
* @returns Thread color information with Brother mapping, or null if code doesn't match
|
||||
*/
|
||||
export function mapThreadCode(
|
||||
threadCode: string | number,
|
||||
): ThreadColorInfo | null {
|
||||
// Parse and pad the thread code
|
||||
const code = padColorCode(threadCode);
|
||||
|
||||
// Look up the Brother color (exact match only)
|
||||
const brotherColor = findBrotherColorByCode(code);
|
||||
|
||||
if (!brotherColor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return brotherColorToThreadInfo(brotherColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a custom thread color (for non-Brother colors)
|
||||
*
|
||||
* This replicates the custom color handling for chartcodes 250-253:
|
||||
* ```csharp
|
||||
* if ("000".Equals(threadCode) && num >= 250 && num <= 253) {
|
||||
* Color colorLong = EmbroideryUtil.GetColorLong(element);
|
||||
* threadColor1.BrandName = "";
|
||||
* threadColor1.BrandCode = num;
|
||||
* threadColor1.ColorName = "";
|
||||
* threadColor1.ColorCode = "0";
|
||||
* threadColor1.R = colorLong.R;
|
||||
* threadColor1.G = colorLong.G;
|
||||
* threadColor1.B = colorLong.B;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param r - Red value (0-255)
|
||||
* @param g - Green value (0-255)
|
||||
* @param b - Blue value (0-255)
|
||||
* @param chartCode - Chart code (250-253 for custom colors)
|
||||
* @returns Thread color information for custom color
|
||||
*/
|
||||
export function createCustomThreadColor(
|
||||
r: number,
|
||||
g: number,
|
||||
b: number,
|
||||
chartCode?: number,
|
||||
): ThreadColorInfo {
|
||||
return {
|
||||
hex: rgbToHex(r, g, b),
|
||||
brand: chartCode !== undefined ? "" : null,
|
||||
catalogNumber: chartCode !== undefined ? "0" : null,
|
||||
description: chartCode !== undefined ? "" : null,
|
||||
chart: chartCode !== undefined ? chartCode.toString() : null,
|
||||
rgb: { r, g, b },
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available Brother colors
|
||||
*
|
||||
* @returns Array of all Brother thread colors
|
||||
*/
|
||||
export function getAllBrotherColors(): BrotherColor[] {
|
||||
return [...brotherColors];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all Brother colors as ThreadColorInfo
|
||||
*
|
||||
* @returns Array of all Brother thread colors as ThreadColorInfo
|
||||
*/
|
||||
export function getAllBrotherThreads(): ThreadColorInfo[] {
|
||||
return brotherColors.map(brotherColorToThreadInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhance thread data with Brother color mapping
|
||||
*
|
||||
* Takes thread data from a PES file and enhances it with Brother color information
|
||||
* using exact matching by catalog number or RGB values.
|
||||
*
|
||||
* 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;
|
||||
},
|
||||
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 by catalog number - use Brother data
|
||||
return brotherInfo;
|
||||
}
|
||||
}
|
||||
|
||||
// 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, g, b },
|
||||
};
|
||||
}
|
||||
Loading…
Reference in a new issue