internal Bitmap BuildBitmapOnWin32() { Bitmap bmp; if (imageData == null) { return(new Bitmap(32, 32)); } IconImage ii = (IconImage)imageData[id]; BitmapInfoHeader bih = ii.iconHeader; int biHeight = bih.biHeight / 2; int ncolors = (int)bih.biClrUsed; if ((ncolors == 0) && (bih.biBitCount < 24)) { ncolors = (int)(1 << bih.biBitCount); } switch (bih.biBitCount) { case 1: bmp = new Bitmap(bih.biWidth, biHeight, PixelFormat.Format1bppIndexed); break; case 4: bmp = new Bitmap(bih.biWidth, biHeight, PixelFormat.Format4bppIndexed); break; case 8: bmp = new Bitmap(bih.biWidth, biHeight, PixelFormat.Format8bppIndexed); break; case 24: bmp = new Bitmap(bih.biWidth, biHeight, PixelFormat.Format24bppRgb); break; case 32: bmp = new Bitmap(bih.biWidth, biHeight, PixelFormat.Format32bppArgb); break; default: string msg = string.Format("Unexpected number of bits: {0}", bih.biBitCount); throw new Exception(msg); } if (bih.biBitCount < 24) { ColorPalette pal = bmp.Palette; // Managed palette for (int i = 0; i < ii.iconColors.Length; i++) { pal.Entries[i] = Color.FromArgb((int)ii.iconColors[i] | unchecked ((int)0xff000000)); } bmp.Palette = pal; } int bytesPerLine = (int)((((bih.biWidth * bih.biBitCount) + 31) & ~31) >> 3); BitmapData bits = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, bmp.PixelFormat); for (int y = 0; y < biHeight; y++) { Marshal.Copy(ii.iconXOR, bytesPerLine * y, (IntPtr)(bits.Scan0.ToInt64() + bits.Stride * (biHeight - 1 - y)), bytesPerLine); } bmp.UnlockBits(bits); bmp = new Bitmap(bmp); // This makes a 32bpp image out of an indexed one // Apply the mask to make properly transparent bytesPerLine = (int)((((bih.biWidth) + 31) & ~31) >> 3); for (int y = 0; y < biHeight; y++) { for (int x = 0; x < bih.biWidth / 8; x++) { for (int bit = 7; bit >= 0; bit--) { if (((ii.iconAND[y * bytesPerLine + x] >> bit) & 1) != 0) { bmp.SetPixel(x * 8 + 7 - bit, biHeight - y - 1, Color.Transparent); } } } } return(bmp); }
private static CGColorSpace CreateColorSpace(ColorPalette palette) { throw new NotImplementedException(); }
public static unsafe Bitmap IndexColors(this Bitmap src, ColorPalette palette, PixelFormat format) { int w = src.Width, h = src.Height; int entries = palette.Entries.Length; switch (format) { case PixelFormat.Format4bppIndexed: { entries = Math.Min(entries, 16); break; } case PixelFormat.Format8bppIndexed: { entries = Math.Min(entries, 256); break; } default: { throw new ArgumentException("Pixel format is not an indexed format."); } } Bitmap dst = new Bitmap(w, h, format); dst.Palette = palette; BitmapData sData = src.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); BitmapData dData = dst.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, format); ARGBPixel *sPtr = (ARGBPixel *)sData.Scan0; for (int y = 0; y < h; y++) { byte *dPtr = (byte *)dData.Scan0 + (y * dData.Stride); for (int x = 0; x < w; x++) { ARGBPixel p = *sPtr++; int bestDist = Int32.MaxValue, bestIndex = 0; for (int z = 0; z < entries; z++) { int dist = p.DistanceTo(palette.Entries[z]); if (dist < bestDist) { bestDist = dist; bestIndex = z; } } if (format == PixelFormat.Format4bppIndexed) { byte val = *dPtr; if ((x % 2) == 0) { *dPtr = (byte)((bestIndex << 4) | (val & 0x0F)); } else { *dPtr++ = (byte)((val & 0xF0) | (bestIndex & 0x0F)); } } else { *dPtr++ = (byte)bestIndex; } } } dst.UnlockBits(dData); src.UnlockBits(sData); return(dst); }
private void ResetPalette() { _palette = _pixelFormat.IsIndexed() ? new ColorPalette(new Color[_pixelFormat.GetColorCount()]) : null; _quantizer = null; }
public Bitmap(int width, int height, PixelFormat format) { imageTransform = new CGAffineTransform(1, 0, 0, -1, 0, height); int bitsPerComponent, bytesPerRow; CGColorSpace colorSpace; CGBitmapFlags bitmapInfo; bool premultiplied = false; int bitsPerPixel = 0; pixelFormat = format; // Don't forget to set the Image width and height for size. imageSize.Width = width; imageSize.Height = height; switch (format) { case PixelFormat.Format32bppPArgb: case PixelFormat.DontCare: premultiplied = true; colorSpace = CGColorSpace.CreateDeviceRGB(); bitsPerComponent = 8; bitsPerPixel = 32; bitmapInfo = CGBitmapFlags.PremultipliedLast; break; case PixelFormat.Format32bppArgb: colorSpace = CGColorSpace.CreateDeviceRGB(); bitsPerComponent = 8; bitsPerPixel = 32; bitmapInfo = CGBitmapFlags.PremultipliedLast; break; case PixelFormat.Format32bppRgb: colorSpace = CGColorSpace.CreateDeviceRGB(); bitsPerComponent = 8; bitsPerPixel = 32; bitmapInfo = CGBitmapFlags.NoneSkipLast; break; case PixelFormat.Format24bppRgb: colorSpace = CGColorSpace.CreateDeviceRGB(); bitsPerComponent = 8; bitsPerPixel = 24; bitmapInfo = CGBitmapFlags.None; break; case PixelFormat.Format8bppIndexed: // FIXME: Default palette colorSpace = CGColorSpace.CreateIndexed(CGColorSpace.CreateDeviceRGB(), 255, new byte[3 * 256]); bitsPerComponent = 8; bitsPerPixel = 8; bitmapInfo = CGBitmapFlags.None; palette = new ColorPalette(0, new Color[256]); break; case PixelFormat.Format4bppIndexed: // FIXME: Default palette colorSpace = CGColorSpace.CreateIndexed(CGColorSpace.CreateDeviceRGB(), 15, new byte[3 * 16]); bitsPerComponent = 4; bitsPerPixel = 4; bitmapInfo = CGBitmapFlags.None; palette = new ColorPalette(0, new Color[16]); break; case PixelFormat.Format1bppIndexed: // FIXME: Default palette colorSpace = CGColorSpace.CreateIndexed(CGColorSpace.CreateDeviceRGB(), 1, new byte[3 * 2]); bitsPerComponent = 1; bitsPerPixel = 1; bitmapInfo = CGBitmapFlags.None; palette = new ColorPalette(0, new Color[2] { Color.Black, Color.White }); break; default: throw new Exception("Format not supported: " + format); } bytesPerRow = (int)(((long)width * bitsPerPixel + 7) / 8); int size = bytesPerRow * height; bitmapBlock = Marshal.AllocHGlobal(size); unsafe { byte *b = (byte *)bitmapBlock; for (int i = 0; i < size; i++) { b [i] = 0; } } dataProvider = new CGDataProvider(bitmapBlock, size, true); NativeCGImage = new CGImage(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpace, bitmapInfo, dataProvider, null, false, CGColorRenderingIntent.Default); dpiWidth = dpiHeight = ConversionHelpers.MS_DPI; physicalDimension.Width = width; physicalDimension.Height = height; // The physical size may be off on certain implementations. For instance the dpiWidth and dpiHeight // are read using integers in core graphics but in windows it is a float. // For example: // coregraphics dpiWidth = 24 as integer // windows dpiWidth = 24.999935 as float // this gives a few pixels difference when calculating the physical size. // 256 * 96 / 24 = 1024 // 256 * 96 / 24.999935 = 983.04 // // https://bugzilla.xamarin.com/show_bug.cgi?id=14365 // PR: https://github.com/mono/maccore/pull/57 // physicalSize = new SizeF(physicalDimension.Width, physicalDimension.Height); physicalSize.Width *= ConversionHelpers.MS_DPI / dpiWidth; physicalSize.Height *= ConversionHelpers.MS_DPI / dpiHeight; rawFormat = ImageFormat.MemoryBmp; pixelFormat = format; if (premultiplied) // make compiler happy { } }