Пример #1
0
        static ColorPalette getPalette(byte[] palette)
        {
            List <byte> paletteFile = new List <byte>();

            paletteFile.AddRange(BMP.CreateBmpHeader
                                 (
                                     (UInt32)4,
                                     (UInt32)4,
                                     (UInt32)1,
                                     (UInt16)8,
                                     (UInt32)palette.Length
                                 ));
            paletteFile.AddRange(palette);
            paletteFile.AddRange(new byte[4]);
            Bitmap bmPalette;

            using (MemoryStream argbStream = new MemoryStream(paletteFile.ToArray()))
                try
                {
                    bmPalette = new Bitmap(argbStream);
                }
                catch { return(null); }

            return(bmPalette.Palette);
        }
Пример #2
0
        public static ExtendedBitmap GetBitmap(StciData RGBData)
        {
            byte[] argbFile = convert16ARGBTo32ARGB(RGBData);

            List <byte> bmpFile = new List <byte>();

            bmpFile.AddRange(BMP.CreateBmpHeader
                             (
                                 (UInt32)argbFile.Length,
                                 (UInt32)RGBData.Width,
                                 (UInt32)RGBData.Height,
                                 (UInt16)32,
                                 (UInt32)0
                             ));
            bmpFile.AddRange(argbFile);

            using (MemoryStream argbStream = new MemoryStream(bmpFile.ToArray()))
            {
                Bitmap bm;
                try
                {
                    bm = new Bitmap(argbStream);
                }
                catch
                {
                    bm = new Bitmap(RGBData.Width, RGBData.Height);
                }
                bm.RotateFlip(RotateFlipType.Rotate180FlipX);
                return(new ExtendedBitmap(bm, RGBData._RGB));                //, (UInt16)RGBData.Height, (UInt16)RGBData.Width);
            }
        }
Пример #3
0
        public static ColorPalette MakeTransparentPalette(ColorPalette palette, Color bC)
        {
            List <byte> paletteFile = new List <byte>();

            paletteFile.AddRange(BMP.CreateBmpHeader
                                 (
                                     (UInt32)4,
                                     (UInt32)4,
                                     (UInt32)1,
                                     (UInt16)8,
                                     (UInt32)(palette.Entries.Length * 4)
                                 ));
            paletteFile.AddRange(new byte[] { bC.B, bC.G, bC.R, bC.A });
            for (int i = 1; i < palette.Entries.Length; i++)
            {
                Color c = palette.Entries[i];
                paletteFile.AddRange(new byte[] { c.B, c.G, c.R, c.A });
            }
            paletteFile.AddRange(new byte[4]);
            Bitmap bmPalette;

            using (MemoryStream argbStream = new MemoryStream(paletteFile.ToArray()))
                try
                {
                    bmPalette = new Bitmap(argbStream);
                }
                catch { return(null); }

            return(bmPalette.Palette);
        }
Пример #4
0
        // Анимированный GIF разбиавается покадрово на неанимированные, каждый из которых преобразуется в ExtendedBitmap.
        public static List <ExtendedBitmap> ConvertGifToBitmaps
            (string fileName, int foreshrteningNum, out bool containsLocalPalette)
        {
            List <ExtendedBitmap> result = new List <ExtendedBitmap>();

            //bool itIsStiEditFile = false;
            containsLocalPalette = false;
            Bitmap _prevImage = null;

            using (BinaryReader br = new BinaryReader(new FileStream(fileName, FileMode.Open)))
            {
                while (br.BaseStream.Position < br.BaseStream.Length)
                {
                    List <byte> header      = new List <byte>();
                    byte[]      _startBytes = br.ReadBytes(10);
                    header.AddRange(_startBytes);                                 //Заголовок: GIF 89a,
                    UInt16 _canvasWidth  = BitConverter.ToUInt16(_startBytes, 6); // ширина экрана,
                    UInt16 _canvasHeight = BitConverter.ToUInt16(_startBytes, 8); // высота экрана.

                    byte flags           = br.ReadByte(); header.Add(flags);
                    bool isGlobalPalette = flags > 127;
                    header.AddRange(br.ReadBytes(2));                     // Цвет фона, форма пикселя.
                    if (isGlobalPalette)
                    {
                        int paletteDepth  = flags % 8 + 1;
                        int paletteLength = (Int32)Math.Pow(2, paletteDepth) * 3;
                        header.AddRange(br.ReadBytes(paletteLength));
                    }
                    else
                    {
                        containsLocalPalette = true;
                    }

                    byte  separator  = br.ReadByte();
                    int   imageCount = 0;
                    Int16 shiftX     = 0;
                    Int16 shiftY     = 0;
                    bool  shiftsRead = false;
                    while (!(separator == Convert.ToByte(';')))
                    {
                        List <byte> image   = new List <byte>(header);
                        byte[]      appData = new byte[16];
                        byte        _transparentColorIndex = 0;
                        byte        _imageBehaviorFlags    = 0;
                        while (!(separator == Convert.ToByte(',')))
                        {
                            // Выкидываем расширения
                            if (separator == Convert.ToByte('!'))
                            {
                                byte exCode   = br.ReadByte();
                                byte exLength = br.ReadByte();
                                while (exLength != 0)
                                {
                                    if (exCode == 0xFF)
                                    {
                                        if (new String(br.ReadChars(8)) == "STI_EDIT")
                                        {
                                            // itIsStiEditFile = true;
                                            br.ReadBytes(exLength - 8);
                                            if (!shiftsRead)
                                            {
                                                br.ReadByte();
                                                shiftX     = br.ReadInt16();
                                                shiftY     = br.ReadInt16();
                                                shiftsRead = true;
                                            }
                                            else
                                            {
                                                appData = br.ReadBytes(br.ReadByte());
                                            }
                                            exLength = br.ReadByte();
                                        }
                                        else
                                        {
                                            br.ReadBytes(exLength - 8);
                                            exLength = br.ReadByte();
                                            exCode   = 0;
                                        }
                                    }
                                    else if (exCode == 0xF9)
                                    {
                                        // если третий бит = 1, предудущий кадр копируется в последующий
                                        _imageBehaviorFlags = br.ReadByte();
                                        br.ReadByte(); // Время задержки в мс. В формате STCI не используется.
                                        _transparentColorIndex = br.ReadByte();
                                        br.ReadByte(); // Идентификатор окончания блока.
                                        exLength = br.ReadByte();
                                    }
                                    else
                                    {
                                        br.ReadBytes(exLength);
                                        exLength = br.ReadByte();
                                    }
                                }
                            }
                            separator = br.ReadByte();
                        }
                        image.Add(separator);
                        // Заголовок картинки.

                        Int16 offsetX = BitConverter.ToInt16(br.ReadBytes(2), 0);
                        Int16 offsetY = BitConverter.ToInt16(br.ReadBytes(2), 0);

                        image.AddRange(new byte[4]);
                        byte[] width  = br.ReadBytes(2); image.AddRange(width);
                        byte[] heigth = br.ReadBytes(2); image.AddRange(heigth);
                        image[6] = width[0]; image[7] = width[1];
                        image[8] = heigth[0]; image[9] = heigth[1];

                        flags = br.ReadByte();                         // флаги

                        image.Add(flags);
                        if (flags > 127)
                        {
                            containsLocalPalette = true;
                            int paletteDepth  = flags % 8 + 1;
                            int paletteLength = (Int32)Math.Pow(2, paletteDepth) * 3;
                            image.AddRange(br.ReadBytes(paletteLength));
                        }
                        image.Add(br.ReadByte());                         // кол-во цветов
                        // Читаем картинку
                        byte blockLength = br.ReadByte();

                        while (blockLength != 0)
                        {
                            image.Add(blockLength);
                            image.AddRange(br.ReadBytes(blockLength));
                            blockLength = br.ReadByte();
                        }
                        image.Add(blockLength);
                        image.Add(Convert.ToByte(';'));
                        imageCount++;
                        Bitmap bm = new Bitmap(new MemoryStream(image.ToArray()));

                        // draw next image above previouse
                        if ((_imageBehaviorFlags >> 2) % 2 == 1)
                        {
                            if (_prevImage != null)
                            {
                                Bitmap _argbBm = BMP.ConvertIndexedToArgb32(bm);

                                Graphics _gr = Graphics.FromImage(_prevImage);
                                _gr.DrawImage(_argbBm, offsetX, offsetY);

                                bm      = BMP.Convert32argbToIndexed(_prevImage, bm.Palette);
                                offsetX = (short)-shiftX;
                                offsetY = (short)-shiftY;
                            }
                            else
                            {
                                _prevImage = BMP.ConvertIndexedToArgb32(bm);
                            }
                        }
                        else
                        {
                            offsetX -= shiftX;
                            offsetY -= shiftY;
                        }

                        ExtendedBitmap exBm = new ExtendedBitmap(bm, offsetX, offsetY);
                        exBm.ApplicationData       = appData;
                        exBm.TransparentColorIndex = _transparentColorIndex;

                        result.Add(exBm);
                        separator = br.ReadByte();
                    }
                }
            }
            if (foreshrteningNum != 0)
            {
                int length = result.Count / foreshrteningNum;
                if (length != 0)
                {
                    for (int i = 0; i < result.Count; i += length)
                    {
                        result[i].ApplicationData =
                            new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, (byte)length, 2, 0, 0, 0, 0, 0, 0 };
                        for (int j = i + 1; j < length; j++)
                        {
                            result[j].ApplicationData = new byte[16];
                        }
                    }
                }
            }
            return(result);
        }
