参照有关资料,写了几个类,用来实现真彩色图像转16色、256色索引图像。下面是PNG图片转换效果图:
左边是PNG源图,中间是转换后存储的白色背景GIF图片(设置ColorBackground属性可改变背景颜色),右边是没经过转换直接存储的GIF图片。完整代码见我的BLOG文章:http://blog.csdn.net/maozefa/archive/2009/09/24/4592103.aspx

解决方案 »

  1.   

    关于真彩色图像转索引图像我也研究了很多,关键是两点:一是调色板的获取,二是像素抖动。要有好的效果,必须有优良的调色板和好的抖动方法,一般来说八叉树法找图像的流行色所获得的调色板是非常好的,但是这里有个效率问题,对于大图像必须注意,比较恰当的做法是先生成这个图像的一个比较小的(比如150*100,要保证长宽比不变),然后计算这个图像的流行色。 
    抖动的目的是为了增强图像的视觉效果,有很多中抖动方式,经典的莫过于flyod抖动了。
      

  2.   

    to laviewpbt:谢谢评点,我只不过采用了最常规的转换办法,并没实现抖动。其实,在测试的时候发现,计算调色板耗时并不大,关键是像素调色板匹配太费时间了,不知是否有更快速的匹配算法(保证质量前提下)?
      

  3.   

    en 
    这个也是个耗时个过程,GDI函数中有个GetNearestPaletteIndex,但是这里还是可以进一步优化的
    通常是这样做的    
        With logPal
            .palNumEntries = mUsedColor
            .palVersion = &H300
             CopyMemory .palPalEntry(0), ColorTable(0), mUsedColor * 4
        End With
        mhPal = CreatePalette(logPal)
        For i = 0 To 15
            For j = 0 To 15
                For k = 0 To 15
                    RGB4096(i, j, k) = GetNearestPaletteIndex(mhPal, RGB(k * 17, j * 17, i * 17))
                Next
            Next
        Next
        DeleteObject mhPal
    以上代码中ColorTable就是你找到的最优调色板。RGB4096数组中就保存了量化到一定空间的颜色对应的调板索引。当想取得某个RGB颜色对应的索引时,可以这样做NewImageData(Fast) = RGB4096(Spd16(ImageData(Speed + 2)), Spd16(ImageData(Speed + 1)), Spd16(ImageData(Speed)))其中Spd16大概为。
        For i = 0 To 255
            Spd16(i) = (i + 8) \ 17
            If (Spd16(i) < 0) Then Spd16(i) = 0
            If (Spd16(i) > 16) Then Spd16(i) = 16
        Next
      

  4.   

    我用过GetNearestPaletteIndex函数,和我自写的匹配代码质量基本一致,但速度更慢:同一张图片在我的机器上,整个转换过程耗时282ms,用我写的BASM匹配代码耗时为171ms,即使我写的纯Delphi匹配代码耗时也只有255ms