Example #1
0
        public unsafe void Set(Bitmap bitmap, Bitmap bitmapMask, Color transparentColor)
        {
            // We need to rotate the images, but we don't want to mess with the source image, lets create a clone
            Bitmap image = (Bitmap) bitmap.Clone();
            Bitmap mask  = bitmapMask != null ? (Bitmap) bitmapMask.Clone() : null;
            try
            {
                //.NET has a bug flipping in the Y axis for 1bpp images, let do it ourself
                if (image.PixelFormat != PixelFormat.Format1bppIndexed)
                    image.RotateFlip(RotateFlipType.RotateNoneFlipY);
                else
                    Tools.FlipYBitmap(image);

                if (mask != null)
                    Tools.FlipYBitmap(mask);

                if (mask != null && (image.Size != mask.Size || mask.PixelFormat != PixelFormat.Format1bppIndexed))
                    throw new InvalidMultiIconMaskBitmap();

                // Palette
                // Some icons programs like Axialis have program with a reduce palette, so lets create a complete palette instead
                RGBQUAD[] palette = Tools.RGBQUADFromColorArray(image);

                // Bitmap Header
                BITMAPINFOHEADER infoHeader= new BITMAPINFOHEADER();
                infoHeader.biSize           = (uint) sizeof(BITMAPINFOHEADER);
                infoHeader.biWidth          = (uint) image.Width;
                infoHeader.biHeight         = (uint) image.Height * 2;
                infoHeader.biPlanes         = 1;
                infoHeader.biBitCount       = (ushort) Tools.BitsFromPixelFormat(image.PixelFormat);
                infoHeader.biCompression    = IconImageFormat.BMP;
                infoHeader.biXPelsPerMeter  = 0;
                infoHeader.biYPelsPerMeter  = 0;
                infoHeader.biClrUsed        = (uint) palette.Length;
                infoHeader.biClrImportant   = 0;

                // IconImage
                mEncoder.Header  = infoHeader;
                mEncoder.Colors  = palette;

                // XOR Image
                BitmapData bmpData = image.LockBits(new Rectangle(0,0, image.Width, image.Height), ImageLockMode.ReadOnly, image.PixelFormat);
                IntPtr scanColor= bmpData.Scan0;
                mEncoder.XOR = new byte[Math.Abs(bmpData.Stride) * bmpData.Height];
                Marshal.Copy(scanColor, mEncoder.XOR, 0, mEncoder.XOR.Length);
                image.UnlockBits(bmpData);
                infoHeader.biSizeImage = (uint) mEncoder.XOR.Length;

                // AND Image
                if (mask == null)
                {
                    // Lets create the AND Image from the Color Image
                    Bitmap bmpBW = new Bitmap(image.Width, image.Height, PixelFormat.Format1bppIndexed);
                    BitmapData bmpBWData = bmpBW.LockBits(new Rectangle(0,0, image.Width, image.Height), ImageLockMode.ReadWrite, bmpBW.PixelFormat);
                    IntPtr scanBW   = bmpBWData.Scan0;
                    mEncoder.AND = new byte[Math.Abs(bmpBWData.Stride) * bmpBWData.Height];

                    //Let extract the AND image from the XOR image
                    int strideC =Math.Abs(bmpData.Stride);
                    int strideB =Math.Abs(bmpBWData.Stride);
                    int bpp = Tools.BitsFromPixelFormat(image.PixelFormat);
                    int posCY;
                    int posCX;
                    int posBY;
                    int color;
                    Color tColor;
                    RGBQUAD paletteColor;

                    //If the image is 24 bits, then lets make sure alpha channel is 0
                    if (bpp == 24)
                        transparentColor = Color.FromArgb(0, transparentColor.R, transparentColor.G, transparentColor.B);

                    for(int y=0;y<bmpData.Height; y++)
                    {
                        posBY = strideB * y;
                        posCY = strideC * y;
                        for(int x=0;x<bmpData.Width; x++)
                        {
                            switch (bpp)
                            {
                                case 1:
                                    mEncoder.AND[(x >> 3) + posCY] = (byte) mEncoder.XOR[(x >> 3) + posCY];
                                    break;
                                case 4:
                                    color = mEncoder.XOR[(x >> 1) + posCY];
                                    paletteColor = mEncoder.Colors[(x & 1) == 0 ? color >> 4 : color & 0x0F];
                                    if (Tools.CompareRGBQUADToColor(paletteColor , transparentColor))
                                    {
                                        mEncoder.AND[(x >> 3) + posBY] |= (byte) (0x80 >> (x & 7));
                                        mEncoder.XOR[(x >> 1) + posCY] &= (byte) ((x & 1) == 0 ? 0x0F : 0xF0);
                                    }
                                    break;
                                case 8:
                                    color = mEncoder.XOR[x + posCY];
                                    paletteColor = mEncoder.Colors[color];
                                    if (Tools.CompareRGBQUADToColor(paletteColor , transparentColor))
                                    {
                                        mEncoder.AND[(x >> 3) + posBY] |= (byte) (0x80 >> (x & 7));
                                        mEncoder.XOR[x + posCY] = 0;
                                    }
                                    break;
                                case 16:
                                    throw new NotSupportedException("16 bpp images are not supported for Icons");
                                case 24:
                                    posCX = x * 3;
                                    tColor = Color.FromArgb(0, mEncoder.XOR[posCX + posCY + 0],
                                                                mEncoder.XOR[posCX + posCY + 1],
                                                                mEncoder.XOR[posCX + posCY + 2]);
                                    if (tColor == transparentColor)
                                        mEncoder.AND[(x >> 3) + posBY] |= (byte) (0x80 >> (x & 7));
                                    break;
                                case 32:
                                    if (transparentColor == Color.Transparent)
                                    {
                                        if (mEncoder.XOR[(x << 2) + posCY + 3] == 0)
                                            mEncoder.AND[(x >> 3) + posBY] |= (byte) (0x80 >> (x & 7));
                                    }
                                    else
                                    {
                                        if (mEncoder.XOR[(x << 2) + posCY + 0] == transparentColor.B &&
                                            mEncoder.XOR[(x << 2) + posCY + 1] == transparentColor.G &&
                                            mEncoder.XOR[(x << 2) + posCY + 2] == transparentColor.R)
                                        {
                                            mEncoder.AND[(x >> 3) + posBY] |= (byte) (0x80 >> (x & 7));
                                            mEncoder.XOR[(x << 2) + posCY + 0] = 0;
                                            mEncoder.XOR[(x << 2) + posCY + 1] = 0;
                                            mEncoder.XOR[(x << 2) + posCY + 2] = 0;
                                        }
                                        else
                                        {
                                            mEncoder.XOR[(x << 2) + posCY + 3] = 255;
                                        }
                                    }
                                    break;
                            }
                        }
                    }
                    bmpBW.UnlockBits(bmpBWData);
                }
                else
                {
                    // Mask is coming by parameter, so we don't need to create it
                    BitmapData bmpBWData    = mask.LockBits(new Rectangle(0,0, mask.Width, mask.Height), ImageLockMode.ReadOnly, mask.PixelFormat);
                    IntPtr scanBW           = bmpBWData.Scan0;
                    mEncoder.AND          = new byte[Math.Abs(bmpBWData.Stride) * bmpBWData.Height];
                    Marshal.Copy(scanBW, mEncoder.AND, 0, mEncoder.AND.Length);
                    mask.UnlockBits(bmpBWData);
                }
            }
            finally
            {
                if (image != null)
                    image.Dispose();
                if (mask != null)
                    mask.Dispose();
            }
        }
Example #2
0
        public unsafe void Set(Bitmap bitmap, Bitmap bitmapMask, Color transparentColor)
        {
            // We need to rotate the images, but we don't want to mess with the source image, lets create a clone
            Bitmap image = (Bitmap)bitmap.Clone();
            Bitmap mask  = bitmapMask != null ? (Bitmap)bitmapMask.Clone() : null;

            try
            {
                //.NET has a bug flipping in the Y axis for 1bpp images, let do it ourself
                if (image.PixelFormat != PixelFormat.Format1bppIndexed)
                {
                    image.RotateFlip(RotateFlipType.RotateNoneFlipY);
                }
                else
                {
                    Tools.FlipYBitmap(image);
                }

                if (mask != null)
                {
                    Tools.FlipYBitmap(mask);
                }

                if (mask != null && (image.Size != mask.Size || mask.PixelFormat != PixelFormat.Format1bppIndexed))
                {
                    throw new InvalidMultiIconMaskBitmap();
                }

                // Palette
                // Some icons programs like Axialis have program with a reduce palette, so lets create a complete palette instead
                RGBQUAD[] palette = Tools.RGBQUADFromColorArray(image);

                // Bitmap Header
                BITMAPINFOHEADER infoHeader = new BITMAPINFOHEADER();
                infoHeader.biSize          = (uint)sizeof(BITMAPINFOHEADER);
                infoHeader.biWidth         = (uint)image.Width;
                infoHeader.biHeight        = (uint)image.Height * 2;
                infoHeader.biPlanes        = 1;
                infoHeader.biBitCount      = (ushort)Tools.BitsFromPixelFormat(image.PixelFormat);
                infoHeader.biCompression   = IconImageFormat.BMP;
                infoHeader.biXPelsPerMeter = 0;
                infoHeader.biYPelsPerMeter = 0;
                infoHeader.biClrUsed       = (uint)palette.Length;
                infoHeader.biClrImportant  = 0;

                // IconImage
                mEncoder.Header = infoHeader;
                mEncoder.Colors = palette;

                // XOR Image
                BitmapData bmpData   = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, image.PixelFormat);
                IntPtr     scanColor = bmpData.Scan0;
                mEncoder.XOR = new byte[Math.Abs(bmpData.Stride) * bmpData.Height];
                Marshal.Copy(scanColor, mEncoder.XOR, 0, mEncoder.XOR.Length);
                image.UnlockBits(bmpData);
                infoHeader.biSizeImage = (uint)mEncoder.XOR.Length;

                // AND Image
                if (mask == null)
                {
                    // Lets create the AND Image from the Color Image
                    Bitmap     bmpBW     = new Bitmap(image.Width, image.Height, PixelFormat.Format1bppIndexed);
                    BitmapData bmpBWData = bmpBW.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, bmpBW.PixelFormat);
                    IntPtr     scanBW    = bmpBWData.Scan0;
                    mEncoder.AND = new byte[Math.Abs(bmpBWData.Stride) * bmpBWData.Height];

                    //Let extract the AND image from the XOR image
                    int     strideC = Math.Abs(bmpData.Stride);
                    int     strideB = Math.Abs(bmpBWData.Stride);
                    int     bpp     = Tools.BitsFromPixelFormat(image.PixelFormat);
                    int     posCY;
                    int     posCX;
                    int     posBY;
                    int     color;
                    Color   tColor;
                    RGBQUAD paletteColor;

                    //If the image is 24 bits, then lets make sure alpha channel is 0
                    if (bpp == 24)
                    {
                        transparentColor = Color.FromArgb(0, transparentColor.R, transparentColor.G, transparentColor.B);
                    }

                    for (int y = 0; y < bmpData.Height; y++)
                    {
                        posBY = strideB * y;
                        posCY = strideC * y;
                        for (int x = 0; x < bmpData.Width; x++)
                        {
                            switch (bpp)
                            {
                            case 1:
                                mEncoder.AND[(x >> 3) + posCY] = (byte)mEncoder.XOR[(x >> 3) + posCY];
                                break;

                            case 4:
                                color        = mEncoder.XOR[(x >> 1) + posCY];
                                paletteColor = mEncoder.Colors[(x & 1) == 0 ? color >> 4 : color & 0x0F];
                                if (Tools.CompareRGBQUADToColor(paletteColor, transparentColor))
                                {
                                    mEncoder.AND[(x >> 3) + posBY] |= (byte)(0x80 >> (x & 7));
                                    mEncoder.XOR[(x >> 1) + posCY] &= (byte)((x & 1) == 0 ? 0x0F : 0xF0);
                                }
                                break;

                            case 8:
                                color        = mEncoder.XOR[x + posCY];
                                paletteColor = mEncoder.Colors[color];
                                if (Tools.CompareRGBQUADToColor(paletteColor, transparentColor))
                                {
                                    mEncoder.AND[(x >> 3) + posBY] |= (byte)(0x80 >> (x & 7));
                                    mEncoder.XOR[x + posCY]         = 0;
                                }
                                break;

                            case 16:
                                throw new NotSupportedException("16 bpp images are not supported for Icons");

                            case 24:
                                posCX  = x * 3;
                                tColor = Color.FromArgb(0, mEncoder.XOR[posCX + posCY + 0],
                                                        mEncoder.XOR[posCX + posCY + 1],
                                                        mEncoder.XOR[posCX + posCY + 2]);
                                if (tColor == transparentColor)
                                {
                                    mEncoder.AND[(x >> 3) + posBY] |= (byte)(0x80 >> (x & 7));
                                }
                                break;

                            case 32:
                                if (transparentColor == Color.Transparent)
                                {
                                    if (mEncoder.XOR[(x << 2) + posCY + 3] == 0)
                                    {
                                        mEncoder.AND[(x >> 3) + posBY] |= (byte)(0x80 >> (x & 7));
                                    }
                                }
                                else
                                {
                                    if (mEncoder.XOR[(x << 2) + posCY + 0] == transparentColor.B &&
                                        mEncoder.XOR[(x << 2) + posCY + 1] == transparentColor.G &&
                                        mEncoder.XOR[(x << 2) + posCY + 2] == transparentColor.R)
                                    {
                                        mEncoder.AND[(x >> 3) + posBY]    |= (byte)(0x80 >> (x & 7));
                                        mEncoder.XOR[(x << 2) + posCY + 0] = 0;
                                        mEncoder.XOR[(x << 2) + posCY + 1] = 0;
                                        mEncoder.XOR[(x << 2) + posCY + 2] = 0;
                                    }
                                    else
                                    {
                                        mEncoder.XOR[(x << 2) + posCY + 3] = 255;
                                    }
                                }
                                break;
                            }
                        }
                    }
                    bmpBW.UnlockBits(bmpBWData);
                }
                else
                {
                    // Mask is coming by parameter, so we don't need to create it
                    BitmapData bmpBWData = mask.LockBits(new Rectangle(0, 0, mask.Width, mask.Height), ImageLockMode.ReadOnly, mask.PixelFormat);
                    IntPtr     scanBW    = bmpBWData.Scan0;
                    mEncoder.AND = new byte[Math.Abs(bmpBWData.Stride) * bmpBWData.Height];
                    Marshal.Copy(scanBW, mEncoder.AND, 0, mEncoder.AND.Length);
                    mask.UnlockBits(bmpBWData);
                }
            }
            finally
            {
                if (image != null)
                {
                    image.Dispose();
                }
                if (mask != null)
                {
                    mask.Dispose();
                }
            }
        }
Example #3
0
 public BITMAPINFOHEADER(Stream stream)
 {
     this = new BITMAPINFOHEADER();
     Read(stream);
 }
Example #4
0
 public BITMAPINFOHEADER(Stream stream)
 {
     this = new BITMAPINFOHEADER();
     this.Read(stream);
 }