Какие программы читают png

Желаю здравствовать всем труженикам «мыша» и клавиатуры. В этой статье мне хотелось бы поделиться опытом загрузки различных графических и не очень форматов данных. В первую очередь, рассказ пойдет для новичков, но, думаю, и многочисленные опытные гейм разработчики найдут в нем много интересного.

И так, о чем же пойдет речь? Начиная свой новый проект, мы решили, что хорошо бы спрятать все игровые данные от глаз любопытных пользователей. Да и с эстетической точки зрения, чем меньше файлов, тем нагляднее структура. Дабы не изобретать велосипед, в качестве ресурсного файла был взят обычный zip-архив.

И все бы ничего, да вот для чтения текстур из файлов (*.jpg и *.png) используются сторонние библиотеки, с ними то и возникло большинство проблем. Вот о них и пойдет разговор.

Что нам понадобится?

1. Для чтения из ZIP-архива понадобиться библиотека unzip. Найти ее можно по этому адресу:
http://www.winimage.com/zLibDll/unzip.html. Дома у меня версия 1.00, за 10 сентября 2003 г.

Как убрать белый фон в фотошопе и сохранить в формате PNG


2. Читать PNG формат будем при помощи библиотечки libpng. Домашняя страничка здесь:
http://www.libpng.org/pub/png/libpng.html. Я пользовался версией 1.2.5, от 3 октября 2002 г.
3. Картинки в JPEG-формате понимает libjpeg. Последние версии можно найти по этому адресу:
ftp://ftp.uu.net/graphics/jpeg/. Моя версия библиотеки значится под номером 6 бета, и датируется 27 марта 1998 г. Страница этой библиотеки здесь: http://www.ijg.org/.
4. Пример, поставляемый с этой статьей.
5. Ко всему этому комплекту желательно иметь какую-нибудь визуальную студию с компилятором «С++».

Стоит отметить, что все вышеперечисленные библиотеки и примеры работы с ними можно найти в «nVidia SDK».

Чтение ZIP-архивов

Наша игра общается с винчестером через класс-оболочку cFile, который умеет писать и читать как обычные файлы, так и файлы, запакованные в zip (только чтение). Описан он в файле «filemngr.h», а реализован соответственно в «filemngr.cpp». Для унификации работы, параметры, принимаемые методами этого класса, и возвращаемые значения совпадают с параметрами функций из заголовочного файла . Дабы не отвлекаться по мелочам, в статье рассмотрим только те части кода, которые непосредственно необходимы для чтения ZIP-архивов.

Для работы с архивом, понадобится две переменных. Первая – указатель на ZIP-файл, подобная FILE* в стандартных потоках ввода/вывода. Вторая представляет собой структуру, содержащую информацию о файле в архиве.

// данные для сжатых ZIP’ом файлов // указатель на ZIP файл unzFile m_pZFile; // информация о зазипованном файле (интересен размер распакованного файла) unz_file_info m_ZInfo;

Открытие файлов — метод Open.

// смотрим, откуда юзверь хочет достать файл if ( szZipName ) < // из зипа // определяем тип файла (запись/чтение), сейчас доступно только чтение switch ( szMode[0] ) < case ‘r’: m_pData->m_Type = cFileData::e_ZipFile; break; > if ( m_pData->m_Type == cFileData::e_Unknown ) return( cFile::cError::WrongMode ); //——————————————————————- // пытаемся открыть файл и распаковать его try < // открываем zip файл m_pData->m_pZFile = unzOpen( szZipName); if ( !m_pData->m_pZFile ) throw cZipCatch( «^7File Manager:^6 ZIP file %s ^4not found^6n», cFile::cError::ZipNotFound); // ищем в нем наш файл if ( unzLocateFile( m_pData->m_pZFile, szFileName, 0) != UNZ_OK ) throw cZipCatch( «^7File Manager:^6 File %s ^4not found^6 in ZIP filen», cFile::cError::FileNotFound); // если мы его нашли, то получаем о нем информацию if ( unzGetCurrentFileInfo( m_pData->m_pZFile, m_ZInfo, 0,0, 0,0, 0,0) != UNZ_OK ) throw cZipCatch( «^7File Manager:^6 ^4Internal error^6 in ZIP file — couldn’t get file infon», cFile::cError::DamageZip); // открываем наш файл для чтения if ( unzOpenCurrentFile( m_pData->m_pZFile) != UNZ_OK ) throw cZipCatch( «^7File Manager:^6 ^4Internal error^6 in ZIP file — couldn’t open filen», cFile::cError::DamageZip); > catch ( cZipCatch err ) < // сначала выведем ошибку в консоль // . // удаляем промежуточные данные (те которые в блоке try) if ( m_pData->m_pZFile ) unzClose( m_pData->m_pZFile ); // теперь удалим основные данные и вернем ошибку SAFE_DELETE( m_pData ); return( err.m_iError ); > >

Метод поиска и открытия файла в архиве, очень похож на стандартный сишный стиль.

Почему PNG картинка скачивается с фоном из квадратиков в фотошопе

Сначала, как и с обычным I/O потоком открываем архив функцией unzOpen(). В случае отсутствия файла или некорректного архива она вернет 0, если же все прошло гладко, то результатом будет указатель, используемый в других zip-функциях. Следующий наш шаг — поиск необходимого файла в архиве при помощи функции unzLocateFile(), помимо этого она сделает его файлом по умолчанию.

В качестве параметров ей передается само имя файла, а также метод сравнения имен, зависящий от регистра букв или нет. В случае успешного поиска результат функции будет равен UNZ_OK, в противном случае — UNZ_END_OF_LIST_OF_FILE.

Читайте также:
Какая программа переводчик работает без интернета

В процессе работы с файлом, часто приходится запрашивать его размер, к сожалению, ничего подобного fseek() моя старая версия библиотеки не поддерживала, поэтому, и по сей день, приходится брать информацию о файле непосредственно у zip-архива. Для этих целей служит функция unzGetCurrentFileInfo().

Помимо этого она позволяет узнать: версию zip’а, необходимого для распаковки, метод компрессии, дату последней модификации файла, размер файла в сжатом виде и пр. Так как пишем не архиватор, то об этих вещах, я рассказывать не буду. И последний шаг — это открытие текущего файла для чтения при помощи функции unzOpenCurrentFile(). В случае успеха, он вернет UNZ_OK.

Закрытие запакованного файла (метод Close()) происходит в 2 этапа: сначала мы закрываем файл внутри архива при помощи функции unzCloseCurrentFile(), а затем сам архив, используя unzClose().

// смотрим, как открывали файл if ( m_pData->m_Type == cFileData::e_ZipFile ) < // открывали из зипа if ( m_pData->m_pZFile ) unzCloseCurrentFile( m_pData->m_pZFile ); if ( m_pData->m_pZFile ) unzClose( m_pData->m_pZFile ); >

Стоит заметить, что в моей версии библиотеки, функция unzClose(), не может сама закрывать читаемый документ, поэтому первый этап обязателен.

Получение данных из запакованного файла происходит при помощи метода Read():

// читаем из зип-файла if ( m_pData->m_Type == cFileData::e_ZipFile ) < int err = unzReadCurrentFile( m_pData->m_pZFile, pBuffer, ( unsigned int)( uiSize * uiCount)); if ( err 0 ) < err = 0; // была ошибка — вернем 0 > return( err / uiSize ); // возвращаем как и fread кол-во полностью прочитанных элементов (а не байт) >

Функция unzReadCurrentFile() заполняет буфер pBuffer, массивом байт из уже распакованного файла, последний параметр указывает на размер буфера. В случае успеха, функция возвращает: число байт занесенное в буфер, 0 если достигнут конец файла и отрицательное число если произошла какая-то ошибка. Так как метод Read() я старался сделать похожим на стандартную функцию fread(), то возвращается не кол-во прочитанных байт, а кол-во «полных» элементов, в связи с этим и происходит деление на размер элемента.

Чтение PNG-формата

Теперь, когда разобрались с чтением запакованных файлов, можно приступить к главному — чтению графических форматов. Благо все библиотеки предоставляют возможность работы с пользовательскими I/O потоками. Для этого, библиотеке нужно описать функцию чтения данных из файла:

void PNGReadFunction( png_structp png_ptr, png_bytep data, png_size_t length) < cFile* pFile = ( cFile*)png_get_io_ptr( png_ptr); pFile->Read( data, 1, length); >

На вход подается структура, содержащая информацию о библиотеке, массив байт, в который нужно занести прочитанную информацию, и длина этого массива. Первой строкой определяется указатель на поток данных.

