Example #1
0
        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);
        }
Example #2
0
 private static CGColorSpace CreateColorSpace(ColorPalette palette)
 {
     throw new NotImplementedException();
 }
Example #3
0
        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);
        }
Example #4
0
 private void ResetPalette()
 {
     _palette   = _pixelFormat.IsIndexed() ? new ColorPalette(new Color[_pixelFormat.GetColorCount()]) : null;
     _quantizer = null;
 }
Example #5
0
        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
            {
            }
        }