Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.11.2011, 13:46   #1
Alexanderrr
 
Регистрация: 19.07.2011
Сообщений: 3
Вопрос Формирование PNG

Доброго времени суток, народ!

Возникла проблема-надо сформировать png с индексной палитрой (256 цветов) на основе 3х файлов (заголовок содержит ширину и высоту изображения; индексированная палитра на 256 цветов; файл-растр с номерами цветов из индексной палитры). Формируется только часть изображения, а остальное красится одним цветом - почему такое может получаться. Исходник прилагаю. Заранее спс за помощь
Вложения
Тип файла: zip AntiIdrisi(2).zip (98.7 Кб, 13 просмотров)
Alexanderrr вне форума Ответить с цитированием
Старый 17.11.2011, 13:48   #2
Alexanderrr
 
Регистрация: 19.07.2011
Сообщений: 3
По умолчанию

Сам метод, который формирует изображение:

Код:
private void MakePNG(string headerFile, string rastrFile, string paletteFile)
        {
            MemoryStream stream = new MemoryStream();

            //массив байтов, который в дальнейшем будем использовать для расчета crc
            byte[] bytesForCRC = null;

            //запишем сигнатуру png-файла: 137 80 78 71 13 10 26 10
            stream.WriteByte(137);
            stream.WriteByte(80);
            stream.WriteByte(78);
            stream.WriteByte(71);
            stream.WriteByte(13);
            stream.WriteByte(10);
            stream.WriteByte(26);
            stream.WriteByte(10);

            #region chunk_IHDR
            //запишем первый chunk-IHDR
            //для записи массива байтов - чтоб потом посчитать crc надо запомнить 17 байтов
            bytesForCRC = new byte[17];
            //запишем длину - 4 байта (в последнем байте для IHDR - значение 13)
            stream.WriteByte(0);
            stream.WriteByte(0);
            stream.WriteByte(0);
            stream.WriteByte(13);

            //запишем тип чанка 73 72 68 82
            stream.WriteByte(73);
            bytesForCRC[0] = 73;
            stream.WriteByte(72);
            bytesForCRC[1] = 72;
            stream.WriteByte(68);
            bytesForCRC[2] = 68;
            stream.WriteByte(82);
            bytesForCRC[3] = 82;


            //запишем ширину изображения - 4 байта (возьмем ее из файла заголовка)
            long w = GetImageWidth(headerFile);
            stream.WriteByte((byte)(w >> 24));
            bytesForCRC[4] = (byte)(w >> 24);
            stream.WriteByte((byte)(w >> 16));
            bytesForCRC[5] = (byte)(w >> 16);
            stream.WriteByte((byte)(w >> 8));
            bytesForCRC[6] = (byte)(w >> 8);
            stream.WriteByte((byte)(w));
            bytesForCRC[7] = (byte)w;


            //запишем высоту изображения - 4 байта (возьмем ее из файла заголовка)
            long h = GetImageHeight(headerFile);
            stream.WriteByte((byte)(h >> 24));
            bytesForCRC[8] = (byte)(h >> 24);
            stream.WriteByte((byte)(h >> 16));
            bytesForCRC[9] = (byte)(h >> 16);
            stream.WriteByte((byte)(h >> 8));
            bytesForCRC[10] = (byte)(h >> 8);
            stream.WriteByte((byte)(h));
            bytesForCRC[11] = (byte)h;

            //пишем глубину цвета - 256 цветов, палитру (=3 - индексная палитра) и еще 3 пар-ра
            stream.WriteByte(8);
            bytesForCRC[12] = 8;
            stream.WriteByte(3);
            bytesForCRC[13] = 3;
            stream.WriteByte(0);
            bytesForCRC[14] = 0;
            stream.WriteByte(0);
            bytesForCRC[15] = 0;
            stream.WriteByte(0);
            bytesForCRC[16] = 0;
            
            //пишем CRC
            byte[] crc = this.CalculateCRC(bytesForCRC);
            stream.WriteByte(crc[0]);
            stream.WriteByte(crc[1]);
            stream.WriteByte(crc[2]);
            stream.WriteByte(crc[3]);
            #endregion

            #region chunk_PLTE
            //запишем chunk-палитру
            //получим палитру из файла
            ArrayList pallete = this.GetPallete(paletteFile);
            
            //запишем ее длину
            stream.WriteByte((byte)(pallete.Count >> 24));
            stream.WriteByte((byte)(pallete.Count >> 16));
            stream.WriteByte((byte)(pallete.Count >> 8));
            stream.WriteByte((byte)(pallete.Count));

            //определим кол-во кол-во байт для crc
            bytesForCRC = new byte[pallete.Count + 4];

            //запишем тип чанка 80 76 84 69
            stream.WriteByte(80);
            bytesForCRC[0] = 80;
            stream.WriteByte(76);
            bytesForCRC[1] = 76;
            stream.WriteByte(84);
            bytesForCRC[2] = 84;
            stream.WriteByte(69);
            bytesForCRC[3] = 69;

            //пишем палитру и запоминаем байты под crc
            int pos = 4;
            foreach (object obj in pallete)
            {
                byte b = (byte)obj;
                stream.WriteByte(b);
                bytesForCRC[pos] = b;
                pos++;
            }

            //читаем и пишем crc
            crc = this.CalculateCRC(bytesForCRC);
            stream.WriteByte(crc[0]);
            stream.WriteByte(crc[1]);
            stream.WriteByte(crc[2]);
            stream.WriteByte(crc[3]);

            #endregion

<продолжение далее>
Alexanderrr вне форума Ответить с цитированием
Старый 17.11.2011, 13:48   #3
Alexanderrr
 
Регистрация: 19.07.2011
Сообщений: 3
По умолчанию

продолжение метода (не вставляет более 5000 символов)

Код:
            #region chunk_IDAT
            //определим треб длину w*h + кол-во строк h + 7 байт вначале и 4 в конце (11)
            /*stream.WriteByte((byte)((w * h + h + 11) >> 24));
            stream.WriteByte((byte)((w * h + h + 11) >> 16));
            stream.WriteByte((byte)((w * h + h + 11) >> 8));
            stream.WriteByte((byte)((w * h + h + 11)));*/
            stream.WriteByte((byte)((w * h + h) >> 24));
            stream.WriteByte((byte)((w * h + h) >> 16));
            stream.WriteByte((byte)((w * h + h) >> 8));
            stream.WriteByte((byte)((w * h + h)));

            //подготовим crc для записи
            bytesForCRC = new byte[w * h + 11 + h];

            //запишем тип чанка 73 68 65 84
            stream.WriteByte(73);
            bytesForCRC[0] = 73;
            stream.WriteByte(68);
            bytesForCRC[1] = 68;
            stream.WriteByte(65);
            bytesForCRC[2] = 65;
            stream.WriteByte(84);
            bytesForCRC[3] = 84;

            //откроем файл для чтения
            StreamReader rastr = new StreamReader(rastrFile);

            //запишем непонятные 7 байтов
            //zlib_header
            stream.WriteByte(120);
            bytesForCRC[4] = 120;
            stream.WriteByte(1);
            bytesForCRC[5] = 1;
            //deflate_header
            stream.WriteByte(1);
            bytesForCRC[6] = 1;
            stream.WriteByte(255);
            bytesForCRC[7] = 255;
            stream.WriteByte(255);
            bytesForCRC[8] = 255;
            stream.WriteByte(0);
            bytesForCRC[9] = 0;
            stream.WriteByte(0);
            bytesForCRC[10] = 0;

            /*stream.WriteByte(0);
            bytesForCRC[4] = 0;
            stream.WriteByte(0);
            bytesForCRC[5] = 0;
            stream.WriteByte(0);
            bytesForCRC[6] = 0;
            stream.WriteByte(0);
            bytesForCRC[7] = 0;
            stream.WriteByte(0);
            bytesForCRC[8] = 0;
            stream.WriteByte(0);
            bytesForCRC[9] = 0;
            stream.WriteByte(0);
            bytesForCRC[10] = 0;*/

            int k = 4; int m = 0;
            while (!rastr.EndOfStream)
            {
                byte b = byte.Parse(rastr.ReadLine().Trim());
                if ((m) % w == 0)
                {
                    bytesForCRC[k] = 0;
                    stream.WriteByte(0);
                    k++;
                }
                bytesForCRC[k] = b;
                stream.WriteByte(b);                
                m++;
                k++;
            }

            rastr.Close();

            //запишем последние 4 байта
            /*stream.WriteByte(0);
            bytesForCRC[k + 0] = 0;
            stream.WriteByte(0);
            bytesForCRC[k + 1] = 0;
            stream.WriteByte(0);
            bytesForCRC[k + 2] = 0;
            stream.WriteByte(59);
            bytesForCRC[k + 3] = 0;*/

            //читаем и пишем crc
            crc = this.CalculateCRC(bytesForCRC);
            stream.WriteByte(crc[0]);
            stream.WriteByte(crc[1]);
            stream.WriteByte(crc[2]);
            stream.WriteByte(crc[3]);


            #endregion

            #region chunk_IEND
            //пишем длину
            stream.WriteByte(0);
            stream.WriteByte(0);
            stream.WriteByte(0);
            stream.WriteByte(0);

            bytesForCRC = new byte[4];

            //тип 73 69 78 68
            stream.WriteByte(73);
            bytesForCRC[0] = 73;
            stream.WriteByte(69);
            bytesForCRC[1] = 69;
            stream.WriteByte(78);
            bytesForCRC[2] = 78;
            stream.WriteByte(68);
            bytesForCRC[3] = 68;

            //читаем и пишем crc
            crc = this.CalculateCRC(bytesForCRC);
            stream.WriteByte(crc[0]);
            stream.WriteByte(crc[1]);
            stream.WriteByte(crc[2]);
            stream.WriteByte(crc[3]);

            #endregion

            //---------------------------------------------------
            this.pbResult.Image = Image.FromStream(stream);
            this.Text = this.pbResult.Image.Width.ToString() + "___" + this.pbResult.Image.Height.ToString();
            if (File.Exists("d:\\asd.png"))
                File.Delete("d:\\asd.png");
            FileStream writer = new FileStream("d:\\asd.png", FileMode.CreateNew);
            stream.WriteTo(writer);
            writer.Close();
            stream.Close();
        }
Alexanderrr вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
PNG nXs Мультимедиа в Delphi 2 31.10.2010 12:53
PNG _-Re@l-_ Общие вопросы Delphi 8 15.07.2010 16:48
Ковертирование из png 24 бит в png 8 бит isat Общие вопросы .NET 0 22.03.2010 13:38
*.png Killbrum Помощь студентам 3 30.08.2008 15:51
Png Witaliy Мультимедиа в Delphi 3 25.05.2008 23:10