//============================================================ // <T>存储索引颜色。</T> // // @param output 输出流 // @param quantizer 优化器 // @param bitmap 位图对象 //============================================================ protected void StoreIndexedColor(IOutput output, Bitmap bitmap, int colorCount, int cx, int cy) { // 优化图形 FPictureQuantizer pictureQuantizer = new FPictureQuantizer(_quantizerCd); IColorQuantizer colorQuantizer = pictureQuantizer.LoadQuantizerColors(bitmap, FPictureQuantizer.EQuantizedMode.Rgb); int colorTotal = colorQuantizer.GetColorCount(); // 构造调色板 Color[] palette = colorQuantizer.MakePalette(colorCount).ToArray(); // 输出调色板 int paletteCount = palette.Length; output.WriteUint8((byte)paletteCount); foreach (Color color in palette) { output.WriteInt32(color.ToArgb() & 0x00FFFFFF); } // 输出颜色数组 int width = bitmap.Width; int height = bitmap.Height; for (int h = 0; h < height; h++) { for (int w = 0; w < width; w++) { Color color = bitmap.GetPixel(w, h); int index = colorQuantizer.FindPaletteIndex(Color.FromArgb(255, color)); output.WriteUint8((byte)index); output.WriteUint8(color.A); } } _logger.Debug(this, "StoreIndexedColor", "Make indexed color. (position={0}-{1}, color_total={2}, color_count={3})", cx, cy, colorTotal, paletteCount); }
/// ============================================================ /// <summary>生成指定颜色数目的图形。</summary> /// <param name="colorCount">颜色数目</param> /// <returns>图形</returns> /// ============================================================ public Bitmap BuildQuantizedImage(int colorCount) { // 生成调色板 Color[] palette = _quantizer.MakePalette(colorCount).ToArray(); // 创建输出图像 int width = _imageSource.Width; int height = _imageSource.Height; Bitmap result = new Bitmap(width, height, PixelFormat.Format32bppArgb); // 绘制输出图形颜色 Rectangle bounds = Rectangle.FromLTRB(0, 0, width, height); BitmapData sourceData = _imageSource.LockBits(bounds, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); BitmapData targetData = result.LockBits(bounds, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); try { // 初始化读取和写入缓冲 int[] sourceBuffer = new int[width]; int[] targetBuffer = new int[width]; long sourceOffset = sourceData.Scan0.ToInt64(); long targetOffset = targetData.Scan0.ToInt64(); // 处理所有原图像颜色 for (int row = 0; row < height; row++) { // 读取一行 Marshal.Copy(new IntPtr(sourceOffset), sourceBuffer, 0, width); // 通过调色板转换颜色 for (Int32 index = 0; index < width; index++) { Color color = Color.FromArgb(sourceBuffer[index]); int paletteIndex = _quantizer.FindPaletteIndex(color); targetBuffer[index] = palette[paletteIndex].ToArgb(); } // 写入一行 Marshal.Copy(targetBuffer, 0, new IntPtr(targetOffset), width); // 修正行边界 sourceOffset += sourceData.Stride; targetOffset += targetData.Stride; } } finally { // 释放图像对象 _imageSource.UnlockBits(sourceData); result.UnlockBits(targetData); } // 返回结果 return(result); }
//============================================================ // <T>序列化位图的一个区块。</T> // // @params output 输出流 // @params colorQuantizer 颜色优化器 // @params rect 序列化的矩形区域 // @params colorCount 颜色数量 //============================================================ protected bool SerializeBlock(IOutput output, IColorQuantizer colorQuantizer, SIntRectangle rect, int colorCount) { int blockWidth = rect.Width; int blockHeight = rect.Height; output.WriteUint16((ushort)blockWidth); output.WriteUint16((ushort)blockHeight); // 构造调色板 Color[] palette = null; if (_optionAlpha) { palette = colorQuantizer.MakePalette(colorCount).ToArray(); if (0 == palette.Length) { RMoCore.TrackConsole.Write(this, "SerializeBlock", "Palette color is empty."); return(false); } } else { List <Color> colorList = colorQuantizer.MakePalette(colorCount); if (0 == colorList.Count) { RMoCore.TrackConsole.Write(this, "SerializeBlock", "Palette color is empty."); return(false); } colorList.Add(Color.Transparent); palette = colorList.ToArray(); } // 输出调色板 int paletteCount = palette.Length; output.WriteUint16((ushort)paletteCount); foreach (Color color in palette) { if (_optionAlpha) { output.WriteInt32(color.ToArgb() & 0x00FFFFFF); } else { output.WriteInt32(color.ToArgb()); } } // _logger.Debug(this, "SerializeIndexed", "block_size={0}x{1}, color={2}, alpha={3}", blockWidth, blockHeight, paletteCount, _optionAlpha); // 输出颜色数组 int x = rect.Left; int y = rect.Top; // 透明色索引 int transparentIndex = palette.Length - 1; int size = blockWidth * blockHeight; // 写入数组 int postion = 0; byte[] bytes = null; if (_optionAlpha) { // 写入索引颜色和透明度 bytes = new byte[size * 2]; for (int h = 0; h < blockHeight; h++) { for (int w = 0; w < blockWidth; w++) { Color color = _native.GetPixel(x + w, y + h); int index = colorQuantizer.FindPaletteIndex(Color.FromArgb(255, color)); bytes[postion++] = (byte)index; bytes[postion++] = color.A; } } } else { // 写入带透明的索引颜色 bytes = new byte[size]; for (int h = 0; h < blockHeight; h++) { for (int w = 0; w < blockWidth; w++) { Color color = _native.GetPixel(x + w, y + h); int index = colorQuantizer.FindPaletteIndex(color); bytes[postion++] = (byte)index; } } } output.WriteBytes(bytes, 0, postion); return(true); }
//============================================================ // <T>序列化位图的一个区块。</T> // // @params output 输出流 // @params colorQuantizer 颜色优化器 // @params rect 序列化的矩形区域 // @params colorCount 颜色数量 //============================================================ protected bool SerializeUnpackBlock(IOutput output, IColorQuantizer colorQuantizer, SIntRectangle rect, int colorCount) { int blockWidth = rect.Width; int blockHeight = rect.Height; output.WriteUint16((ushort)blockWidth); output.WriteUint16((ushort)blockHeight); // 构造调色板 Color[] palette = null; if (_optionAlpha) { palette = colorQuantizer.MakePalette(colorCount).ToArray(); if (0 == palette.Length) { RMoCore.TrackConsole.Write(this, "SerializeBlock", "Palette color is empty."); return(false); } } else { List <Color> colorList = colorQuantizer.MakePalette(colorCount); if (0 == colorList.Count) { RMoCore.TrackConsole.Write(this, "SerializeBlock", "Palette color is empty."); return(false); } colorList.Add(Color.Transparent); palette = colorList.ToArray(); } // 输出颜色数组 int x = rect.Left; int y = rect.Top; // 写入数组 if (_optionAlpha) { // 写入索引颜色和透明度 for (int h = 0; h < blockHeight; h++) { for (int w = 0; w < blockWidth; w++) { Color color = _native.GetPixel(x + w, y + h); int index = colorQuantizer.FindPaletteIndex(Color.FromArgb(255, color)); Color c = Color.FromArgb(color.A, palette[index]); output.WriteInt32(c.ToArgb()); } } } else { // 写入带透明的索引颜色 for (int h = 0; h < blockHeight; h++) { for (int w = 0; w < blockWidth; w++) { Color color = _native.GetPixel(x + w, y + h); int index = colorQuantizer.FindPaletteIndex(color); output.WriteInt32(palette[index].ToArgb()); } } } return(true); }
//============================================================ // <T>序列化位图的一个区块。</T> // // @params output 输出流 // @params colorQuantizer 颜色优化器 // @params rect 序列化的矩形区域 // @params colorCount 颜色数量 //============================================================ protected bool SerializeBlock(IOutput output, IColorQuantizer colorQuantizer, SIntRectangle rect, int colorCount) { FByteStream stream = new FByteStream(); int blockWidth = rect.Width; int blockHeight = rect.Height; // 写入设置 stream.WriteBool(_optionAlpha); stream.WriteUint16((ushort)blockWidth); stream.WriteUint16((ushort)blockHeight); // 构造调色板 Color[] palette = null; if (_optionAlpha) { palette = colorQuantizer.MakePalette(colorCount).ToArray(); if (0 == palette.Length) { RMoCore.TrackConsole.Write(this, "SerializeBlock", "Palette color is empty."); return(false); } } else { List <Color> colorList = colorQuantizer.MakePalette(colorCount); if (0 == colorList.Count) { RMoCore.TrackConsole.Write(this, "SerializeBlock", "Palette color is empty."); return(false); } colorList.Add(Color.FromArgb(0, 0, 0, 0)); palette = colorList.ToArray(); } // 输出调色板 int paletteCount = palette.Length; stream.WriteUint16((ushort)paletteCount); //if(RResourceManager.IsColoPremultiplied) { // foreach (Color color in palette) { // if (_optionAlpha) { // stream.WriteInt32(color.ToArgb() & 0x00FFFFFF); // } else { // byte a = color.A; // byte r = (byte)(((float)color.R * (float)a) / 255.0f); // byte g = (byte)(((float)color.G * (float)a) / 255.0f); // byte b = (byte)(((float)color.B * (float)a) / 255.0f); // stream.WriteInt32(Color.FromArgb(a, r, g, b).ToArgb()); // } // } //} else if(RResourceManager.IsColoSkipProcess) { // int skipAlpha = RResourceManager.ColoSkipAlpha; // foreach(Color color in palette) { // if(_optionAlpha) { // stream.WriteInt32(color.ToArgb() & 0x00FFFFFF); // } else { // if(color.A < skipAlpha) { // stream.WriteInt32(0); // } else { // stream.WriteInt32(color.ToArgb()); // } // } // } //} else { // foreach(Color color in palette) { // if(_optionAlpha) { // stream.WriteInt32(color.ToArgb() & 0x00FFFFFF); // } else { // stream.WriteInt32(color.ToArgb()); // } // } //} // _logger.Debug(this, "SerializeIndexed", "block_size={0}x{1}, color={2}, alpha={3}", blockWidth, blockHeight, paletteCount, _optionAlpha); // 输出颜色数组 int x = rect.Left; int y = rect.Top; // 透明色索引 int transparentIndex = palette.Length - 1; int size = blockWidth * blockHeight; // 写入数组 int postion = 0; byte[] bytes = null; if (_optionAlpha) { // 写入索引颜色和透明度 bytes = new byte[size * 2]; for (int h = 0; h < blockHeight; h++) { for (int w = 0; w < blockWidth; w++) { Color color = _bitmap.GetPixel(x + w, y + h); int index = colorQuantizer.FindPaletteIndex(Color.FromArgb(255, color)); bytes[postion++] = (byte)index; bytes[postion++] = color.A; } } } else { // 写入带透明的索引颜色 bytes = new byte[size]; for (int h = 0; h < blockHeight; h++) { for (int w = 0; w < blockWidth; w++) { Color color = _bitmap.GetPixel(x + w, y + h); int index = colorQuantizer.FindPaletteIndex(color); bytes[postion++] = (byte)index; } } } stream.WriteBytes(bytes, 0, postion); // 写入数据 output.WriteInt32(stream.Length); output.WriteBytes(stream.Memory, 0, stream.Length); return(true); }