Как настроить на него PNG-библиотеку будет сказано ниже. Вторая строка — побайтовое чтение из файла в массив. На этом написание вспомогательных функций закончено, можно приступать к чтению файла.

Первым делом, откроем файл и считаем из него сигнатуру, которая позволит узнать тип файла. Обычно для PNG-формата считывают первые восемь байт:

// проверяем сигнатуру файла (первые number байт) png_byte sig[number] = 0>; file.Read( sig, sizeof( png_byte), number); if ( !png_check_sig( sig, number) ) < file.Close( ); return( cDataManager::cError::UnknownFormat ); > // проверка прошла успешно — это png-файл

Тестируется сигнатура при помощи функции png_check_sig(), на вход которой поступает массив из считанных байт и его длина. На выходе в случае несовпадения сигнатур, будет 0, в противном случае можно считать, что файл правильный. Следующий шаг — создание структур, содержащих информацию о библиотеке и файле:

// создаем внутреннюю структуру png для работы с файлом // последние параметры — структура, для функции обработки ошибок и варнинга (последн. 2 параметра) png_structp png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0); // создаем структуру с информацией о файле png_infop info_ptr = png_create_info_struct( png_ptr);

Затем говорим библиотеке, что мы уже считали восемь байт и записываем информацию о файле в структуру, созданную ранее. Нас будет интересовать информация о размерах картинки, глубине цвета и формате данных.

// говорим библиотеке, что мы уже прочли number байт, когда проверяли сигнатуру png_set_sig_bytes( png_ptr, number); // читаем всю информацию о файле png_read_info( png_ptr, info_ptr); // Эта функция возвращает инфу из info_ptr png_uint_32 width = 0, height = 0; // размер картинки в пикселях int bit_depth = 0; // глубина цвета (одного из каналов, может быть 1, 2, 4, 8, 16) int color_type = 0; // описывает какие каналы присутствуют: // PNG_COLOR_TYPE_GRAY, PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, // PNG_COLOR_TYPE_RGB, PNG_COLOR_TYPE_RGB_ALPHA. // последние 3 параметра могут быть нулями и обозначают: тип фильтра, тип компрессии и тип смещения png_get_IHDR( png_ptr, info_ptr, height, color_type, 0, 0, 0);

Получив необходимые данные, можно проверить, подходят они нам или нет. В случае неудовлетворительного ответа, библиотеке можно сказать, чтобы она на этапе считывания массива данных, конвертировала их в удобный для нас формат:

Читайте также:
Как изменить внешний вид программы

// png формат может содержать 16 бит на канал, но нам нужно только 8, поэтому сужаем канал if ( bit_depth == 16) png_set_strip_16( png_ptr); // преобразуем файл если он содержит палитру в нормальный RGB if ( color_type == PNG_COLOR_TYPE_PALETTE bit_depth = 8) png_set_palette_to_rgb( png_ptr); // если в грэйскейле меньше бит на канал чем 8, то конвертим к нормальному 8-битному if ( color_type == PNG_COLOR_TYPE_GRAY bit_depth 8) png_set_gray_1_2_4_to_8( png_ptr); // и добавляем полный альфа-канал if ( png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha( png_ptr);

В нашей игре допустимы картинки, содержащие информацию только об оттенках серого цвета (grayscale картинки). Если же, необходимо преобразование к RGB формату, то это можно сделать таким образом:

