Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/soymatudev/Pokedex-Fleek/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The Color Analysis system is the core algorithm that identifies Pokémon based on the dominant color of scanned objects. It uses react-native-image-colors to extract colors and a custom HSL hue-based matching system to map colors to Pokémon.

Color Extraction

Using react-native-image-colors

After capturing a photo, the dominant color is extracted:
import ImageColors from 'react-native-image-colors';

const photo = await cameraRef.current.takePhoto({
  flash: 'off',
  skipMetadata: true
});

const result = await ImageColors.getColors(photo.path, { 
  fallback: '#000000' 
});

const detectedHex = result.platform === 'android' 
  ? result.dominant 
  : result.background;

Platform Differences

  • Android: Uses result.dominant - the most dominant color in the image
  • iOS: Uses result.background - the background color detected by the algorithm

Hex to Hue Conversion

The extracted hex color is converted to an HSL hue value (0-360°):
const hexToHue = (hex) => {
  if (!hex || hex.length < 6) return 0;
  const cleanHex = hex.startsWith('#') ? hex : `#${hex}`;

  // Convert hex to RGB
  let r = parseInt(cleanHex.slice(1, 3), 16) / 255;
  let g = parseInt(cleanHex.slice(3, 5), 16) / 255;
  let b = parseInt(cleanHex.slice(5, 7), 16) / 255;

  let max = Math.max(r, g, b), min = Math.min(r, g, b);
  let h, d = max - min;

  if (d === 0) h = 0;
  else if (max === r) h = (g - b) / d + (g < b ? 6 : 0);
  else if (max === g) h = (b - r) / d + 2;
  else if (max === b) h = (r - g) / d + 4;

  return Math.round(h * 60);
};

Algorithm Breakdown

  1. Normalize hex: Ensure hex string is properly formatted
  2. Convert to RGB: Parse hex values to RGB components (0-1)
  3. Find max/min: Determine the maximum and minimum RGB values
  4. Calculate hue: Use the HSL hue formula based on which component is dominant
  5. Convert to degrees: Multiply by 60 to get hue in 0-360° range

Pokémon Color Database

The POKEMON_DB object maps Pokémon to color ranges:
export const POKEMON_DB = {
  // Green Pokémon (Hue: 80 - 160)
  "001": { 
    id: "001", 
    name: "Bulbasaur", 
    colorRange: { hueMin: 80, hueMax: 160 }, 
    uiTheme: "#4E8234" 
  },
  "002": { 
    id: "002", 
    name: "Ivysaur", 
    colorRange: { hueMin: 80, hueMax: 160 }, 
    uiTheme: "#4E8234" 
  },
  
  // Red/Orange Pokémon (Hue: 0 - 40)
  "004": { 
    id: "004", 
    name: "Charmander", 
    colorRange: { hueMin: 0, hueMax: 40 }, 
    uiTheme: "#F08030" 
  },
  
  // Blue Pokémon (Hue: 170 - 260)
  "007": { 
    id: "007", 
    name: "Squirtle", 
    colorRange: { hueMin: 170, hueMax: 260 }, 
    uiTheme: "#6890F0" 
  },
  
  // Yellow Pokémon (Hue: 45 - 75)
  "025": { 
    id: "025", 
    name: "Pikachu", 
    colorRange: { hueMin: 45, hueMax: 75 }, 
    uiTheme: "#F8D030" 
  },
  
  // Purple/Pink Pokémon (Hue: 270 - 350)
  "092": { 
    id: "092", 
    name: "Gastly", 
    colorRange: { hueMin: 270, hueMax: 320 }, 
    uiTheme: "#705898" 
  },
};

Color Range Categories

Green (80° - 160°)

  • Bulbasaur, Ivysaur, Venusaur
  • Caterpie, Metapod
  • Bellsprout

Red/Orange (0° - 40°)

  • Charmander, Charmeleon, Charizard
  • Vulpix, Growlithe
  • Magmar

Blue (170° - 260°)

  • Squirtle, Wartortle, Blastoise
  • Psyduck, Lapras

Yellow (45° - 75°)

  • Pikachu, Raichu
  • Electabuzz, Zapdos

Purple/Pink (270° - 350°)

  • Clefairy, Jigglypuff
  • Gastly, Gengar
  • Mewtwo, Mew

Gray/Brown (Low Saturation)

  • Geodude, Onix
  • Uses full hue range with saturation constraint

Matching Algorithm

The hue value is compared against the color ranges:
const hue = hexToHue(detectedHex);

const match = Object.values(POKEMON_DB).find(p =>
  hue >= p.colorRange.hueMin && hue <= p.colorRange.hueMax
);

if (match) {
  setDetectedPokemon(match);
  console.log("Match encontrado:", match.name);
  
  setTimeout(() => {
    navigation.navigate('Details', { pokemonId: match.id });
  }, 1000);
} else {
  console.log("Color no reconocido.");
}

Random Selection from Matches

For manual scans, if multiple Pokémon share a color range, one is randomly selected:
const potentialMatches = Object.values(POKEMON_DB).filter(p =>
  hue >= p.colorRange.hueMin && hue <= p.colorRange.hueMax
);

if (potentialMatches.length > 0) {
  const randomIndex = Math.floor(Math.random() * potentialMatches.length);
  const match = potentialMatches[randomIndex];
  
  setDetectedPokemon(match);
  // Navigate to details...
}
This adds variety when scanning the same color multiple times.

UI Theme Colors

Each Pokémon entry includes a uiTheme color for consistent UI styling:
"025": { 
  id: "025", 
  name: "Pikachu", 
  colorRange: { hueMin: 45, hueMax: 75 }, 
  uiTheme: "#F8D030"  // Pikachu's signature yellow
}
This color is passed to the Details screen for type-based theming.

Example Color Ranges

ColorHue RangeExample PokémonHex Example
Red0° - 40°Charmander#F08030
Yellow45° - 75°Pikachu#F8D030
Green80° - 160°Bulbasaur#4E8234
Blue170° - 260°Squirtle#6890F0
Purple270° - 320°Gengar#705898
Pink270° - 350°Clefairy#EE99AC

Workflow

  1. User scans object with camera
  2. Photo is captured
  3. Dominant color is extracted (hex)
  4. Hex is converted to HSL hue (0-360°)
  5. Hue is matched against Pokémon color ranges
  6. Matching Pokémon is selected (random if multiple matches)
  7. User is navigated to Pokémon details

Future Enhancements

Potential improvements to the color analysis system:
  • Saturation filtering: Better handling of gray/brown colors
  • Multi-color detection: Match Pokémon with multiple dominant colors
  • Machine learning: Train a model to recognize Pokémon more accurately
  • Confidence scoring: Show match confidence to users

See Also

Implementation: