Jump to: navigation, search

Programmation:Hexadecimal color in openframeworks

Class to load and retrieve string with hexadecimal colors. Usefull when saving the color in an XML file, for instance.

To use this, just create a GColor.h in your project, copy/paste the code and include GColor.h where you need it.

/*
 * Usage: load color by calling set
 * 
 * GColor col();
 * col.set( "f" ); // opaque white
 * col.set( "f00" ); // red
 * col.set( "ff0000" ); // red
 * col.set( "f00a" ); // transparent red
 * col.set( "f0000aa" ); // transparent red
 * 
 * retrieve an ofColor with color()
 * ofBackground( col.color() );
 * 
 * use it directly with apply()
 * it is equivalent to use ofSetColor( col.color() );
 * 
 * print it with str()
 * cout << col.str() << end;
 * 
 * result: "f0000aa", whatever is your input
 * 
 */

/* 
 * File:   Gcolor.h
 * Author: frankiezafe
 *
 * Created on May 5, 2016, 3:08 PM
 */

#ifndef GCOLOR_H
#define GCOLOR_H

#include "ofMain.h"

using namespace std;

union gc {
   uint32_t i;
   unsigned char c[ 4 ]; // RGBA
};

class GColor {
public:
   GColor() {
       _internal.c[ 0 ] = 0;
       _internal.c[ 1 ] = 0;
       _internal.c[ 2 ] = 0;
       _internal.c[ 3 ] = 0;
       ocolor = ofColor( _internal.c[ 0 ], _internal.c[ 1 ], _internal.c[ 2 ], _internal.c[ 3 ] );
   }
   void set( string rgba_hexa ) {
       std::transform( rgba_hexa.begin(), rgba_hexa.end(), rgba_hexa.begin(), ::tolower );
       stringstream ss;
       if ( rgba_hexa.length() == 1 ) {
           // same on all channels
           for ( int i = 0; i < 8; ++i ) ss << rgba_hexa.at( 0 );
           ss >> rgba_hexa;
       } else if ( rgba_hexa.length() == 3 ) {
           // RGB shorten
           for ( int i = 0; i < 6; ++i ) ss << rgba_hexa.at( i / 2 );
           ss << 'f' << 'f';
           ss >> rgba_hexa;
       } else if ( rgba_hexa.length() == 4 ) {
           // RGBA shorten
           for ( int i = 0; i < 8; ++i ) ss << rgba_hexa.at( i / 2 );
           ss >> rgba_hexa;
       } else if ( rgba_hexa.length() == 6 ) {
           for ( int i = 0; i < 6; ++i ) ss << rgba_hexa.at( i );
           ss << 'f' << 'f';
           ss >> rgba_hexa;
       }
       if ( rgba_hexa.length() != 8 ) {
           cerr << "GColor::set(), wrong color format: 3,4,6 and 8 digits are allowed, " << rgba_hexa << endl;
           return;
       }
       // inverting channels
       std::stringstream ss1;
       for ( int i = 3; i >= 0; --i ) { 
           ss1 << rgba_hexa.at( i * 2 );
           ss1 << rgba_hexa.at( i * 2 + 1 );
       }
       ss1 >> rgba_hexa;
       // conversion to int 32
       std::stringstream ss2;
       ss2 << std::hex << rgba_hexa;
       ss2 >> _internal.i;
       // generation of ofColor
       ocolor = ofColor( _internal.c[ 0 ], _internal.c[ 1 ], _internal.c[ 2 ], _internal.c[ 3 ] );
   }
   unsigned char & operator [] ( unsigned int p ) {
       return _internal.c[ p ];
   }
   string str() {
       std::stringstream stream;
       stream << std::hex << _internal.i;
       string out = stream.str();
       std::reverse( out.begin(), out.end() );
       return out;
   }
   void apply() {
       ofSetColor( _internal.c[ 0 ], _internal.c[ 1 ], _internal.c[ 2 ], _internal.c[ 3 ] );
   }
   ofColor color() {
       return ocolor;
   }
protected:
   gc _internal;
   ofColor ocolor;
   
};

#endif /* GCOLOR_H */


--Frankiezafe (talk) 15:21, 5 May 2016 (CEST)