The @bbplayer/image-theme-colors package is a native Expo module that extracts color palettes from images using platform-native color extraction algorithms. It provides access to dominant, vibrant, muted, and other color swatches with their recommended text colors.
Installation
npm install @bbplayer/image-theme-colors
This package requires Expo 55+ and is designed to work with Expo’s native module system.
Basic Usage
import ExpoImageThemeColors from '@bbplayer/image-theme-colors';
// Extract colors from an image URL
const palette = await ExpoImageThemeColors.extractThemeColorAsync(
'https://example.com/image.jpg'
);
if (palette) {
console.log('Dominant color:', palette.dominant?.hex);
console.log('Vibrant color:', palette.vibrant?.hex);
console.log('Image dimensions:', palette.width, 'x', palette.height);
}
API Reference
Extracts a color palette from an image source.
function extractThemeColorAsync(
source: string | SharedRef<'image'> | ImageRef
): Promise<ExtractedPalette | null>
source
string | SharedRef<'image'> | ImageRef
required
The image source to extract colors from. Can be:
- A URL string (http/https)
- A local file URI
- An Expo ImageRef from the
expo-image component
- A SharedRef to a native image instance
Returns: A Promise that resolves to an ExtractedPalette object or null if extraction fails.
Type Definitions
The complete color palette extracted from an image.
type ExtractedPalette = {
width: number;
height: number;
dominant: ColorInfo | null;
vibrant: ColorInfo | null;
lightVibrant: ColorInfo | null;
darkVibrant: ColorInfo | null;
muted: ColorInfo | null;
lightMuted: ColorInfo | null;
darkMuted: ColorInfo | null;
}
The width of the analyzed image in pixels
The height of the analyzed image in pixels
The most prominent color in the image
A vibrant, saturated color from the image
A light, vibrant color variant
A dark, vibrant color variant
A muted, less saturated color from the image
A light, muted color variant
A dark, muted color variant
ColorInfo
Detailed information about a specific color swatch.
interface ColorInfo {
hex: string;
titleTextColor: string;
bodyTextColor: string;
population: number;
}
The color as a 6-digit hexadecimal value (e.g., "#FF0000")
Recommended text color for titles when using this background color (e.g., "#FFFFFF")
Recommended text color for body text when using this background color (e.g., "#000000")
The number of pixels in the image that match this color, indicating its prominence
Usage with Expo Image
You can use this package with Expo’s Image component by accessing its ImageRef:
import { Image } from 'expo-image';
import ExpoImageThemeColors from '@bbplayer/image-theme-colors';
import { useRef } from 'react';
function AlbumArt() {
const imageRef = useRef<ImageRef>(null);
const extractColors = async () => {
if (imageRef.current) {
const palette = await ExpoImageThemeColors.extractThemeColorAsync(
imageRef.current
);
// Use the extracted colors
}
};
return (
<Image
ref={imageRef}
source={{ uri: 'https://example.com/album.jpg' }}
onLoad={extractColors}
/>
);
}
Practical Example
Create dynamic UI based on album artwork:
import ExpoImageThemeColors from '@bbplayer/image-theme-colors';
import { View, Text, StyleSheet } from 'react-native';
import { useState, useEffect } from 'react';
function MusicPlayer({ albumUrl }: { albumUrl: string }) {
const [colors, setColors] = useState<ExtractedPalette | null>(null);
useEffect(() => {
ExpoImageThemeColors.extractThemeColorAsync(albumUrl)
.then(setColors);
}, [albumUrl]);
if (!colors?.vibrant) return null;
return (
<View
style={[
styles.container,
{ backgroundColor: colors.vibrant.hex }
]}
>
<Text style={{ color: colors.vibrant.titleTextColor }}>
Now Playing
</Text>
<Text style={{ color: colors.vibrant.bodyTextColor }}>
Song details here
</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
padding: 20,
borderRadius: 12,
},
});
- iOS: Uses native color palette extraction
- Android: Uses native color palette extraction
Both platforms use optimized native implementations for fast color extraction.