2010-09-09 71 views
0

我需要编写一些代码,这些代码可以处理多种像素格式(例如A8R8G8B8,R8G8B8,R5G6B6,甚至可能是浮点格式)。支持多种像素格式

理想情况下,我想不必为每种格式编写每个函数,因为这是大量近乎相同的代码。

我能想到的唯一的事情是某种接口让它处理像素格式转换,例如:

class IBitmap 
{ 
public: 
    virtual unsigned getPixel(unsigned x, unsigned y)const=0; 
    virtual void setPixel(unsigned x, unsigned y, unsigned argb)=0; 
    virtual unsigned getWidth()const=0; 
    virtual unsigned getHeight()const=0; 
}; 

但是呼吁虚函数每次获取或设置像素的操作是很难快,因为不只有虚拟调用的额外开销,但是更重要的是防止内联仅仅是几条指令的内容。

是否有任何其他选项可以让我有效地支持所有这些格式?一般来说,我的代码可能只能在小部分位图上运行,并且在很多情况下(混合)需要读/写访问权限。

回答

0

在现代处理器上,虚拟功能相当麻烦,所以我不确定我会否决它们。确保运行一个或两个时间测试。虚拟函数为您提供了运行时多态性,可以让您设想(或在编译时生成)更少的代码。由模板表示的静态多态性可能会导致编译器生成您试图避免的大量代码。

+1

设置像素的工作量很小,调用虚拟函数(甚至普通函数)的开销与函数本身的工作量大致相同或更大。特别是如果您拨打50万次SetPixel来覆盖表面,则可能会浪费一半或更多的时间来处理函数调用。是的,虚拟功能很快,但不适用于setpixel功能。 – AshleysBrain 2010-09-09 13:37:11

0

为了避免写入格式的负载,编写一个Color类或类似的总是存储特定格式的文件(例如A8R8G8B8或A32R32G32B32F),然后使用该类的方法以不同的格式进行检索,例如。 get(FORMAT_R5G6B6)或类似的。然后你所有的方法都可以处理那个类。只要有可能,只将颜色转换一次(例如,在绘制矩形时,将矩形颜色转换为目标格式,然后将其写入所有像素 - 不要将其转换为每个像素!)。

避免使用SetPixel/GetPixel方法。它不能有效地完成,特别是如果你正在进行颜色转换,特别是如果优化器决定不内联这些调用。你最好直接公开内存缓冲区,并相信调用者会正确使用内存。这就是我之前使用过的每个其他API都是如此。

0

(这是我的新的答案,因为经过广泛的研究,我得出的结论是GIL的Adobe不适合这个目的。)

我会强烈建议Windows图像处理组件的架构和接口设计。

我的意思是:

  • 它们的接口是什么,我建议。不是执行。
    • 每个人都可以实现类似的东西。事实上,Mono项目(葡萄酒)包含WIC的部分实施。
  • WIC使用流水线存储模型,而不是生产者 - 消费者模型。
    • 一个只读位图实现IWICBitmapSource接口
      • 只有5构件的方法。
    • 的可写位图实现IWICBitmap接口并提供给像素数据直接存储器读/写访问。
      • IWICBitmapSource上只有3个额外的成员方法。
      • 作为“存储”类意味着此类在生成像素值时不依赖于任何其他位图实例。
0

一切转换为一个单一的通用格式,然后在手术后转换回的开销,可能会小于你的想法。如果您可以限制一次转换的像素数量,例如对单个行,则中间结果可能会保留在缓存中以用于整个操作。我实际上已经看到了一种使用这种方法的端到端时间为更快的情况,尽管它涉及一位像素,在仍然打包时固有地难以处理。

对于像素级函数调用你是对的。我从来没有见过一个像素功能没有使处理速度变得难以接受的情况。