您当前位置: 圣才学习网首页 >> IT类 >> .NET程序设计

GDI+高频问题思考(6)

扫码手机阅读
用圣才电子书APP或微信扫一扫,在手机上阅读本文,也可分享给你的朋友。
评论(0
   
来源:网络 作者:未知
 
  6.2 GIF
 
  GIF的全称是图像交换格式Graphics Interchange Format,是CompuServe公司在1987年创建并使用的。这种格式使用8位索引值来表达一个像素,也就是说1个像素1byte,最多可以表示256种颜色。它使用LZW无损压缩算法来对图像进行压缩,之后这家公司又和几家其他的公司发明了PNG文件格式,并被更广泛地应用在Web以及其他领域。GIF支持动画,可以保存数个帧并不断地播放。关于动画的部分我们将会放到非常后面来讲,现在只谈谈GIF的透明。
 
  在GIF文件的头部有一个调色板Palette,里面保存了颜色的信息。一般而言,如果对GIF 进行LockBits的操作,只能把它lockFormat*bppIndexed,这样才不会导致前面调色板信息的丢失,在处理上也更方便一些。在调色板里面定义了透明的颜色,也就是说当实际数据为这个颜色时,那个位置的颜色为透明。让我们来看看Palette是怎么使用的。顺便再说一句GIF没有半透明,只支持完全透明或者不透明。此外,在一个调色板中,只有一种颜色可以设置为透明,这是GIF标准所决定的。
 
  1         public static unsafe void ConvertTransparancyGif(int colorIndex, string baseFile, string outputFile)
 
  2         {
 
  3             using (FileStream fs = new FileStream(baseFile, FileMode.Open, FileAccess.Read))
 
  4             {
 
  5                 Bitmap img = (Bitmap)Image.FromStream(fs, false, false);
 
  6                 int width = img.Width;
 
  7                 int height = img.Height;
 
  8
 
  9                 Bitmap resultbmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
 
  10                 ColorPalette palette = resultbmp.Palette;
 
  11                 int n = 0;
 
  12                 foreach (Color tc in img.Palette.Entries)
 
  13                 {
 
  14                     palette.Entries[n] = Color.FromArgb(255, tc);
 
  15                     n++;
 
  16                 }
 
  17
 
  18                 palette.Entries[colorIndex] = Color.FromArgb(0, palette.Entries [colorIndex]);
 
  19                 resultbmp.Palette = palette;
 
  20
 
  21                 //now to copy the actual bitmap data
 
  22                 BitmapData src = img.LockBits
 
  23                     new Rectangle(0, 0, width, height),
 
  24                     ImageLockMode.ReadOnly,
 
  25                     img.PixelFormat);
 
  26
 
  27                 BitmapData dst = resultbmp.LockBits
 
  28                     new Rectangle (0, 0, width, height),
 
  29                     ImageLockMode.WriteOnly,
 
  30                     resultbmp.PixelFormat);
 
  31
 
  32                 byte* pSrc = (byte*)src.Scan0.ToPointer();
 
  33                 byte* pDst = (byte*)dst.Scan0.ToPointer();
 
  34                 int offset = src.Stride - width;
 
  35
 
  36                 //steps through each pixel
 
  37                 for (int y = 0; y < height; y++)
 
  38                 {
 
  39                     for (int x = 0; x < width; x++)
 
  40                     {
 
  41                         pDst[0] = pSrc[0];
 
  42                         pDst++;
 
  43                         pSrc++;
 
  44                     }
 
  45                     pDst += offset;
 
  46                     pSrc += offset;
 
  47                 }
 
  48
 
  49                 //unlock the bitmaps
 
  50                 img.UnlockBits(src);
 
  51                 resultbmp.UnlockBits(dst);
 
  52
 
  53                 resultbmp.Save(outputFile, ImageFormat.Gif);
 
  54
 
  55                 img.Dispose();
 
  56                 resultbmp.Dispose();
 
  57             }
 
  59         }
 
  请注意,在这里,我读图的时候和我之前推荐的方法不同。我没有创建一个新的Bitmap ,这是因为在创建新的Bitmap的时候,调色板信息会完全丢失,所以Indexed的格式不可以随意进行复制,否则将造成信息的丢失。这也就是为什么当时我说这是一个土办法的原因。真正的好办法是复制那个流,而不是直接去复制Bitmap。不过那是看需求的。在创建一个带透明颜色的GIF的时候,只要创建一个调色板,就一切OK了。这比Alpha通道修正要简单。还可以参考KB 319061 http://support.microsoft.com/kb/319061/en-us
 
  最后提一句,Bitmap类还提供了一个MakeTransparent方法用于设置透明颜色,不过只对 PNG有效。
 
相关阅读
 
 

小编工资已与此挂钩!一一分钱!求打赏↓ ↓ ↓

如果你喜欢本文章,请赐赏:

已赐赏的人
最新评论(共0条)评论一句