簡體   English   中英

什么是存儲顏色的好方法?

[英]What is a good way to store color?

我開始制作“生命游戲”,我想,如果我能有比1或0更多的狀態怎么辦?

但后來我需要不同的顏色。 我希望顏色鏈接到網格/對象(網格是一個類)。

什么是一種優質/體面的方式來存儲彩色托盤以便快速/輕松訪問?

我目前不太理想的解決方案是每個紅色,綠色,藍色和alpha值有4個內存指針。

在我的班級中,我有一個函數將值v的顏色設置為rgba:

SetColor(v, r, g, b, a) //Set v to the appropriate color values

我想保持此功能以輕松修改顏色。

我使用的是非常簡單的東西:4個漂浮物

struct Color {
    float r, g, b, a;
};

然后,您可以擁有類似彩色托盤的東西:

// a Palette of 8 colors:
using palette_t = std::array<Color, 8>

palette_t myPalette { /* ... */ };

然后,在您的網格或對象類中,您可以使用索引引用顏色:

struct Grid {
    // lot's of code

private:
    std::size_t colorIndex = 0;
};

但后來你問如何輕松訪問顏色(我想簡單訪問來自Grid類)

有很多解決方案可以存在,而且大多數都取決於您的項目結構。 這是其他許多想法。 我希望它會激勵你。

您可以存儲返回正確顏色的函數:

struct Grid {
    // lot's of code

private:
    std::size_t colorIndex = 0;
    std::function<Color(std::size_t)> color;
};

然后,有一些能夠正確創建網格的東西:

struct GridCreator {
    GridCreator(const palette_t& aPalette) : palette{aPalette} {}

    Grid create(std::size_t color) const {
        Grid grid;

        // create the grid

        grid.color = [this](std::size_t index) {
            return palette[index];
        };

        return grid;
    }

private:
    const palette_t& palette;
};

然后,您可以自由訪問您的調色板,而無需直接知道Grid類中存在調色板。

有一系列顏色:

std::vector<std::array<unsigned char, 4>> palette {
    {255, 0, 0, 255},  // red
    {0, 255, 0, 255},  // green
    {0, 0, 255, 255},  // blue
};

然后為每個字段存儲數組中的索引(類型為size_t )。 例:

auto id = field[5][2];
auto color = palette[id];
auto r = color[0], alpha = color[3];

更改顏色非常簡單:

palette[id] = {255, 0, 0, 127};

要添加新顏色,請使用:

palette.push_back({255, 0, 0, 127}).

或者,您可以定義一個簡單的結構,以便您可以使用color.rcolor.alpha等,並編寫構造函數以便於顏色創建。

記住這個例子是C ++ 11代碼。

枚舉非常適合顏色類型的結構。

  1. 更多代碼可讀性。
  2. 更好的編譯時優化。

     enum Color { red, green, blue }; Color r = red; switch(r) { case red : std::cout << "red\\n"; break; case green: std::cout << "green\\n"; break; case blue : std::cout << "blue\\n"; break; } 

為您的特殊情況。 您可以將每個點的顏色存儲為單個整數。

uint32_t point_color = field[5][2].color;
unsigned char* color = (unsigned char*)point_color[id];
auto r = color[0], alpha = color[3];

///// 

void SetColor(uint32_t& point_color,unsigned char r,
               unsigned char g,unsigned char b,unsigned char a){
   point_color=r | (b*(1<<8)) | (g*(1<<16)) | (a*(1<<24));   
}

這種結構的優點

  1. 較為凌亂。
  2. 僅更快的位操作。
  3. 記憶力較小。

你的問題是二元的:

  • 什么是存儲顏色的好方法?
  • 什么是存儲彩色托盤的好/體面方式?

如果你真的只想存儲顏色,我的建議不是將顏色存儲為參考,而是將RGB值存儲在類中的一個INT32中,您可以在其中獲取並設置Reg / Green / Blue值。 將此與.NET的相關方式進行比較。

這種方法的優點是它沒有比使用指針更多的空間,並且它在get / set / comparisons中很快。

彩色調色板是一組顏色。 如果要將所有使用的顏色切換為不同的顏色,則經常使用此功能。 例如,如果你想要所有淺藍色到朦朧藍色,所有火紅色到磚紅色。

通過將調色板定義為預定義大小的數組或RGB值來使用此方法。 歷史上,調色板包含16,64或256個值,或者如果您只需要黑/白圖片,則有時為2。 如果使用調色板,則網格中的每個點在調色板陣列中都有一個索引,並且您的網格具有當前的調色板。 然后,網格G的點X的RGB值是G.CurrentPallette [X.PaletIndex]。 一次更改網格的所有顏色意味着切換到另一個調色板:G.CurrentPalette = otherPalette。 這是一種非常快速有效的方式來更改網格中的顏色

是使用RGB方法還是Palette方法取決於您的需要:

  • 您是否只想使用所有可能顏色的子集,是否要將完整子集更改為不同的子集:使用Palette方法
  • 是否要更改具有特定狀態的點的顏色,例如將所有黃點更改為綠色,使用調色板方法:將調色板中的黃色更改為綠色
  • 但是,如果您只想更改網格上的單個點,則使用RGB方法可能更有效。

任何顏色值的間隔都是0到255,因此您需要3個unsigned char變量和另一個alph。 我們做了一件事,將它們映射為一個結構:

typedef struct Color
{
    unsigned char _ucRed;
    unsigned char _ucGreen;
    unsigned char _ucBlue;
    unsigned char _ucAlpha;
}COLOR;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM