public virtual ExtendedBitmap Clone() { ExtendedBitmap newExBm = new ExtendedBitmap(this); newExBm.TransparentColorIndex = this.TransparentColorIndex; return(newExBm); }
//public static void ConvertBitmapToRGBData(ExtendedBitmap exBm, string fileName) //{ // UInt32 flags = 4; // using (BinaryWriter bw = // new BinaryWriter(new FileStream(fileName, FileMode.Create, FileAccess.Write))) // { // bw.Write(Convert.ToByte('S')); // bw.Write(Convert.ToByte('T')); // bw.Write(Convert.ToByte('C')); // bw.Write(Convert.ToByte('I')); // bw.Write((UInt32)(exBm.Bm.Height * exBm.Bm.Width * 2)); // bw.Write((UInt32)(exBm.Bm.Height * exBm.Bm.Width * 2)); // bw.Write((UInt32)0); // bw.Write(flags); // bw.Write((UInt16)exBm.Bm.Height); // bw.Write((UInt16)exBm.Bm.Width); // // // bw.Write((UInt32)exBm.RgbData.uiRedMask); // bw.Write((UInt32)exBm.RgbData.uiGreenMask); // bw.Write((UInt32)exBm.RgbData.uiBlueMask); // bw.Write((UInt32)exBm.RgbData.uiAlphaMask); // bw.Write((byte)exBm.RgbData.ubRedDepth); // bw.Write((byte)exBm.RgbData.ubGreenDepth); // bw.Write((byte)exBm.RgbData.ubBlueDepth); // bw.Write((byte)exBm.RgbData.ubAlphaDepth); // // // bw.Write((byte)16); // bw.Write(new byte[3]); // bw.Write((UInt16)0); // bw.Write(new byte[14]); // Bitmap bm = (Bitmap)exBm.Bm.Clone(); // int colorDepth = 4; // if (bm.PixelFormat == PixelFormat.Format24bppRgb) // colorDepth = 3; // Int32 height = exBm.Bm.Height; // Int32 width = exBm.Bm.Width; // Int32 remainder = (4 - width % 4) % 4; // byte[] bmFile = new byte[(width + remainder) * height * colorDepth + 54]; // bm.RotateFlip(RotateFlipType.RotateNoneFlipY); // using (MemoryStream ms = new MemoryStream(bmFile)) // { // bm.Save(ms, ImageFormat.Bmp); // } // int columnNum = 0; // for (int i = 54; i < bmFile.Length; i += colorDepth) // { // if (columnNum == width) // { // columnNum = 0; // i += (remainder * colorDepth); // continue; // } // else // columnNum++; // int alpha = 0; // if (colorDepth == 4) // alpha = ((UInt16)bmFile[i + 3]) << 8; // int red = ((UInt16)bmFile[i + 2]) << (8 - exBm.RgbData.ubAlphaDepth); // int green = ((UInt16)bmFile[i + 1] << (8 - exBm.RgbData.ubRedDepth - exBm.RgbData.ubAlphaDepth)); // int blue = ((UInt16)bmFile[i] >> (8 - exBm.RgbData.ubBlueDepth)); // UInt16 color = (UInt16)(alpha | red | green | blue); // bw.Write(color); // } // } //} #endregion // Функция из версии 1.0.0.3 (востановлена рефлектором) public static void ConvertBitmapToRGBData(ExtendedBitmap exBm, string fileName) { uint num = 4; using (BinaryWriter writer = new BinaryWriter(new FileStream(fileName, FileMode.Create, FileAccess.Write))) { writer.Write(Convert.ToByte('S')); writer.Write(Convert.ToByte('T')); writer.Write(Convert.ToByte('C')); writer.Write(Convert.ToByte('I')); writer.Write((UInt32)((exBm.Bm.Height * exBm.Bm.Width) * 2)); writer.Write((UInt32)((exBm.Bm.Height * exBm.Bm.Width) * 2)); writer.Write((UInt32)0); writer.Write(num); writer.Write((UInt16)exBm.Bm.Height); writer.Write((UInt16)exBm.Bm.Width); writer.Write(exBm.RgbData.uiRedMask); writer.Write(exBm.RgbData.uiGreenMask); writer.Write(exBm.RgbData.uiBlueMask); writer.Write(exBm.RgbData.uiAlphaMask); writer.Write(exBm.RgbData.ubRedDepth); writer.Write(exBm.RgbData.ubGreenDepth); writer.Write(exBm.RgbData.ubBlueDepth); writer.Write(exBm.RgbData.ubAlphaDepth); writer.Write((byte)0x10); writer.Write(new byte[3]); writer.Write((UInt16)0); writer.Write(new byte[14]); Bitmap bitmap = (Bitmap)exBm.Bm.Clone(); int num2 = 4; if (bitmap.PixelFormat == PixelFormat.Format24bppRgb) { num2 = 3; } byte[] buffer = new byte[((exBm.Bm.Width * exBm.Bm.Height) * num2) + 0x36]; bitmap.RotateFlip(RotateFlipType.Rotate180FlipX); using (MemoryStream stream = new MemoryStream(buffer)) { bitmap.Save(stream, ImageFormat.Bmp); } RGB rgbData = exBm.RgbData; for (int i = 0x36; i < buffer.Length; i += num2) { int alpha = 0; if (num2 == 4) { alpha = buffer[i + 3] << 8; } int red = buffer[i + 2] << (8 - rgbData.ubAlphaDepth); int green = buffer[i + 1] << ((8 - rgbData.ubRedDepth) - rgbData.ubAlphaDepth); int blue = buffer[i] >> (8 - rgbData.ubBlueDepth); ushort num8 = (UInt16)(alpha & rgbData.uiAlphaMask | red & rgbData.uiRedMask | green & rgbData.uiGreenMask | blue & rgbData.uiBlueMask); writer.Write(num8); } } }
private ExtendedBitmap(ExtendedBitmap old) { this.Bm = (Bitmap)old.Bm.Clone(); this.OffsetX = old.OffsetX; this.OffsetY = old.OffsetY; this.id = old.Id; this.ApplicationData = old.ApplicationData; this.RgbData = old.RgbData; //this.Height = old.Height; //this.Width = old.Width; }
// Анимированный 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); }
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); }