Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [VC#] Конвертация/Расконвертация .tga файлов, Как преобразовать .tga файл к Image клас 
V
    Опции темы
MuForum
  Дата 15.8.2008, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



Доброе время суток!
- Столкнулся со следующей проблемой, мне необходимо показать содержимое '*.tga' файла в компоненте 'PictureBox'.
- Поискав информацию в google.com, я понял, что '.tga' данные могут храниться в двух форматах: 'Запакованные/Не запакованные'.
- Насколько я понял, так отличить в каком формате хранятся данные можно по 3-ему байту, который в свою очередь может принимать 9 вариантов.


# Задача: Отобразить содержимое '*.tga' файла в компоненте 'PictureBox'. (Класс Image)
# Спецификация формата: Wiki, FileFormat.Info, TGA format specification, Описание формата TGA, http://www.truevision.com/;


Это сообщение отредактировал(а) MuForum - 18.8.2008, 11:21


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
MuForum
Дата 15.8.2008, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



# for all - Сделал, но подпрограмма не работает. Вылетает исключение: 'Недопустимый параметр.'

Код

        static public Image GetFromTGA(string FilePath)
        {
            Image img = null;
            FileStream fs = null;
            MemoryStream ms = null;
            // ----
            try
            {
                fs = new FileStream(FilePath, FileMode.Open);
                ms = new MemoryStream();
                // ----
                byte[] buffer = new byte[((int)(fs.Length - 1L)) + 1];
                // ----
                fs.Read(buffer, 0, buffer.Length);
                ms.Write(buffer, 18, buffer.Length - 18);
                // ----
                img = Image.FromStream(ms);
            }
            catch (Exception) { img = null;}
            finally
            {
                if (fs != null) fs.Close();
                if (ms != null) ms.Close();
            }
            // ----
            return img;
        }



P.S. -> Где косяк? В каком месте нужно руки себе отрубить? =)

Это сообщение отредактировал(а) MuForum - 15.8.2008, 15:44


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
Wanderer2019
Дата 15.8.2008, 16:29 (ссылка)    | (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 937
Регистрация: 3.12.2004
Где: Санкт-Петербург/П рага

Репутация: 7
Всего: 17



MuForum, мне кажется .NET не поддерживает тга по умолчанию и необходимо пользоваться какими нибудь сторонними библиотеками или например той же DirectX.
PM ICQ MSN   Вверх
MuForum
Дата 16.8.2008, 14:04 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



Цитата(Wanderer2019 @ 15.8.2008,  16:29)

MuForum, мне кажется .NET не поддерживает тга по умолчанию и необходимо пользоваться какими нибудь сторонними библиотеками или например той же DirectX.

А мне кажется, что ты ошибаешься, так как я видел программы написаные на Dot .NET, которые работают с '*.tga' файлами.
- Например программа 'Paint.NET', и таких не мало...
- Если есть голова и руки, то всё можно сделать.

P.S. -> MSDN: Class PictureBox;

Это сообщение отредактировал(а) MuForum - 17.8.2008, 17:45


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
MuForum
Дата 17.8.2008, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



# for all - Парни, ну ёмаё, помогите хоть советом...
- Я сделал чтение не запакованного '*.tga' файла. (То есть, у которого 3 байт равен 2)

Код

       static public Image GetFromTGA(string FilePath) // Not completed;
        {
            Image img = null;
            FileStream fs = null;
            MemoryStream ms = null;
            int Width, Height, imageSize, bpp, bytesPerPixel;
            byte[] header = new byte[18]; // header
            // ----
            try
            {
                fs = new FileStream(FilePath, FileMode.Open);
                fs.Read(header, 0, 18); // Маркер сдвинут на 18 байтов, так как произошло чтение;
                ms = new MemoryStream();
                // ----
                // Определяем ширину TGA (старший байт * 256 + младший байт);
                Width = (header[13] * 256) + header[12];
                // Определяем высоту TGA (старший байт * 256 + младший байт);
                Height = (header[15] * 256) + header[14];
                // ----
                // Получаем TGA бит/пиксель (24 or 32);
                bpp = header[16];
                // Делим на 8 для получения байт/пиксель;
                bytesPerPixel = bpp / 8;
                // Подсчитываем размер памяти для данных TGA;
                imageSize = Width * Height * bytesPerPixel;
                // ----
                byte temp;
                byte[] buffer = new byte[imageSize];
                fs.Read(buffer, 0, imageSize);
                // ----
                // Цикл по данным, описывающим изображение;
                for (int i = 0; i < imageSize; i += bytesPerPixel)
                {
                    // Временно сохраняем значение imageData[i];
                    temp = buffer[i];
                    // Устанавливаем 1й байт в значение 3го байта;
                    buffer[i] = buffer[i + 2];
                    // Устанавливаем 3й байт в значение, хранящееся в temp (значение 1го байта);
                    buffer[i + 2] = temp;
                }
                // ----
                ms.Write(buffer, 0, imageSize);
                img = Image.FromStream(ms);
            }
            catch (Exception ex) { img = null; MessageBox.Show(ex.Source + " : " + ex.Message); }
            finally
            {
                if (fs != null) fs.Close();
                if (ms != null) ms.Close();
            }
            // ----
            return img;
        }


- Всё вроде отрабатывает как надо, до момента записи изображения в класс 'Image', то есть вот на этой строчке уходит в исключение:
Код

img = Image.FromStream(ms);

Exception: System.Drawing : Недопустимый параметр.

- Что я не правильно делаю?


P.S. -> Я прикрепил архив, в котором 4 не запакованных '*.tga' файла.

Это сообщение отредактировал(а) MuForum - 17.8.2008, 17:47

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  img_tga_unc.rar 23,99 Kb


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
MuForum
  Дата 18.8.2008, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



# for all - Парни, и у меня получилось сделать загрузку '*.tga' файла я ппц рад, то теперь осталось решить проблему со флипом.
- на Wiki Написано следующее:
Цитата(Wiki)

* Описатель изображения — 1 байт

Биты 3-0 этого поля определяют количество атрибутивных бит на пиксель. Биты 5 и 4 определяют порядок передачи пиксельных данных из файла на экран. Бит 4 устанавливается для порядка «слева направо», бит 5 — для порядка «сверху вниз». Биты 7 и 6 в целях совместимости должны быть установлены в 0.


# Вопрос: Как проверить эти биты?
Код

bool LeftToRight = ((header[17] & (1 << 4)) == 0) ? false : true;
bool TopToBottom = ((header[17] & (1 << 5)) == 0) ? false : true;

- Так не хочет =(


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
Partizan
Дата 18.8.2008, 10:58 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 18
Всего: 67



MuForum, ну возможно в вики биты считают слева направо, поэтому стоит попробовать так:

Код

bool LeftToRight = ((header[17] & (1 << (8-4))) == 0) ? false : true;
bool TopToBottom = ((header[17] & (1 << (8-5))) == 0) ? false : true;


8-4 и 8-5 можно заменить на 4 и 3 соответственно )

для ясности просто привёл)


