几年前有一个流行于 DOS 世界的 Alchemy,现在已公开源码(Linux),参考一下应该有
帮助的。它支持的图像格式超过 50 种,单色至 24 位色。
缩放也有。

解决方案 »

  1.   

    我以前做过同样的东西,但不能符合你的要求:速度快!
    PHOTOSHOP进行转换也不快呀!如果速度要求快,可以考虑将R色其中的3bit,G色其中的3bit,B色其中的2bit合并成一个byte(蓝色敏感都差些),这样组成256色,具体是怎么个处理过程我只是见过,给忘了!
      

  2.   

    但是想作到很好的效果, 估计还是不大可能的.
    现在都什么时代了, 为什么还用256色呢?
    还有tchaikov提出的方法估计购呛, 还不如选择合适的调色板, 这种衰减太过分了.
      

  3.   

    找了一个以前的程序,算法简单,效果也可以。unsigned char* Color256(int sourcelen,int sourcewid)
    {
            int Colorcount[4096];
            short  Colorindex[4096];
            unsigned char *buff;
            buff=new unsigned char[sourcelen*sourcewid*3];
            Contensta=new unsigned char[sourcelen*sourcewid];
            memset(Colorindex,0,4096*sizeof(short));
            memset(Colorcount,0,4096*sizeof(int));
            fseek(fpsource,54,0);
            fread(buff,1,sourcelen*sourcewid*3,fpsource);
            int i,j;
            int blue,green,red,clrindex,colornum=0;
            struct panel{
                    int blue;
                    int green;
                    int red;
                    }pan[256];
            for(i=0;i<sourcelen*sourcewid*3;)
                    {
                    blue=buff[i++]&0xf0;
                    green=buff[i++]&0xf0;
                    red=buff[i++]&0xf0;
                    clrindex=(blue<<4)+green+(red>>4);
                    Colorcount[clrindex]++;
                    }
            for(i=0;i<4096;i++)
                    {
                    if(Colorcount[i]!=0)
                            {
                            Colorcount[colornum]=Colorcount[i];
                            Colorindex[colornum]=short(i);
                            colornum++;
                            }
                    }
            quicksort(Colorcount,Colorindex,0,colornum-1);        for(i=0,j=0;i<256;i++)
                    {
                    bmphead[54+j++]=(Colorindex[colornum-i-1]&0xf00)>>4;
                    bmphead[54+j++]=(Colorindex[colornum-i-1]&0x0f0);
                    bmphead[54+j++]=(Colorindex[colornum-i-1]&0x00f)<<4;
                    bmphead[54+j++]=0;
                    Colorcount[colornum-i-1]=i;
                    pan[i].blue=(Colorindex[colornum-i-1]&0xf00)>>4;
                    pan[i].green=(Colorindex[colornum-i-1]&0x0f0);
                    pan[i].red=(Colorindex[colornum-i-1]&0x00f)<<4;
                    }
            if(colornum>256)
                    {
                    int Colorerror,Colorerr;
                    for(i=0;i<colornum-256;i++)
                            {
                            Colorerr=1000000;
                            blue=(Colorindex[i]&0xf00)>>4;
                            green=(Colorindex[i]&0x0f0);
                            red=(Colorindex[i]&0x00f)<<4;
                            clrindex=0;
                            for(j=0;j<256;j++)
                                    {
                                    Colorerror=(blue-pan[j].blue)*(blue-pan[j].blue)+
                                               (green-pan[j].green)*(green-pan[j].green)+
                                               (red-pan[j].red)*(red-pan[j].red);
                                    if(Colorerror<Colorerr)
                                            {
                                            Colorerr=Colorerror;
                                            clrindex=j;
                                            }
                                    }
                                    Colorcount[i]=clrindex;
                            }
                    }
            for(i=0;i<sourcelen*sourcewid*3;)
                    {
                    blue=buff[i++]&0xf0;
                    green=buff[i++]&0xf0;
                    red=buff[i++]&0xf0;
                    clrindex=(blue<<4)+green+(red>>4);
                    for(j=colornum-1;j>=0;j--)
                            if(clrindex==Colorindex[j])
                                    {
                                    Contensta[sourcewid*(sourcelen-(i-)/3/sourcewid-1)+(i-3)/3%sourcewid]=(unsigned char)(Colorcount[j]);
                                    break;
                                    }
                    }
            delete buff;
            return Contensta;
    }