public override BitmapDataBase ConvertTo(PixelFormat dstFormat) { if (dstFormat.Format == PixelFormat.Format) { return(Copy()); } else if (dstFormat.IsIndexed) { IQuantization quantization = new WuAlphaColorQuantizer(); if (quantization.StartQuantization(pixels, Convert.ToInt32(Math.Pow(2, dstFormat.BitsPerPixel)))) { var newData = quantization.QuantData; if (dstFormat.Format == PixelFormatEnum.Indexed4Reverse) { var data2data = PixelConverters.GetDataToDataConverter(PixelFormats.Indexed4, PixelFormats.Indexed4Reverse); newData = data2data(newData); } return(new BitmapDataIndexed(Width, Height, dstFormat, newData, quantization.QuantPalette)); } else { throw new Exception($"BitmapData: convert to {dstFormat} error. Quantization don't work."); } } else { var color2data = PixelConverters.GetColorToDataConverter(dstFormat); if (color2data != null) { return(new BitmapData(Width, Height, dstFormat, color2data(pixels))); } else { throw new Exception($"BitmapData: convert to {dstFormat} error. ColorToDataConverter undefined."); } } }
private unsafe void button1_Click(object sender, EventArgs e) { WuAlphaColorQuantizer quant = new WuAlphaColorQuantizer(); Bitmap img = (Bitmap)Image.FromFile("f:/temp/avsham-0.PNG"); Bitmap bmp = quant.Quantize(img, 256); /* Bitmap img = (Bitmap)Image.FromFile("f:/temp/scannen.PNG"); * Bitmap bmp = new Bitmap(img.Width, img.Height, PixelFormat.Format8bppIndexed); * * BitmapData data = img.LockBits( * Rectangle.FromLTRB(0, 0, img.Width, img.Height), * ImageLockMode.ReadOnly, img.PixelFormat); * * BitmapData bmpdata = bmp.LockBits( * Rectangle.FromLTRB(0, 0, bmp.Width, bmp.Height), * ImageLockMode.WriteOnly, bmp.PixelFormat); * * uint[] res = quant.Quantize( * (uint*)data.Scan0.ToPointer(), * 256, img.Width, img.Height, * (byte*)bmpdata.Scan0.ToPointer()); * * ColorPalette pal = bmp.Palette; * for (int i = 0; i < 256; i++) * pal.Entries[i] = Color.FromArgb((int)res[i]); * bmp.Palette = pal; * * img.UnlockBits(data); * bmp.UnlockBits(bmpdata);*/ bmp.Save("f:/temp/avsham-0_quant.png"); img.Dispose(); bmp.Dispose(); }
public UVRT(Bitmap bitmap, PixelFormat pixelFormat, ImageType imageType, int mipLevels, byte[] palette = null) { if (!IsPow2(bitmap.Width) || !IsPow2(bitmap.Height)) { throw new Exception("Width and height must be powers of two."); } if (imageType.IsIndexed()) { byte indexBits = imageType.GetIndexBits(); byte[] indices; Color[] colorPalette; if (palette != null) { indices = new byte[bitmap.Width * bitmap.Height]; colorPalette = BitmapUtil.PaletteToColors(palette, pixelFormat); for (int y = 0; y < bitmap.Height; y++) { for (int x = 0; x < bitmap.Width; x++) { int index = BitmapUtil.GetClosestColorIndex(bitmap.GetPixel(x, y), colorPalette, pixelFormat != PixelFormat.RGB565); if (index == -1) { throw new Exception("Could not find a palette entry for pixel (" + x + ", " + y + ")."); } indices[y * bitmap.Width + x] = (byte)(index & 0xFF); } } } else { BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); byte[] argbData = new byte[data.Stride * bitmap.Height]; Marshal.Copy(data.Scan0, argbData, 0, argbData.Length); bitmap.UnlockBits(data); WuAlphaColorQuantizer quantizer = new WuAlphaColorQuantizer(); ColorQuantizerResult result = quantizer.Quantize(argbData, 1 << indexBits); indices = result.Bytes; colorPalette = new Color[1 << indexBits]; for (int i = 0; i < result.Palette.Length / 4; i++) { colorPalette[i] = Color.FromArgb(result.Palette[i * 4 + 3], result.Palette[i * 4 + 2], result.Palette[i * 4 + 1], result.Palette[i * 4 + 0]); } } byte[] converted = new byte[bitmap.Width * bitmap.Height * indexBits / 8]; for (int y = 0; y < bitmap.Height; y++) { for (int x = 0; x < bitmap.Width; x++) { int dataIndex = y * bitmap.Width + x; int index = indices[dataIndex]; if (indexBits == 4) { int shift = (dataIndex & 1) * 4; converted[dataIndex / 2] = (byte)((converted[dataIndex / 2] & ~(0xF << shift)) | ((index & 0xF) << shift)); } else { converted[dataIndex] = (byte)(index & 0xFF); } } } this.Data = BitmapUtil.Swizzle(converted, (bitmap.Width * imageType.GetIndexBits()) / 8, bitmap.Height, (bitmap.Width * imageType.GetIndexBits()) / 8, bitmap.Height); this.Palette = BitmapUtil.ColorsToPalette(colorPalette, pixelFormat); } else { if (pixelFormat == PixelFormat.DXT1A || pixelFormat == PixelFormat.DXT1A_EXT) { this.Data = BitmapUtil.CompressDxt1(bitmap.Width, bitmap.Height, pixelFormat == PixelFormat.DXT1A_EXT, bitmap); } else { int pixelSize = pixelFormat.GetSize(); byte[] converted = new byte[bitmap.Width * bitmap.Height * pixelSize]; for (int y = 0; y < bitmap.Height; y++) { for (int x = 0; x < bitmap.Width; x++) { int pixel = pixelFormat.FromColor(bitmap.GetPixel(x, y)); for (int j = 0; j < pixelSize; j++) { converted[(y * bitmap.Width + x) * pixelSize + j] = (byte)((pixel >> (j * 8)) & 0xFF); } } } this.Data = BitmapUtil.Swizzle(converted, bitmap.Width * pixelSize, bitmap.Height, bitmap.Width * pixelSize, bitmap.Height); } this.Palette = new byte[0]; } this.Format = pixelFormat; this.Type = imageType; this.Width = (ushort)bitmap.Width; this.Height = (ushort)bitmap.Height; this.MipLevels = mipLevels; }