--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
MuForum
Дата 18.8.2008, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



# for all - Парни, немного помучившись, вот получилась функция для отображения не запакованного '*.tga' файла.

Код

        static public Image GetFromTGA(string FilePath) // Only for UnCompressed(RGB); (DataTypeCode == 2)
        {
            Bitmap bm = null;
            FileStream fs = null;
            int Width, Height, bpp, bytesPerPixel, stride;
            byte[] header = new byte[18]; // header
            // ----
            try
            {
                fs = new FileStream(FilePath, FileMode.Open);
                fs.Read(header, 0, 18); // Маркер сдвинут на 18 байтов, так как произошло чтение;
                // ----
                // Определяем ширину TGA (старший байт * 256 + младший байт);
                Width = (header[13] * 256) + header[12];
                // Определяем высоту TGA (старший байт * 256 + младший байт);
                Height = (header[15] * 256) + header[14];
                // ----
                // Получаем TGA бит/пиксель (16, 24 или 32);
                bpp = header[16];
                // Делим на 8 для получения байт/пиксель;
                bytesPerPixel = bpp / 8;
                // Вычисляем количество байт на строке;
                stride = Width * bytesPerPixel;
                // ----
                if (bpp != 16 && bpp != 24 && bpp != 32) return null;
                // ----
                int x = 0;
                byte temp;
                bool RightToLeft = ((header[17] & (1 << (8 - 4))) == 0) ? false : true;
                bool BottomToTop = ((header[17] & (1 << (8 - 5))) == 0) ? false : true;
                byte[] line = new byte[stride];
                bm = new Bitmap(Width, Height);
                // ----
                if (!RightToLeft) //Вывод изображения слева на право;
                {
                    if (!BottomToTop) // Вывод изобрадения сверху вниз;
                    {
                        for (int y = 0; y < Height; y++) // проход по всем строкам;
                        {
                            fs.Read(line, 0, stride);
                            x = 0;
                            for (int pt = 0; pt < stride; pt += bytesPerPixel) // Проход по строке;
                            {
                                temp = line[pt];
                                line[pt] = line[pt + 2];
                                line[pt + 2] = temp;
                                bm.SetPixel(x, y, (bpp == 32) ? Color.FromArgb(line[pt + 3], line[pt], line[pt + 1], line[pt + 2]) : Color.FromArgb(line[pt], line[pt + 1], line[pt + 2]));
                                x++;
                            }
                        }
                    }
                    else // Вывод изобрадения сниху вверх;
                    {
                        for (int y = Height - 1; y >= 0; y--) // проход по всем строкам;
                        {
                            fs.Read(line, 0, stride);
                            x = 0;
                            for (int pt = 0; pt < stride; pt += bytesPerPixel) // Проход по строке;
                            {
                                temp = line[pt];
                                line[pt] = line[pt + 2];
                                line[pt + 2] = temp;
                                bm.SetPixel(x, y, (bpp == 32) ? Color.FromArgb(line[pt + 3], line[pt], line[pt + 1], line[pt + 2]) : Color.FromArgb(line[pt], line[pt + 1], line[pt + 2]));
                                x++;
                            }
                        }
                    }
                }
                else // Вывод изображения справо на лево;
                {
                    if (!BottomToTop) // Вывод изобрадения сверху вниз;
                    {
                        for (int y = 0; y < Height; y++) // проход по всем строкам;
                        {
                            fs.Read(line, 0, stride);
                            x = 0;
                            for (int pt = stride - 1; pt >= 0; pt -= bytesPerPixel) // Проход по строке;
                            {
                                temp = line[pt];
                                line[pt] = line[pt + 2];
                                line[pt + 2] = temp;
                                bm.SetPixel(x, y, (bpp == 32) ? Color.FromArgb(line[pt + 3], line[pt], line[pt + 1], line[pt + 2]) : Color.FromArgb(line[pt], line[pt + 1], line[pt + 2]));
                                x++;
                            }
                        }
                    }
                    else // Вывод изобрадения сниху вверх;
                    {
                        for (int y = Height - 1; y >= 0; y--) // проход по всем строкам;
                        {
                            fs.Read(line, 0, stride);
                            x = 0;
                            for (int pt = stride - 1; pt >= 0; pt -= bytesPerPixel) // Проход по строке;
                            {
                                temp = line[pt];
                                line[pt] = line[pt + 2];
                                line[pt + 2] = temp;
                                bm.SetPixel(x, y, (bpp == 32) ? Color.FromArgb(line[pt + 3], line[pt], line[pt + 1], line[pt + 2]) : Color.FromArgb(line[pt], line[pt + 1], line[pt + 2]));
                                x++;
                            }
                        }
                    }
                }
                // ----
            }
            catch (Exception) { bm = null; }
            finally
            {
                if (fs != null) fs.Close();
            }
            // ----
            return bm;
        }
        // ----------------------------------------------------------------------



# Благодарности: Marcus[VPF], zot17[GameDev.Ru], Partizan[VPF];

Это сообщение отредактировал(а) MuForum - 18.8.2008, 18:21


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
MuForum
Дата 30.4.2009, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



# for all - Прочитал немало литературы, статей, форумов по поводу работы с классами Image, Bitmap и т.д., и почти везде говорят, что использование функции SetPixel() сильно сказывается на производительности.
Я на сколько смог оптимизировал алгоритм обработки массива в изображение, но может у кого-то возникнут ещё какие-то идеи по поводу оптимизации.

Код

using System;
using System.Drawing; // Bitmap;
using System.IO; // File;
using System.Runtime.InteropServices; // StructLayout; LayoutKind;
// ----------------------------------------------------------------------
namespace MST
{
    public static class TFFTGA
    {
        // ----------------------------------------------------------------------
        //  Developed by: S@nek[BoR]
        //  Creation Date: 18.08.2008
        //  Last Update: 06.04.2009
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        // # DATA/IMAGE TYPES:
        //  0  -  No image data included.
        //  1  -  Uncompressed, color-mapped images.
        //  2  -  Uncompressed, Unmapped RGB images.
        //  3  -  Uncompressed, black and white images.
        //  9  -  Run length encoded, color-mapped images.
        // 10  -  Run length encoded, RGB images.
        // 11  -  Compressed, black and white images.
        // ----------------------------------------------------------------------

        [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 */
        }
        // ----------------------------------------------------------------------