Пример #5
0
 public static byte[] CreateBmpHeader(
     Int32 imageLength, Int32 width, Int32 height, Int32 bitPerPixel, Int32 paletteLength)
 {
     return(BMP.CreateBmpHeader(
                (UInt32)imageLength, (UInt32)width, (UInt32)height, (UInt16)bitPerPixel, (UInt32)paletteLength));
 }
Пример #6
0
        public static Bitmap Convert32argbToIndexed(Bitmap argbFile, ColorPalette palette)
        {
            // if palette = null, create palette.
            // if file contains more than 256 different colors throw excepiton
            int _headerSize    = 54;
            int _colorNum      = 256;
            int _paletteSize   = 256 * 4;
            int _width         = argbFile.Width;
            int _height        = argbFile.Height;
            int _imageDataSize = _width * _height;

            byte[] _indexedBmData = new byte[_headerSize + _paletteSize + _imageDataSize];
            bool   _isNewPalette  = false;

            if (palette == null)
            {
                byte[] _paletteData = new byte[_paletteSize];
                palette       = BMP.getPalette(_paletteData);
                _isNewPalette = true;
            }

            int _paletteIndex = 0;

            byte[] _argbBmData = new byte[_headerSize + _imageDataSize * 4];

            Bitmap _indexedBm = null;

            using (MemoryStream _argbStream = new MemoryStream(_argbBmData))
            {
                argbFile.Save(_argbStream, ImageFormat.Bmp);
                using (MemoryStream _indexedStream = new MemoryStream(_indexedBmData))
                {
                    byte[] _header = BMP.CreateBmpHeader(
                        _imageDataSize, argbFile.Width, argbFile.Height, 8, _colorNum);
                    _indexedStream.Write(_header, 0, _headerSize);

                    _indexedStream.Seek(_paletteSize, SeekOrigin.Current);
                    _argbStream.Seek(_headerSize, SeekOrigin.Begin);

                    for (int i = 0; i < _height; i++)
                    {
                        for (int j = 0; j < _width; j++)
                        {
                            // argb data is reversed
                            // TODO GetPixel works very slowly. Use stream instead.
                            //Color _c1 = argbFile.GetPixel(_width - j - 1, _height - i - 1);
                            int   _b = _argbStream.ReadByte();
                            int   _g = _argbStream.ReadByte();
                            int   _r = _argbStream.ReadByte();
                            int   _a = _argbStream.ReadByte();
                            Color _c = Color.FromArgb(_a, _r, _g, _b);

                            int _ci = Array.IndexOf(palette.Entries, _c);
                            if (_ci >= 0)
                            {
                                _indexedStream.WriteByte((byte)_ci);
                            }
                            else
                            {
                                if (_isNewPalette)
                                {
                                    if (_paletteIndex < _colorNum)
                                    {
                                        palette.Entries[_paletteIndex] = _c;
                                        _paletteIndex++;
                                    }
                                    else
                                    {
                                        string _msg = String.Format(
                                            "There are more than {0} colors in input file.", _colorNum);
                                        throw new ArgumentException(_msg, "argbFile");
                                    }
                                }
                                else
                                {
                                    string _msg = String.Format(
                                        "Color R={0} G={1} B={2} is not found in palette.", _c.R, _c.G, _c.B);
                                    throw new ArgumentException(_msg, "palette");
                                }
                            }
                        }
                    }

                    _indexedBm         = new Bitmap(_indexedStream);
                    _indexedBm.Palette = palette;
                }
            }

            return(_indexedBm);
        }
Пример #7
0
        static List <ExtendedBitmap> ConvertEtrleDataToBitmaps
            (UInt16 startIndex, UInt16 length, ETRLEData data)
        {
            byte[] palette = data.palette;
            List <ExtendedBitmap> bitmaps = new List <ExtendedBitmap>();

            for (int objIndex = startIndex; objIndex < startIndex + length; objIndex++)
            {
                if (objIndex >= data.ETRLEObjects.Length)
                {
                    return(bitmaps);
                }

                ETRLEObject obj = data.ETRLEObjects[objIndex];

                byte[] file = new byte[obj.uiDataLength];
                Array.Copy(data.imageData, obj.uiDataOffset, file, 0, obj.uiDataLength);
                Int32 remainder = (4 - obj.usWidth % 4) % 4;

                List <byte> argbFile = new List <byte>();

                using (BinaryReader br = new BinaryReader(new MemoryStream(file)))
                {
                    while (br.BaseStream.Position < br.BaseStream.Length)
                    {
                        Int32 firstSectionByte = br.ReadByte();
                        if (firstSectionByte == 0)
                        {
                            for (int i = 0; i < remainder; i++)
                            {
                                argbFile.Add(0);
                            }
                        }
                        else if (firstSectionByte > 127)
                        {
                            for (int j = 0; j < firstSectionByte - 128; j++)
                            {
                                argbFile.Add(0);
                            }
                        }
                        else
                        {
                            for (int j = 0; j < firstSectionByte; j++)
                            {
                                byte index = br.ReadByte();
                                argbFile.Add(index);
                            }
                        }
                    }
                }
                List <byte> bmpFile = new List <byte>();
                bmpFile.AddRange(BMP.CreateBmpHeader
                                 (
                                     (UInt32)argbFile.Count,
                                     (UInt32)(obj.usWidth),
                                     (UInt32)obj.usHeight,
                                     (UInt16)8,
                                     (UInt32)palette.Length
                                 ));
                bmpFile.AddRange(palette);
                bmpFile.AddRange(argbFile);

                byte[] bFile = bmpFile.ToArray();
                using (MemoryStream argbStream = new MemoryStream(bFile))
                {
                    Bitmap bm;
                    try
                    {
                        bm = new Bitmap(argbStream);
                    }
                    catch
                    {
                        bm = new Bitmap(obj.usWidth, obj.usHeight);
                    }
                    bm.RotateFlip(RotateFlipType.RotateNoneFlipY);
                    ExtendedBitmap exBm = new ExtendedBitmap(bm, obj.sOffsetX, obj.sOffsetY);
                    if (data.pAppData != null)
                    {
                        exBm.ApplicationData = new byte[16];
                        Array.Copy(data.pAppData, objIndex * 16, exBm.ApplicationData, 0, 16);
                    }
                    bitmaps.Add(exBm);
                }
            }
            return(bitmaps);
        }