Getting Image’s Color Palette in Ruby on Rails

Colton Shawn O'Connor
2 min readApr 2, 2021

In my last blog post I wrote about a project where I got the color palette of different movie posters. I wanted to expand that idea further. First I wanted to implement it on mobile using React Native, secondly I wanted to handle my image manipulation on the backend using heroku deployment. To start, I had to figure out how I was gonna get the color palettes of an image using ruby on rails.

After scouring the web for a bit, I came across the ruby gem miro. It requires the use of the ruby gem MiniMagick, but essentially you can pass in an image link and miro will return an array of RGB, hex, or RGBA values. In my FilmsController I created the following route.

def getColorPalette    
Miro.options[:color_count] = params[:palette_num]
response = Miro::DominantColors.new(params[:poster])
render json: response.to_rgb
end

Miro.options[:color_count] = params[:palette_num] sets the number of palettes you want, Miro::DominantColors.new(params[:poster]) grabs the colors from the photo link provided (in this case I called it poster), and response.to_rgb converts the Miro object to an array of rgb values. You can also use .to_hex or .to_rgba to get the data in other formats.

Now that we have the backend setup, lets see how we get these colors on the frontend. In my palette container component in my react native app, I grab the poster from theMovieDB’s database. With this poster image URL, and a route set up to grab it’s color palette, we can make the following fetch call.

const [palettes, setPalette] = useState([])useEffect(() => {    
fetch(`https://film-backend.herokuapp.com/getColorPalette? poster=${poster}&palette_num=9`)
.then(response => response.json())
.then(colors => {
setPalette(colors)
})}, [])

And once we get the nine RGB color values, we can send those to our palette component by returning

return (    
<View style={styles.paletteCard}>
<Text>Color Palette:</Text>
{palettes.map(palette => <PaletteSwatch key={palette} color+={palette}/>)}
</View> )

With our PaletteSwatch component looking something like

export default function PaletteSwatch({ color }) {  
return (
<View
style={[
styles.circle, {backgroundColor: `rgb(${color[0]}, ${color[1]}, ${color[2]})`},]}>
</View>
)
}
const styles = StyleSheet.create({
circle: {
width: 35,
height: 35,
borderRadius: 100 / 2,
borderColor: 'rgb(0,0,0)',
borderWidth: 2,
padding: 10
},
});

And there you have it. You can produce a color palette container for any image by passing a URL to the backend.

I hope this article helps anyone trying to work with design and color palettes in the future. Thank you for reading!

--

--