        public static Bitmap GetFromFile(string FilePath)
        {
            Bitmap bmp = null;
            FileStream fs = null;
            byte[] header = null;
            // ----
            if (!File.Exists(FilePath)) return null;
            // ----
            try
            {
                fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
                // ----
                int iHeaderSize = 0;
                unsafe { iHeaderSize = sizeof(HEADER_TGA); }
                header = new byte[iHeaderSize]; // header;
                // ----
                int bLength = (int)fs.Length - iHeaderSize;
                byte[] buffer = new byte[bLength];
                // ----
                fs.Position = 0;
                fs.Read(header, 0, iHeaderSize); // Маркер сдвинут на 18 байтов, так как произошло чтение;
                fs.Read(buffer, 0, bLength);
                fs.Close();
                // ----
                HEADER_TGA sgHeader = new HEADER_TGA();
                unsafe
                {
                    Marshal.Copy(header, 0, new IntPtr(&sgHeader), sizeof(HEADER_TGA));
                }
                // ----
                if (sgHeader.PixelDepth == 16 || sgHeader.PixelDepth == 24 || sgHeader.PixelDepth == 32)
                {
                    switch (sgHeader.ImageType)
                    {
                        case 0: bmp = GetUnCompressed(buffer, sgHeader); break;
                        case 1: break;
                        case 2: bmp = GetUnCompressed(buffer, sgHeader); break;
                        case 3: bmp = GetUnCompressed(buffer, sgHeader); break;
                        case 9: break;
                        case 10: bmp = GetCompressed(buffer, sgHeader); break;
                        case 11: break;
                        default: break;
                    }
                }
            }
            catch (Exception) { bmp = null; }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                    fs.Dispose();
                }
            }
            // ----
            return bmp;
        }
        // ----------------------------------------------------------------------

        private static Bitmap GetUnCompressed(byte[] buffer, HEADER_TGA sgHeader)
        {
            Bitmap bmp = null;
            int Width, Height, bpp, bytesPerPixel, stride;
            // ----
            try
            {
                // Определяем ширину TGA изображения;
                Width = sgHeader.Width;
                // Определяем высоту TGA изображения;
                Height = sgHeader.Height;
                // Получаем TGA бит/пиксель (16, 24 или 32);
                bpp = sgHeader.PixelDepth;
                // Делим на 8 для получения байт/пиксель;
                bytesPerPixel = bpp / 8;
                // Вычисляем количество байт на строке;
                stride = Width * bytesPerPixel;
                // ----
                int x = 0, y = 0, pt = 0, iStep = 0;
                byte[] line = new byte[stride];
                bmp = new Bitmap(Width, Height);
                // ----
                bool RightToLeft = ((sgHeader.ImageDescriptor & (1 << (8 - 4))) == 0) ? false : true;
                bool BottomToTop = ((sgHeader.ImageDescriptor & (1 << (8 - 5))) == 0) ? false : true;
                // ----
                if (!RightToLeft) //Вывод изображения слева на право;
                {
                    if (!BottomToTop) // Вывод изобрадения сверху вниз;
                    {
                        for (y = 0; y < Height; y++) // проход по всем строкам;
                        {
                            Array.Copy(buffer, iStep, line, 0, stride);
                            iStep += stride;
                            x = 0;
                            // ----
                            for (pt = 0; pt < stride; pt += bytesPerPixel) // Проход по строке;
                            {
                                bmp.SetPixel(x, y, (bpp == 32) ? Color.FromArgb(line[pt + 3], line[pt + 2], line[pt + 1], line[pt]) : Color.FromArgb(line[pt + 2], line[pt + 1], line[pt]));
                                x++;
                            }
                        }
                    }
                    else // Вывод изобрадения сниху вверх;
                    {
                        for (y = Height - 1; y >= 0; y--) // проход по всем строкам;
                        {
                            Array.Copy(buffer, iStep, line, 0, stride);
                            iStep += stride;
                            x = 0;
                            // ----
                            for (pt = 0; pt < stride; pt += bytesPerPixel) // Проход по строке;
                            {
                                bmp.SetPixel(x, y, (bpp == 32) ? Color.FromArgb(line[pt + 3], line[pt + 2], line[pt + 1], line[pt]) : Color.FromArgb(line[pt + 2], line[pt + 1], line[pt]));
                                x++;
                            }
                        }
                    }
                }
                else // Вывод изображения справо на лево;
                {
                    if (!BottomToTop) // Вывод изобрадения сверху вниз;
                    {
                        for (y = 0; y < Height; y++) // проход по всем строкам;
                        {
                            Array.Copy(buffer, iStep, line, 0, stride);
                            iStep += stride;
                            x = 0;
                            // ----
                            for (pt = stride - 1; pt >= 0; pt -= bytesPerPixel) // Проход по строке;
                            {
                                bmp.SetPixel(x, y, (bpp == 32) ? Color.FromArgb(line[pt + 3], line[pt + 2], line[pt + 1], line[pt]) : Color.FromArgb(line[pt + 2], line[pt + 1], line[pt]));
                                x++;
                            }
                        }
                    }
                    else // Вывод изобрадения сниху вверх;
                    {
                        for (y = Height - 1; y >= 0; y--) // проход по всем строкам;
                        {
                            Array.Copy(buffer, iStep, line, 0, stride);
                            iStep += stride;
                            x = 0;
                            // ----
                            for (pt = stride - 1; pt >= 0; pt -= bytesPerPixel) // Проход по строке;
                            {
                                bmp.SetPixel(x, y, (bpp == 32) ? Color.FromArgb(line[pt + 3], line[pt + 2], line[pt + 1], line[pt]) : Color.FromArgb(line[pt + 2], line[pt + 1], line[pt]));
                                x++;
                            }
                        }
                    }
                }
                // ----
            }
            catch (Exception) { bmp = null; }
            // ----
            return bmp;
        }
        // ----------------------------------------------------------------------

        private static Bitmap GetCompressed(byte[] buffer, HEADER_TGA sgHeader)
        {
            Bitmap bmp = null;
            MemoryStream nms = null;
            int Width, Height, bpp, bytesPerPixel;
            // ----
            try
            {
                // Определяем ширину TGA изображения;
                Width = sgHeader.Width;
                // Определяем высоту TGA изображения;
                Height = sgHeader.Height;
                // Получаем TGA бит/пиксель (16, 24 или 32);
                bpp = sgHeader.PixelDepth;
                // Делим на 8 для получения байт/пиксель;
                bytesPerPixel = bpp / 8;
                // ----
                uint j = 0;
                int iStep = 0;
                uint currentpixel = 0;
                uint pixelcount = Convert.ToUInt32(Width * Height); // Количество пикселей в изображении;
                byte[] colorbuffer = new byte[bytesPerPixel];
                byte chunkheader;
                nms = new MemoryStream();
                // ----
                do
                {
                    chunkheader = buffer[iStep];
                    iStep++;
                    // ----
                    if (chunkheader < 128) // Если секция является 'RAW' секцией;
                    {
                        chunkheader++; // Добавляем единицу для получения количества RAW пикселей;
                        for (j = 0; j < chunkheader; j++)
                        {
                            Array.Copy(buffer, iStep, colorbuffer, 0, bytesPerPixel);
                            iStep += bytesPerPixel;
                            // ----
                            nms.Write(colorbuffer, 0, bytesPerPixel);
                        }
                        currentpixel += chunkheader;
                    }
                    else // Если это RLE идентификатор;
                    {
                        chunkheader -= 127; // Вычитаем 127 для получения количества повторений;
                        // ----
                        Array.Copy(buffer, iStep, colorbuffer, 0, bytesPerPixel); // Считываем 1 пиксель;
                        iStep += bytesPerPixel;
                        // ----
                        for (j = 0; j < chunkheader; j++) nms.Write(colorbuffer, 0, bytesPerPixel);
                        // ----
                        currentpixel += chunkheader;
                    }
                }
                while (currentpixel < pixelcount);
                // ----
                bmp = GetUnCompressed(nms, sgHeader);
            }
            catch (Exception) { bmp = null; }
            finally
            {
                if (nms != null)
                {
                    nms.Close();
                    nms.Dispose();
                }
            }
            // ----
            return bmp;
        }
        // ----------------------------------------------------------------------

    }
}



Я читал на форумах про класс BitmapData, но не совсем догоняю, как его прикрутить в моём случае.
-- И будет ли с него вообще эффект?


P.S. -> Если у кого-то есть какие-то предложения, советы, с радостью выслушаю.

Это сообщение отредактировал(а) MuForum - 30.4.2009, 14:13


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
Rififi
Дата 30.4.2009, 14:59 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1254
Регистрация: 9.3.2008

Репутация: 5
Всего: 36



MuForum, 
P.S. -> Если у кого-то есть какие-то предложения, советы, с радостью выслушаю.
Умеет загружать BigTIFF (>4Gb)?
Умеет парсить и извлекать exif-информацию?

PM MAIL   Вверх
MuForum
  Дата 30.4.2009, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



10, Rififi - Вопрос был именно по TAGRA формату и именно по моему коду...
- Причём тут то, что ты написал... (Читай внимательнее сообщения и заголовок темы)

Это сообщение отредактировал(а) MuForum - 30.4.2009, 15:15


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
MuForum
Дата 1.5.2009, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



# for all - Переделал класс работы с *.tga форматом под класс BitmapData.
-- Хочу заметить, что скорость обработки данных возросла примерно в 12 раз!
-- Разница более чем существенная.
-- Благодарю всех, кто принимал участие в данной теме, опубликовываю получившейся результат.

# Результаты тестирования:
Цитата

Размер файла: 3,54 МБ (3 714 902 байт)
-- Без BitmapData: ~1008 мсек.
-- С BitmapData: ~83 мсек.

P.S. -> Тестировал 5 раз.


Код

using System;
using System.Drawing; // Bitmap;
using System.Drawing.Imaging; // BitmapData;
using System.IO; // File;
using System.Runtime.InteropServices; // StructLayout; LayoutKind;
// ----------------------------------------------------------------------
namespace MST
{
    public static class TFFTGA
    {
        // ----------------------------------------------------------------------
        //  Developed by: S@nek[BoR]
        //  Creation Date: 18.08.2008
        //  Edit Date: 01.05.2009
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        // # DATA/IMAGE TYPES:
        //  0  -  No image data included.
        //  1  -  Uncompressed, color-mapped images.
        //  2  -  Uncompressed, Unmapped RGB images.
        //  3  -  Uncompressed, black and white images.
        //  9  -  Run length encoded, color-mapped images.
        // 10  -  Run length encoded, RGB images.
        // 11  -  Compressed, black and white images.
        // ----------------------------------------------------------------------

        [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 */
        }
        // ----------------------------------------------------------------------

