首页 > 编程开发 > Objective-C编程 >
-
c#画8位彩色图片自定义调色板
此方法参照msdn上的画8位灰阶gif图片的方法。
函数1,2为画自定义彩色图片方法。
函数3(GetColorPalette)和函数4(SaveGIFWithNewGrayscale)为msdn原方法。
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Drawing;
usingSystem.Drawing.Imaging;
namespaceEm_Picture
{
classClass2
{
publicstaticList<Color>cl;
//函数1:
staticvoidDrawPicture()
{
Imageimage=Image.FromFile("加载你的图片:比如一个总共11色的股票行情走势图,其白色为背景色");
//获取11色相对应的调色板
ColorPalettepal=GetColorPalette(11);
//列出图片中所包含的颜色
cl=newList<Color>();
cl.Add(Color.FromArgb(255,0, 0, 0 ));
cl.Add(Color.FromArgb(255,255,0, 0 ));
cl.Add(Color.FromArgb(255,51, 51, 102));
cl.Add(Color.FromArgb(255,102,102,102));
cl.Add(Color.FromArgb(255,0, 128,0 ));
cl.Add(Color.FromArgb(255,128,128,128));
cl.Add(Color.FromArgb(255,206,158,0 ));
cl.Add(Color.FromArgb(255,200,200,200));
cl.Add(Color.FromArgb(255,206,206,206));
cl.Add(Color.FromArgb(255,206,207,156));
cl.Add(Color.FromArgb(255,255,255,255));
//重写调色板前11色
for(inti=0;i<cl.Count;i++)
{
pal.Entries[i]=cl[i];
}
pal.Entries[10]=Color.FromArgb(0,255,255,255);//将其alpha值修改为0,可使背景通透
//调用画8位彩色图函数
SaveGIFWithNewColorTable(image,pal,"你要保存新图片的位置");
}
//函数2:
publicstaticvoidSaveGIFWithNewColorTable(Imageimage,ColorPalettepal,stringfilename)
{
intWidth=image.Width;
intHeight=image.Height;
Bitmapbitmap=newBitmap(Width,Height,PixelFormat.Format8bppIndexed);
bitmap.Palette=pal;
BitmapBmpCopy=newBitmap(Width,Height,PixelFormat.Format32bppArgb);
{
Graphicsg=Graphics.FromImage(BmpCopy);
g.PageUnit=GraphicsUnit.Pixel;
g.DrawImage(image,0,0,Width,Height);
g.Dispose();
}
BitmapDatabitmapData;
Rectanglerect=newRectangle(0,0,Width,Height);
bitmapData=bitmap.LockBits(rect,ImageLockMode.WriteOnly,PixelFormat.Format8bppIndexed);
IntPtrpixels=bitmapData.Scan0;
BitmapDatabmData=BmpCopy.LockBits(rect,ImageLockMode.ReadWrite,PixelFormat.Format32bppArgb);
unsafe
{
byte*pBits;
if(bitmapData.Stride>0)
pBits=(byte*)pixels.ToPointer();
else
pBits=(byte*)pixels.ToPointer()+bitmapData.Stride*(Height-1);
uintstride=(uint)Math.Abs(bitmapData.Stride);
//
byte*p=(byte*)bmData.Scan0;
intoffset=bmData.Stride-Width*4;
//
for(uintrow=0;row<Height;++row)
{
for(uintcol=0;col<Width;++col)
{
//取原图中某个点颜色值
Colorpixel=Color.FromArgb(p[3],p[2],p[1],p[0]);
p+=4;
//获取新图对应点的指针
byte*p8bppPixel=pBits+row*stride+col;
//将原图这个点的颜色所对应的颜色索引值赋给指针
*p8bppPixel=(byte)cl.IndexOf(pixel);
//===========================================================
//其实上面的代码比较消耗性能,改为如下代码较好(也可使用switch函数)
/*
byteb=0;
//判断的顺序为建立颜色表的倒序
//因为白色为背景色,绝大多数判断到这里就会停止
if(p[1]==255)b=10;
elseif(p[1]==207)b=9;
elseif(p[1]==206)b=8;
elseif(p[1]==200)b=7;
elseif(p[1]==158)b=6;
elseif(p[1]==128&&p[2]==128)b=5;
elseif(p[1]==128&&p[2]==0)b=4;
elseif(p[1]==102)b=3;
elseif(p[1]==51)b=2;
elseif(p[1]==0&&p[2]==225)b=1;
elseif(p[1]==0&&p[2]==0)b=0;
p+=4;
byte*p8bppPixel=pBits+row*stride+col;
*p8bppPixel=b;
*/
//===========================================================
}/*endloopforcol*/
p+=offset;
}/*endloopforrow*/
BmpCopy.UnlockBits(bmData);
}/*endunsafe*/
bitmap.UnlockBits(bitmapData);
bitmap.Save(filename,ImageFormat.Gif);
BmpCopy.Dispose();
bitmap.Dispose();
}
//函数3:获取颜色个数相对应的调色板
publicstaticColorPaletteGetColorPalette(uintnColors)
{
//Assumemonochromeimage.
PixelFormatbitscolordepth=PixelFormat.Format1bppIndexed;
ColorPalettepalette; //ThePalettewearestealing
Bitmapbitmap; //Thesourceofthestolenpalette
//Determinenumberofcolors.
if(nColors>2)
bitscolordepth=PixelFormat.Format4bppIndexed;
if(nColors>16)
bitscolordepth=PixelFormat.Format8bppIndexed;
//MakeanewBitmapobjecttogetitsPalette.
bitmap=newBitmap(1,1,bitscolordepth);
palette=bitmap.Palette; //Grabthepalette
bitmap.Dispose(); //cleanupthesourceBitmap
returnpalette; //Sendthepaletteback
}
//函数4:画8位灰阶gif图
publicstaticvoidSaveGIFWithNewGrayscale(Imageimage,stringfilename,uintnColors,boolfTransparent)
{
if(nColors>256)
nColors=256;
if(nColors<2)
nColors=2;
intWidth=image.Width;
intHeight=image.Height;
Bitmapbitmap=newBitmap(Width,Height,PixelFormat.Format8bppIndexed);
ColorPalettepal=GetColorPalette(nColors);
for(uinti=0;i<nColors;i++)
{
uintAlpha=0xFF; //Colorsareopaque.
uintIntensity=i*0xFF/(nColors-1); //Evendistribution.
if(i==0&&fTransparent) //Makethiscolorindex
Alpha=0; //Transparent
pal.Entries[i]=Color.FromArgb((int)Alpha,(int)Intensity,(int)Intensity,(int)Intensity);
}
bitmap.Palette=pal;
BitmapBmpCopy=newBitmap(Width,Height,PixelFormat.Format32bppArgb);
{
Graphicsg=Graphics.FromImage(BmpCopy);
g.PageUnit=GraphicsUnit.Pixel;
g.DrawImage(image,0,0,Width,Height);
g.Dispose();
}
BitmapDatabitmapData;
Rectanglerect=newRectangle(0,0,Width,Height);
bitmapData=bitmap.LockBits(rect,ImageLockMode.WriteOnly,PixelFormat.Format8bppIndexed);
IntPtrpixels=bitmapData.Scan0;
unsafe
{
byte*pBits;
if(bitmapData.Stride>0)
pBits=(byte*)pixels.ToPointer();
else
pBits=(byte*)pixels.ToPointer()+bitmapData.Stride*(Height-1);
uintstride=(uint)Math.Abs(bitmapData.Stride);
for(uintrow=0;row<Height;++row)
{
for(uintcol=0;col<Width;++col)
{
Colorpixel; //Thesourcepixel.
byte*p8bppPixel=pBits+row*stride+col;
pixel=BmpCopy.GetPixel((int)col,(int)row);
doubleluminance=(pixel.R*0.299)+(pixel.G*0.587)+(pixel.B*0.114);
*p8bppPixel=(byte)(luminance*(nColors-1)/255+0.5);
}/*endloopforcol*/
}/*endloopforrow*/
}/*endunsafe*/
bitmap.UnlockBits(bitmapData);
bitmap.Save(filename,ImageFormat.Gif);
BmpCopy.Dispose();
bitmap.Dispose();
}
}
}