if ( color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb( png_ptr);

Теперь осталось только настроить гамму и можно будет приступить к чтению данных. Гамма складывается из двух компонент, так называемой гаммы монитора (screen gamma) и гаммы картинки. В документации к библиотеке указано, какое значение гаммы лучше подбирать для различных типов платформ и мониторов: 2.2 подходит для PC мониторов в освещенной комнате, 2.0 – в комнате с тусклым освещением и от 1.7 до 1.0 – для MacOS платформ. Гамма картинки может быть указана в самом файле, в случае если эта информация отсутствует, желательно присвоить стандартное значение гаммы, равное 0.45455.

double gamma = 0.0f; // если есть информация о гамме в файле, то устанавливаем на 2.2 if ( png_get_gAMA( png_ptr, info_ptr, // иначе ставим дефолтную гамму для файла в 0.45455 (good guess for GIF images on PCs) else png_set_gamma( png_ptr, 2.2, 0.45455);

Теперь обновим информацию в библиотеке и заново перечитаем данные о картинке — они должны совпасть с теми, которые мы запросили:

// после всех трансформаций, апдейтим информацию в библиотеке png_read_update_info( png_ptr, info_ptr); // опять получаем все размеры и параметры обновленной картинки png_get_IHDR( png_ptr, info_ptr, height, color_type, 0, 0, 0);

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

// определяем кол-во байт нужных для того чтобы вместить строку png_uint_32 row_bytes = png_get_rowbytes( png_ptr, info_ptr); // теперь, мы можем выделить память чтобы вместить картинку png_byte* data = new png_byte[row_bytes * height]; // выделяем память, для указателей на каждую строку png_byte **row_pointers = new png_byte * [height]; // сопоставляем массив указателей на строчки, с выделенными в памяти (res) // т.к. изображение перевернутое, то указатели идут снизу вверх for ( unsigned int i = 0; i height; i++) row_pointers[height — i — 1] = data + i * row_bytes; // все, читаем картинку png_read_image( png_ptr, row_pointers);

В приведенном выше коде определяется размер строки в байтах. Затем выделяется память для массива пикселей (размер строки, помноженный на количество строк). Чтобы после получения информации не заниматься перестановкой строк, просто выделяем еще один массив, в который занесем указатели на строки в обратном порядке, их и будем подсовывать библиотечной функции чтения всей картинки за раз png_read_image. Теперь картинка в памяти и остается только освободить память от указателей, закрыть библиотеку и файл:

// освобождаем память от указателей на строки delete [] row_pointers; // освобождаем память выделенную для библиотеки libpng png_destroy_read_struct( // закрываем файл file.Close( );

На этом рассказ о PNG-формате можно считать завершенным.

Страницы: 1 2 Следующая »

12 июля 2004 (Обновление: 9 июня 2009)

Источник: gamedev.ru

Файл расширение PNG-LARGE

Расширение файла PNG-Large связано с TweetDeck Social и Microgling Network Browser из Twitter.

Файл PNG-Large содержит изображение изображения в растровом формате JPEG, загруженного в Twitter.

Файл PNG -Large создается при просмотре изображения, хранящегося на TweetDeck, используя Google Chrome или браузеры Chromium — щелкните правой кнопкой мыши на картинке и выберите «Сохранить изображение как . опция».

Chrome хотел бы сохранить изображение с расширением файла PNG-LARGE.

Расширение файла PNG-Large получено из URL-адреса изображения, например:

Решение очень простое: переименовать расширение файла PNG-Large в PNG, и вы сможете просматривать файл в любом просмотре изображения растрового изображения.

Другие веб -браузеры, такие как Firefox, Internet Explorer, сохраняют фотографии из Twitter с оригинальным расширением JPG.

Как открыть: используйте любой просмотр, чтобы просмотреть контент *.png-Large файлов.
Как преобразовать: Используйте любое программное обеспечение для редактирования изображений для преобразования файла PNG-LARGE в другой формат файла изображения.

Pierre-Emmanuel Gougelet

  • .fre — Расширение файла
  • .oda — Расширение файла
  • .gif~c200 — Расширение файла
  • .png-large — Расширение файла
  • .jpg-original — Расширение файла

Источник: whatext.com

PNG — not GIF!

Доброго времени суток!
Вам когда-нибудь хотелось узнать как устроены файлы PNG? Нет? А я все равно расскажу.
Формат PNG(Portable Network Graphics) был изобретен в 1995 году, чтобы стать заменой GIF, а уже в 1996, с выходом версии 1.0, он был рекомендован W3C, в качестве полноправного сетевого формата. На сегодняшний день PNG является одним из основных форматов веб-графики.

Под катом вы найдете общее описание строения PNG-файла, некоторое количество картинок-схем, препарирование в hex-редакторе, и, конечно, ссылку на спецификацию.

Читайте также:
Программа для составления схемы для вышивки

Общее строение

Структура PNG в самом общем виде представлена на следующем рисунке.

То есть файл состоит из подписи и некоторого количества блоков(чанков, chunks), каждый из которых несет в себе некоторую информацию (спасибо КО!). Но почему подпись нельзя считать одним из чанков? Давайте разберемся поподробнее.

Подпись файла


Подпись PNG-файла всегда одинакова, состоит из 8 байт, и представляет собой (в hex-записи)

89 50 4E 47 0D 0A 1A 0A

  • 89 — non-ASCII символ. Препятствует распознаванию PNG, как текстового файла, и наоборот.
  • 50 4E 47 — PNG в ASCII записи.
  • 0D 0A — CRLF (Carriage-return, Line-feed), DOS-style перевод строки.
  • 1A — останавливает вывод файла в DOS режиме (end-of-file), чтобы вам не вываливалось многокилобайтное изображение в текстовом виде.
  • 0A — LF, Unix-style перевод строки.
Chunks

Чанки — это блоки данных, из которых состоит файл. Каждый чанк состоит из 4 секций.

Разберем эти секции по порядку.

Длина

Ну, с длиной вроде все ясно. Просто числовое значение длины блока данных.

Тип (имя)

С типом немного поинтересней. Тип представляет собой 4 чувствительных к регистру ASCII-символа. Регистры символов (пятый бит в числовой записи символа) в имени чанка различаются неспроста — это флаги, которые сообщают декодеру некоторую дополнительную информацию.

  • Регистр первого символа определяет является ли данный чанк критическим(верхний регистр) или вспомогательным(нижний регистр). Критические чанки должны распознаваться каждым декодером. Если декодер встречает критический чанк, тип которого не может распознать, он обязан завершить выполнение с ошибкой.
  • Регистр второго символа задает «публичность»(верхний регистр) или «приватность»(нижний регистр) чанка. «Публичные» чанки — официальные, задокументированные, распознаваемые большинством декодеров. Но если вдруг вам для каких-то своих нужд понадобится кодировать специфическую информацию, то просто в имени чанка сделайте второй символ маленьким.
  • Регистр третьего символа оставлен для будущих свершений. Предполагается, что он будет использоваться для дифференциации различных версий стандарта. Для версий 1.0 и 1.1 третий символ должен быть большим. Если он (внезапно!) оказался маленьким, все нынешние декодеры должны поступать с чанком, так же как и с любым другим не распознанным (то есть выходить с ошибкой если чанк критический, или пропускать в противном случае).
  • Регистр же четвертого символа означает возможность копирования данного чанка редакторами, которые не могут его распознать. Если регистр нижний, чанк может быть скопирован, вне зависимости от степени модификации файла, иначе (верхний регистр) он копируется только в случае, когда при модификации не были затронуты никакие критические чанки.

Для лучшего понимания, давайте разберем флаги на примере чанка, содержащего текст.

  • IHDR — заголовок файла, содержит основную информацию о изображении. Обязан быть первым чанком.
  • PLTE — палитра, список цветов.
  • IDAT — содержит, собственно, изображение. Рисунок можно разбить на несколько IDAT чанков, для потоковой передачи. В каждом файле должен быть хотя бы один IDAT чанк.
  • IEND — завершающий чанк, обязан быть последним в файле.
CRC

Контрольная сумма CRC-32. Кстати на днях был топик о ее подсчете в Windows.

Минимальный PNG

IHDR
  • Ширина, 4 байта
  • Высота, 4 байта
  • Битовая глубина (bit depth), определяет количество бит на каждый сэмпл(не пиксель), 1 байт
  • Тип цвета, состоит из 3 флагов 1 (используется палитра), 2 (используется цвет, не монохромное изображение), and 4 (присутствует альфа-канал), 1 байт
  • Метод сжатия. На данный момент доступно только значение 0 — сжатие по алгоритму deflate. Если значение отлично от 0, чанк считается нераспознанным, и декодер рапортует об ошибке. 1 байт
  • Метод фильтрации. Так же, как и в случае сжатия, на данный момент может быть только нулем. 1 байт
  • Interlace(переплетение) метод. Определяет порядок передачи данных. На данный момент доступно 2 значения: 0 (no interlace) и 1 (Adam7 interlace). 1 байт
IEND

Сигнализирует о конце файла, блок данных этого чанка не содержит ничего.

IDAT

Содержит данные, закодированные, в соответствии с полем метода сжатия в заголовке. Алгоритм декодирования выходит за рамки данной статьи (однако если будут желающие, может появиться в следующей), но в довольно хорошо (и по-русски) описан здесь.

Таким образом, простейший PNG-файл (на примере ) выглядит следующим образом.

Заключение

При написании данной статьи я ставил своей задачей дать читателю общие знания о строении PNG-файла, для более глубокого понимания рекомендуется читать спецификации.

Спасибо за внимание, буду рад любой критике!

Источник: habr.com

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru