Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > [VC#] Чтение RLE изображения


Автор: MuForum 30.8.2008, 19:59
Доброе время суток.
- Использую 'MVS 2008'.
- Столкнулся со следующей проблемой, мне необходимо отобразить содержимое '.tga' файла в компоненте 'PictureBox'.
- '.tga' файл может хранить данные в 7 видах. Один из видов, это сжатые данные при помощи 'RLE' (Run-Length Encoding) алгоритма.
- Документация об алгоритме сжатия 'RLE': http://ru.wikipedia.org/wiki/RLE;

# Вопрос: Как на C# осуществить преобразование изображения сжатого RLE алгоритмом в 'RAW' формат. (То есть в несжатое)
- Пытался перевести код с C++ на C#, но без успешно, запутался. Опирался на данную статью: http://pmg.org.ru/nehe/nehe33.htm.
- Хотя сам алгоритм на сколько я понял простой, там просто суммируется количество повторяемых символов: '1111223555555522223' -> '412213754213'.

# Вопрос: Суммируются данные также как в примере(каждый символ) или тут суммируется группой(пикслем)?
- Наглядный маленький пример был бы кстате.


P.S. -> Несжатое '*.tga' изображения я сумел разобрать в данной теме: http://forum.vingrad.ru/forum/topic-224545/kw-tga.html;

Автор: MuForum 30.8.2008, 21:50
# for all - Парни, удалось, теперь читает, изображение показывает всё вроде в ажуре, но почему-то размер распакованного изображения не соответствует изображению не запакованного изображения. Где я туплю?


# Заголовок:
Код

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct HEADER_TGA // 18 bytes;
        {
            public byte IDLength;        /* 00h  Size of Image ID field */
            public byte ColorMapType;    /* 01h  Color map type */
            public byte ImageType;       /* 02h  Image type code */
            public ushort CMapStart;       /* 03h  Color map origin */
            public ushort CMapLength;      /* 05h  Color map length */
            public byte CMapDepth;       /* 07h  Depth of color map entries */
            public ushort XOffset;         /* 08h  X origin of image */
            public ushort YOffset;         /* 0Ah  Y origin of image */
            public ushort Width;           /* 0Ch  Width of image */
            public ushort Height;          /* 0Eh  Height of image */
            public byte PixelDepth;      /* 10h  Image pixel size */
            public byte ImageDescriptor; /* 11h  Image descriptor byte */
        }



# Под-программа обработки сжатого '*.tga' файла: (DataType: 10)
Код

        static public Bitmap GetCompressed(MemoryStream ms, HEADER_TGA sgHeader)
        {
            Bitmap bm = null;
            MemoryStream nms = null;
            int Width, Height, bpp, bytesPerPixel;
            // ----
            try
            {
                byte[] bWidth = BitConverter.GetBytes(sgHeader.Width);
                byte[] bHeight = BitConverter.GetBytes(sgHeader.Height);
                // ----
                // Определяем ширину TGA (старший байт * 256 + младший байт);
                Width = (bWidth[1] * 256) + bWidth[0];
                // Определяем высоту TGA (старший байт * 256 + младший байт);
                Height = (bHeight[1] * 256) + bHeight[0];
                // ----
                // Получаем TGA бит/пиксель (16, 24 или 32);
                bpp = sgHeader.PixelDepth;
                // Делим на 8 для получения байт/пиксель;
                bytesPerPixel = bpp / 8;
                // ----
                int pixelcount = Width * Height; // Количество пикселей в изображении;
                int currentpixel = 0;
                nms = new MemoryStream(pixelcount);
                byte[] colorbuffer = new byte[bytesPerPixel];
                byte chunkheader;
                // ----
                do
                {
                    chunkheader = (byte)ms.ReadByte();
                    // ----
                    if (chunkheader < 128) // Если секция является 'RAW' секцией;
                    {
                        chunkheader++; // Добавляем единицу для получения количества RAW пикселей;
                        for (int j = 0; j < chunkheader; j++)
                        {
                            ms.Read(colorbuffer, 0, bytesPerPixel);
                            nms.Write(colorbuffer, 0, bytesPerPixel);
                        }
                        currentpixel += chunkheader;
                    }
                    else // Если это RLE идентификатор;
                    {
                        chunkheader -= 127; // Вычитаем 127 для получения количества повторений;
                        ms.Read(colorbuffer, 0, bytesPerPixel); // Считываем 1 пиксель;
                        for (int j = 0; j < chunkheader; j++) nms.Write(colorbuffer, 0, bytesPerPixel);
                        currentpixel += chunkheader;
                    }
                }
                while (currentpixel < pixelcount);
                nms.Position = 0;
                using(FileStream fs = new FileStream("C:\\tga_com.tga", FileMode.Create))
                {
                    nms.WriteTo(fs);
                }
                // ----
                bm = GetUnCompressed(nms, sgHeader);
            }
            catch (Exception) { bm = null; }
            // ----
            return bm;
        }



# Результаты:
Цитата

Не запакованное: 2,04 КБ (2 092 байт)
Запакованное: 1,41 КБ (1 452 байт)
Распакованное: 2,00 КБ (2 048 байт) - сюда нужно добавить ещё заголовок + 18 байт и того = 2066 байт.
Теряется: 2092 - 2066 = 26 байт. (Куда они делись?); (nms.Length равняется 2066)

P.S. -> IDLength равняется 0.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)