        public static Bitmap GetFromFile(string FilePath)
        {
            Bitmap bmp = null;
            FileStream fs = null;
            byte[] header = null;
            // ----
            if (!File.Exists(FilePath)) return null;
            // ----
            try
            {
                fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
                // ----
                int iHeaderSize = 0;
                unsafe { iHeaderSize = sizeof(HEADER_TGA); }
                header = new byte[iHeaderSize]; // header;
                // ----
                int bLength = (int)fs.Length - iHeaderSize;
                byte[] buffer = new byte[bLength];
                // ----
                fs.Position = 0;
                fs.Read(header, 0, iHeaderSize); // Маркер сдвинут на 18 байтов, так как произошло чтение;
                fs.Read(buffer, 0, bLength);
                fs.Close();
                // ----
                HEADER_TGA sgHeader = new HEADER_TGA();
                unsafe
                {
                    Marshal.Copy(header, 0, new IntPtr(&sgHeader), sizeof(HEADER_TGA));
                }
                // ----
                if (sgHeader.PixelDepth == 16 || sgHeader.PixelDepth == 24 || sgHeader.PixelDepth == 32)
                {
                    switch (sgHeader.ImageType)
                    {
                        case 0: bmp = GetUnCompressed(buffer, sgHeader); break;
                        case 1: break;
                        case 2: bmp = GetUnCompressed(buffer, sgHeader); break;
                        case 3: bmp = GetUnCompressed(buffer, sgHeader); break;
                        case 9: break;
                        case 10: bmp = GetCompressed(buffer, sgHeader); break;
                        case 11: break;
                        default: break;
                    }
                }
            }
            catch (Exception) { bmp = null; }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                    fs.Dispose();
                }
            }
            // ----
            return bmp;
        }
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        // The functions of processing *.tga files.
        // ----------------------------------------------------------------------

        private static unsafe Bitmap GetUnCompressed(byte[] buffer, HEADER_TGA sgHeader)
        {
            Bitmap bmp = null;
            int Width, Height, bpp, bytesPerPixel, stride;
            // ----
            try
            {
                // Определяем ширину TGA изображения;
                Width = sgHeader.Width;
                // Определяем высоту TGA изображения;
                Height = sgHeader.Height;
                // Получаем кол-во бит на пиксель; (16, 24, 32);
                bpp = sgHeader.PixelDepth;
                // Делим на 8 для получения байт/пиксель;
                bytesPerPixel = bpp / 8;
                // Вычисляем количество байт в строке;
                stride = Width * bytesPerPixel;
                // ----
                byte* row = null;
                int x = 0, y = 0, pt = 0, iStep = 0;
                byte[] line = new byte[stride];
                // ----
                bool LeftToRight = ((sgHeader.ImageDescriptor & (1 << (8 - 4))) == 0);
                bool TopToBottom = ((sgHeader.ImageDescriptor & (1 << (8 - 5))) == 0);
                // ----
                bmp = new Bitmap(Width, Height);
                Rectangle rect = new Rectangle(0, 0, Width, Height);
                BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);
                // ----
                if (LeftToRight) // Вывод изображения слева на право;
                {
                    if (TopToBottom) // Вывод изобрадения сверху вниз;
                    {
                        for (y = 0; y < Height; y++) // Проход по всем строкам;
                        {
                            Array.Copy(buffer, iStep, line, 0, stride);
                            iStep += stride;
                            x = 0;
                            // ----
                            row = (byte*)bmpData.Scan0 + (y * bmpData.Stride);
                            // ----
                            for (pt = 0; pt < stride; pt += bytesPerPixel, x += bytesPerPixel) // Проход по строке;
                            {
                                row[x + 0] = line[pt + 0];
                                row[x + 1] = line[pt + 1];
                                row[x + 2] = line[pt + 2];
                                if (bpp == 32) row[x + 3] = line[pt + 3];
                            }
                        }
                    }
                    else // Вывод изобрадения сниху вверх;
                    {
                        for (y = Height - 1; y >= 0; y--) // Проход по всем строкам;
                        {
                            Array.Copy(buffer, iStep, line, 0, stride);
                            iStep += stride;
                            x = 0;
                            // ----
                            row = (byte*)bmpData.Scan0 + (y * bmpData.Stride);
                            // ----
                            for (pt = 0; pt < stride; pt += bytesPerPixel, x += bytesPerPixel) // Проход по строке;
                            {
                                row[x + 0] = line[pt + 0];
                                row[x + 1] = line[pt + 1];
                                row[x + 2] = line[pt + 2];
                                if (bpp == 32) row[x + 3] = line[pt + 3];
                            }
                        }
                    }
                }
                else // Вывод изображения справо на лево;
                {
                    if (TopToBottom) // Вывод изобрадения сверху вниз;
                    {
                        for (y = 0; y < Height; y++) // Проход по всем строкам;
                        {
                            Array.Copy(buffer, iStep, line, 0, stride);
                            iStep += stride;
                            x = 0;
                            // ----
                            row = (byte*)bmpData.Scan0 + (y * bmpData.Stride);
                            // ----
                            for (pt = stride - 1; pt >= 0; pt -= bytesPerPixel, x += bytesPerPixel) // Проход по строке;
                            {
                                row[x + 0] = line[pt - 3];
                                row[x + 1] = line[pt - 2];
                                row[x + 2] = line[pt - 1];
                                if (bpp == 32) row[x + 3] = line[pt - 0];
                            }
                        }
                    }
                    else // Вывод изобрадения сниху вверх;
                    {
                        for (y = Height - 1; y >= 0; y--) // Проход по всем строкам;
                        {
                            Array.Copy(buffer, iStep, line, 0, stride);
                            iStep += stride;
                            x = 0;
                            // ----
                            row = (byte*)bmpData.Scan0 + (y * bmpData.Stride);
                            // ----
                            for (pt = stride - 1; pt >= 0; pt -= bytesPerPixel, x += bytesPerPixel) // Проход по строке;
                            {
                                row[x + 0] = line[pt - 3];
                                row[x + 1] = line[pt - 2];
                                row[x + 2] = line[pt - 1];
                                if (bpp == 32) row[x + 3] = line[pt - 0];
                            }
                        }
                    }
                }
                // ----
                bmp.UnlockBits(bmpData);
            }
            catch (Exception) { bmp = null; }
            // ----
            return bmp;
        }
        // ----------------------------------------------------------------------

        private static Bitmap GetCompressed(byte[] buffer, HEADER_TGA sgHeader)
        {
            Bitmap bmp = null;
            MemoryStream nms = null;
            int Width, Height, bpp, bytesPerPixel;
            // ----
            try
            {
                // Определяем ширину TGA изображения;
                Width = sgHeader.Width;
                // Определяем высоту TGA изображения;
                Height = sgHeader.Height;
                // Получаем кол-во бит на пиксель; (16, 24, 32);
                bpp = sgHeader.PixelDepth;
                // Делим на 8 для получения байт/пиксель;
                bytesPerPixel = bpp / 8;
                // ----
                uint j = 0;
                int iStep = 0;
                uint currentpixel = 0;
                uint pixelcount = Convert.ToUInt32(Width * Height); // Количество пикселей в изображении;
                byte[] colorbuffer = new byte[bytesPerPixel];
                byte chunkheader;
                nms = new MemoryStream();
                // ----
                while (currentpixel < pixelcount)
                {
                    chunkheader = buffer[iStep];
                    iStep++;
                    // ----
                    if (chunkheader < 128) // Если секция является 'RAW' секцией;
                    {
                        chunkheader++; // Добавляем единицу для получения количества RAW пикселей;
                        for (j = 0; j < chunkheader; j++)
                        {
                            Array.Copy(buffer, iStep, colorbuffer, 0, bytesPerPixel);
                            iStep += bytesPerPixel;
                            // ----
                            nms.Write(colorbuffer, 0, bytesPerPixel);
                        }
                        currentpixel += chunkheader;
                    }
                    else // Если это RLE идентификатор;
                    {
                        chunkheader -= 127; // Вычитаем 127 для получения количества повторений;
                        // ----
                        Array.Copy(buffer, iStep, colorbuffer, 0, bytesPerPixel); // Считываем 1 пиксель;
                        iStep += bytesPerPixel;
                        // ----
                        for (j = 0; j < chunkheader; j++) nms.Write(colorbuffer, 0, bytesPerPixel);
                        // ----
                        currentpixel += chunkheader;
                    }
                }
                // ----
                bmp = GetUnCompressed(nms, sgHeader);
            }
            catch (Exception) { bmp = null; }
            finally
            {
                if (nms != null)
                {
                    nms.Close();
                    nms.Dispose();
                }
            }
            // ----
            return bmp;
        }
        // ----------------------------------------------------------------------

    }
}



P.S. -> Если у кого-то есть ещё какие-то советы/предложения по оптимизации данного класса, высказывайте, буду благодарен.

Это сообщение отредактировал(а) MuForum - 10.5.2009, 11:15


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
MuForum
Дата 10.5.2009, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



# for all - Реализовал очередную оптимизацию для чтения *.tga файлов.
1. Если файл записан слево на право, то прирост в скорости от оптимизации ~ 23%.
2. Если файл сжат алгоритмом RLE, то прирост в скорости от оптимизации ~ 34%
-- + ещё 23% если файл записан слево на право, итого 56%.

# Тестирование:
Цитата

Разрешение: 1123x827
Расширение: .tga
До всех оптимизаций: ~ 1'015 мсек.
После всех оптимизаций: ~ 68 мсек.
Общий прирост в скорости: ~1500%; (~ в 15 раз)


Код

using System;
using System.Drawing; // Bitmap;
using System.Drawing.Imaging; // BitmapData;
using System.IO; // File;
using System.Runtime.InteropServices; // StructLayout; LayoutKind; Marshal;
// ----------------------------------------------------------------------
namespace MST
{
    public static class TFFTGA
    {
        // ----------------------------------------------------------------------
        //  Developed by: S@nek[BoR]
        //  Creation Date: 18.08.2008
        //  Last Update: 10.05.2009
        // ----------------------------------------------------------------------

        // ----------------------------------------------------------------------
        // # DATA/IMAGE TYPES:
        //  0  -  No image data included.
        //  1  -  Uncompressed, color-mapped images.
        //  2  -  Uncompressed, Unmapped RGB images.
        //  3  -  Uncompressed, black and white images.
        //  9  -  Run length encoded, color-mapped images.
        // 10  -  Run length encoded, RGB images.
        // 11  -  Compressed, black and white images.
        // ----------------------------------------------------------------------

        [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 */
        }
        // ----------------------------------------------------------------------

        public static Bitmap GetFromFile(string FilePath)
        {
            Bitmap bmp = null;
            FileStream fs = null;
            byte[] header = null;
            // ----
            if (!File.Exists(FilePath)) return null;
            // ----
            try
            {
                fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
                // ----
                int iHeaderSize = 0;
                unsafe { iHeaderSize = sizeof(HEADER_TGA); }
                header = new byte[iHeaderSize]; // header;
                // ----
                int bLength = (int)fs.Length - iHeaderSize;
                byte[] buffer = new byte[bLength];
                // ----
                fs.Position = 0;
                fs.Read(header, 0, iHeaderSize); // Маркер сдвинут на 18 байтов, так как произошло чтение;
                fs.Read(buffer, 0, bLength);
                fs.Close();
                // ----
                HEADER_TGA sgHeader = new HEADER_TGA();
                unsafe
                {
                    Marshal.Copy(header, 0, new IntPtr(&sgHeader), sizeof(HEADER_TGA));
                }
                // ----
                if (sgHeader.PixelDepth == 16 || sgHeader.PixelDepth == 24 || sgHeader.PixelDepth == 32)
                {
                    switch (sgHeader.ImageType)
                    {
                        case 0: bmp = GetUnCompressed(buffer, sgHeader); break;
                        case 1: break;
                        case 2: bmp = GetUnCompressed(buffer, sgHeader); break;
                        case 3: bmp = GetUnCompressed(buffer, sgHeader); break;
                        case 9: break;
                        case 10: bmp = GetCompressed(buffer, sgHeader); break;
                        case 11: break;
                        default: break;
                    }
                }
            }
            catch (Exception) { bmp = null; }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                    fs.Dispose();
                }
            }
            // ----
            return bmp;
        }
        // ----------------------------------------------------------------------
        
        // ----------------------------------------------------------------------
        // The functions of processing *.tga files.
        // ----------------------------------------------------------------------

        private static unsafe Bitmap GetUnCompressed(byte[] buffer, HEADER_TGA sgHeader)
        {
            Bitmap bmp = null;
            int Width, Height, bpp, bytesPerPixel, stride;
            // ----
            try
            {
                // Определяем ширину TGA изображения;
                Width = sgHeader.Width;
                // Определяем высоту TGA изображения;
                Height = sgHeader.Height;
                // Получаем кол-во бит на пиксель; (16, 24, 32);
                bpp = sgHeader.PixelDepth;
                // Делим на 8 для получения байт/пиксель;
                bytesPerPixel = bpp / 8;
                // Вычисляем количество байт в строке;
                stride = Width * bytesPerPixel;
                // ----
                const int Isb32p = 32;
                // ----
                byte* row = null;
                IntPtr rowP = IntPtr.Zero;
                int x = 0, y = 0, pt = 0, iStep = 0;
                byte[] line = new byte[stride];
                // ----
                bool LeftToRight = ((sgHeader.ImageDescriptor & (1 << (8 - 4))) == 0);
                bool TopToBottom = ((sgHeader.ImageDescriptor & (1 << (8 - 5))) == 0);
                // ----
                bmp = new Bitmap(Width, Height);
                Rectangle rect = new Rectangle(0, 0, Width, Height);
                BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);
                // ----
                if (LeftToRight) // Вывод изображения слева на право;
                {
                    if (TopToBottom) // Вывод изобрадения сверху вниз;
                    {
                        for (y = 0; y < Height; y++) // Проход по всем строкам;
                        {
                            /*
                            Array.Copy(buffer, iStep, line, 0, stride);
                            iStep += stride;
                            x = 0;
                            // ----
                            row = (byte*)bmpData.Scan0 + (y * bmpData.Stride);
                            // ----
                            for (pt = 0; pt < stride; pt += bytesPerPixel, x += bytesPerPixel) // Проход по строке;
                            {
                                row[x + 0] = line[pt + 0];
                                row[x + 1] = line[pt + 1];
                                row[x + 2] = line[pt + 2];
                                if (bpp == 32) row[x + 3] = line[pt + 3];
                            }
                            */
                            // ----
                            ///*
                            rowP = (IntPtr)((int)bmpData.Scan0 + (y * bmpData.Stride));
                            // ----
                            Marshal.Copy(buffer, iStep, rowP, stride);
                            iStep += stride;
                            //*/
                        }
                    }
                    else // Вывод изобрадения сниху вверх;
                    {
                        for (y = Height - 1; y >= 0; y--) // Проход по всем строкам;
                        {
                            /*
                            Array.Copy(buffer, iStep, line, 0, stride);
                            iStep += stride;
                            x = 0;
                            // ----
                            row = (byte*)bmpData.Scan0 + (y * bmpData.Stride);
                            // ----
                            for (pt = 0; pt < stride; pt += bytesPerPixel, x += bytesPerPixel) // Проход по строке;
                            {
                                row[x + 0] = line[pt + 0];
                                row[x + 1] = line[pt + 1];
                                row[x + 2] = line[pt + 2];
                                if (bpp == 32) row[x + 3] = line[pt + 3];
                            }
                            */
                            // ----
                            ///*
                            rowP = (IntPtr)((int)bmpData.Scan0 + (y * bmpData.Stride));
                            // ----
                            Marshal.Copy(buffer, iStep, rowP, stride);
                            iStep += stride;
                            //*/
                        }
                    }
                }
                else // Вывод изображения справо на лево;
                {
                    if (TopToBottom) // Вывод изобрадения сверху вниз;
                    {
                        for (y = 0; y < Height; y++) // Проход по всем строкам;
                        {
                            Array.Copy(buffer, iStep, line, 0, stride);
                            iStep += stride;
                            x = 0;
                            // ----
                            row = (byte*)bmpData.Scan0 + (y * bmpData.Stride);
                            // ----
                            for (pt = stride - 1; pt >= 0; pt -= bytesPerPixel, x += bytesPerPixel) // Проход по строке;
                            {
                                row[x + 0] = line[pt - 3];
                                row[x + 1] = line[pt - 2];
                                row[x + 2] = line[pt - 1];
                                if (bpp == Isb32p) row[x + 3] = line[pt - 0];
                            }
                        }
                    }
                    else // Вывод изобрадения сниху вверх;
                    {
                        for (y = Height - 1; y >= 0; y--) // Проход по всем строкам;
                        {
                            Array.Copy(buffer, iStep, line, 0, stride);
                            iStep += stride;
                            x = 0;
                            // ----
                            row = (byte*)bmpData.Scan0 + (y * bmpData.Stride);
                            // ----
                            for (pt = stride - 1; pt >= 0; pt -= bytesPerPixel, x += bytesPerPixel) // Проход по строке;
                            {
                                row[x + 0] = line[pt - 3];
                                row[x + 1] = line[pt - 2];
                                row[x + 2] = line[pt - 1];
                                if (bpp == Isb32p) row[x + 3] = line[pt - 0];
                            }
                        }
                    }
                }
                // ----
                bmp.UnlockBits(bmpData);
            }
            catch (Exception) { bmp = null; }
            // ----
            return bmp;
        }
        // ----------------------------------------------------------------------

        private static Bitmap GetCompressed(byte[] buffer, HEADER_TGA sgHeader)
        {
            Bitmap bmp = null;
            MemoryStream nms = null;
            int Width, Height, bpp, bytesPerPixel;
            // ----
            try
            {
                // Определяем ширину TGA изображения;
                Width = sgHeader.Width;
                // Определяем высоту TGA изображения;
                Height = sgHeader.Height;
                // Получаем кол-во бит на пиксель; (16, 24, 32);
                bpp = sgHeader.PixelDepth;
                // Делим на 8 для получения байт/пиксель;
                bytesPerPixel = bpp / 8;
                // ----
                const int iRAWSection = 127;
                // ----
                uint j = 0;
                int iStep = 0;
                int bpCount = 0;
                uint currentpixel = 0;
                uint pixelcount = Convert.ToUInt32(Width * Height); // Количество пикселей в изображении;
                byte[] colorbuffer = new byte[bytesPerPixel];
                byte chunkheader = 0;
                // ----
                nms = new MemoryStream();
                // ----
                while (currentpixel < pixelcount)
                {
                    chunkheader = buffer[iStep];
                    iStep++;
                    // ----
                    if (chunkheader <= iRAWSection) // Если секция является 'RAW' секцией;
                    {
                        chunkheader++; // Добавляем единицу для получения количества RAW пикселей;
                        // ----
                        /*
                        for (j = 0; j < chunkheader; j++)
                        {
                            Array.Copy(buffer, iStep, colorbuffer, 0, bytesPerPixel);
                            iStep += bytesPerPixel;
                            // ----
                            nms.Write(colorbuffer, 0, bytesPerPixel);
                        }
                        */
                        // ----
                        ///*
                        bpCount = bytesPerPixel * chunkheader;
                        nms.Write(buffer, iStep, bpCount);
                        iStep += bpCount;
                        //*/
                        // ----
                        currentpixel += chunkheader;
                    }
                    else // Если это RLE идентификатор;
                    {
                        chunkheader -= iRAWSection; // Вычитаем 127 для получения количества повторений;
                        // ----
                        Array.Copy(buffer, iStep, colorbuffer, 0, bytesPerPixel); // Считываем 1 пиксель;
                        iStep += bytesPerPixel;
                        // ----
                        for (j = 0; j < chunkheader; j++) nms.Write(colorbuffer, 0, bytesPerPixel);
                        // ----
                        currentpixel += chunkheader;
                    }
                }
                // ----
                bmp = GetUnCompressed(nms, sgHeader);
            }
            catch (Exception) { bmp = null; }
            finally
            {
                if (nms != null)
                {
                    nms.Close();
                    nms.Dispose();
                }
            }
            // ----
            return bmp;
        }
        // ----------------------------------------------------------------------

    }
}




P.S. -> Если у кого-то есть ещё какие-то предложения по оптимизации, буду рад выслушать.

Это сообщение отредактировал(а) MuForum - 10.5.2009, 13:04


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0684 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.