iPhone上下文:如何从图像中提取调色板信息?

时间:2010-02-10 00:44:11

标签: iphone objective-c colors quartz-graphics palette

大家好:我想拍照并检索分析其调色板的主色(我认为这应该是最简单的方法),但我不知道从哪里开始。

1 个答案:

答案 0 :(得分:0)

假设您有一个原始的24位RGB图像,并且您想要找到每种颜色出现的次数:

实际上有两种简单的方法:

我最喜欢的只是为每种可能的颜色创建一个int数组,然后只是索引到那个数组和那个方法使用的++,就像64 meg的内存一样。

另一种方法是创建一个链表,每次遇到一个新颜色时添加它,存储在列表中的结构会存储颜色和遇到的次数,它会慢慢地完成所有累积因素搜索每个像素的整个列表,但按使用次数排序会更快,因为只有实际使用的颜色在列表中(使其更适合小图像)

我喜欢两者之间的妥协:

比方说,红色和绿色索引到链接列表数组,这样数组只有256k(假设它只存储指向列表的指针),搜索列表相对较短,因为它只有蓝色红色,绿色的变种。如果你只对SINGLE MOST使用的颜色感兴趣,我会把它存储在一个“最大颜色”变量中,我会比较每次迭代一个像素并增加一个颜色,这样你就不必通过整个结构搜索最后使用最多的结构。

struct Pixel
{
   byte R,G,B;
}

const int noPixels = 1024*768; // this is whatever the number of pixels you have is

Pixel pixels[noPixels]; // this is your raw array of pixels

unsinged int mostUsedCount = 0;
Pixel mostUsedColor;

struct ColorNode
{
    ColorNode* next;
    unsigned int count;
    byte B;
} 

ColorNode* RG = new ColorNode[256*256];
memset(RG,0,sizeof(ColorNode)*256*256);

for(int i = 0; i<noPixels; i++)
{
   int idx = pixels[i].R + pixels[i].G*256;
   ColorNode*t;
   for(t=RG[idx]; t; t = t->next)
   {
      if(t->B == pixels[i].B)
      {
          break;
      }
   }
   if(!t)
   {
       t = new ColorNode;
       t->next = RG[idx];
       RG[idx] = t;
       t->B = pixels[i].B;
       t->count = 0;
   }

   t->count++;
   if(t->count > mostUsedCount)
   {
       mostUsedCount = t->count;
       mostUsedColor = pixels[i];
   }
}

您可能会考虑使用二叉树或某种树,而不仅仅是搜索这样的列表。但我对这类事情知之甚少......

哦,是的......我忘记了内存管理。

你可以浏览整个数组并删除所有需要删除的节点,但这很无聊。

如果可能的话,在开头分配你可能需要的所有内存,即256k + sizeof(ColorNode)* noPixels~ = 256 +原始图像数据大小的2到3倍。

这样你就可以使用简单的堆栈方法将节点拉出来,然后一次性删除所有内容。

你可以做的另一件事是将节点添加到所有已分配节点的另一个链接列表中,这会增加迭代过程,将数据添加到Color节点,并且只需要遍历整个数组以查找列表到删除。