Search
Write a publication
Pull to refresh
82.05
NtechLab
Мировой лидер в разработке решений на основе ИИ.

Сравнение форматов PNG: от первой до третьей редакции

Level of difficultyEasy
Reading time30 min
Views2.7K

TL;DR

Введение

Недавно опубликованная третья редакция спецификации Portable Network Graphics (PNG) 2025 года, разработанная World Wide Web Consortium (W3C), привлекла внимание к эволюции этого формата (W3C PNG Specification (Third Edition, 2025)). Ранее я, как и многие, использовал PNG, не задумываясь о его развитии и различных редакциях. Углубившись в изучение спецификаций PNG (1996, 2003, 2025), я решил подготовить данную статью, чтобы обобщить ключевые изменения и их значение для веб-дизайна, разработки игр и мультимедиа. Статья не претендует на исчерпывающий охват, но стремится предоставить полезный обзор для всех заинтересованных, включая начинающих. Приветствуются любые замечания и предложения по улучшению материала в комментариях к публикации. Весь код, приведённый ниже, выложил в репозиторий. Надеюсь, чтение будет полезным и увлекательным.


Почему PNG стал заменой GIF?

Формат PNG (Portable Network Graphics) был создан в 1995 году как свободная альтернатива формату GIF (Graphics Interchange Format), который столкнулся с патентными ограничениями. GIF, разработанный CompuServe в 1987 году, был популярен в раннем интернете благодаря поддержке анимации и сжатия без потерь, но в 1994 году компания Unisys начала требовать роялти за использование алгоритма сжатия LZW (Lempel-Ziv-Welch), что вызвало протесты в сообществе разработчиков, включая кампанию «Burn All GIFs» в 1999 году («История формата PNG»). PNG предложил решение: патентно-чистое сжатие, прозрачность с альфа-каналом и поддержку миллионов цветов. Эта статья исследует эволюцию PNG от первой редакции 1996 года до третьей редакции 2025 года, сравнивая их технические особенности на примере логотипа — красного квадрата 50 x 50 пикселей на прозрачном фоне 100 x 100 пикселей — и предоставляя примеры на Python.

Проблема с GIF началась в 1993 году, когда Unisys, владеющая патентом на LZW (US Patent 4,558,302, 1985), объявила, что разработчики программ, использующих GIF, должны платить лицензионные отчисления. К декабрю 1994 года CompuServe, создатель GIF, подтвердила эти требования, что вызвало возмущение в сообществе. Веб-дизайнеры, использовавшие GIF для кнопок, иконок и простых анимаций, столкнулись с необходимостью искать альтернативу. Кампания «Burn All GIFs», запущенная 5 ноября 1999 года, призывала отказаться от GIF в знак протеста против патентных ограничений (PNG: The Definitive Guide, Chapter 7).

4 января 1995 года инженер Томас Бутелл опубликовал в группах Usenet, таких как comp.graphics и comp.compression, первый черновик нового формата, изначально названного PBF (Portable Bitmap Format). Сообщество активно участвовало в разработке, предложив ключевые особенности:

  • Сжатие DEFLATE: эффективный и патентно-чистый алгоритм, разработанный Жаном-Лу Гайи и Марком Адлером.

  • Прозрачность: альфа-канал для плавной прозрачности, в отличие от бинарной прозрачности GIF.

  • 24-битные цвета: поддержка 16,7 миллиона оттенков против 256 цветов в GIF.

  • Название PNG: предложено Оливером Фромме как «PNG’s Not GIF», подчёркивая свободу от патентов.

К 7 февраля 1995 года CompuServe объявила PNG преемником GIF. К 7 марта 1995 года, после девяти черновиков, спецификация была заморожена. 1 мая 1995 года вышли библиотеки zlib (для сжатия DEFLATE) и libpng (для работы с PNG), созданные Жаном-Лу Гайи, Марком Адлером и Гаем Эриком Шалнатом. 1 октября 1996 года PNG стал стандартом W3C, а к 1997 году его поддерживали браузеры, такие как Internet Explorer 4.0 и Netscape Navigator 4.04 («История формата PNG»).

DEFLATE против LZW: В чём разница?

Алгоритмы сжатия LZW и DEFLATE — это способы уменьшить размер файлов, сохраняя качество изображений. LZW, использованный в GIF, основан на создании словаря повторяющихся последовательностей символов, заменяя их короткими кодами. Например, если в изображении часто встречается последовательность «ABABAB», LZW заменяет её одним кодом, что экономит место. Однако LZW был запатентован Unisys, что ограничило его использование (Linux Journal: PNG — A Replacement for GIF).

DEFLATE, применённый в PNG, комбинирует два подхода: кодирование Хаффмана и сжатие LZ77. LZ77 ищет повторяющиеся последовательности в данных и заменяет их ссылками на предыдущие вхождения, а кодировка Хаффмана присваивает более короткие коды часто встречающимся символам. Это как упаковать чемодан: LZ77 складывает похожие вещи вместе, а Хаффман убирает лишние бирки, чтобы всё занимало меньше места. DEFLATE обычно обеспечивает лучшее сжатие (на 10–20% эффективнее LZW для изображений) и не имеет патентных ограничений, что сделало его идеальным для PNG (PNG FAQ).

PNG превзошёл GIF по нескольким параметрам. Например, для логотипа — красного квадрата на прозрачном фоне — GIF позволял сделать только один цвет полностью прозрачным, что часто приводило к рваным краям. PNG с альфа-каналом обеспечивал плавную прозрачность, создавая эффект стекла, и поддерживал 24-битные цвета, что давало миллионы оттенков вместо 256. DEFLATE также сжимал файлы эффективнее, сохраняя качество. Это сделало PNG стандартом для веб-графики, такой как логотипы на сайтах Yahoo или Netscape в 90-х (PNG Introduction).

PNG эволюционировал через три редакции. Первая (1996) поддерживала статические изображения с прозрачностью (W3C PNG Specification (First Edition, 1996)). Вторая (2003) улучшила управление цветами и добавила поддержку текстов UTF-8 (W3C PNG Specification (Second Edition, 2003)). Третья (2025) ввела HDR, анимации (APNG) и EXIF-метаданные, сделав PNG универсальным для веб-дизайна, фотографии и игр (W3C PNG Specification (Third Edition, 2025)). Эта статья покажет, как PNG изменился, используя пример логотипа — красного квадрата, превращающегося в анимацию, и предложит Python-код для создания таких изображений, чтобы любой мог применить новые возможности PNG.

Первая редакция (1996): простой формат для статичных изображений

Когда в 1996 году формат PNG (Portable Network Graphics) был официально стандартизирован консорциумом W3C, он стал ответом на потребность в свободной альтернативе GIF, ограниченному патентами на алгоритм LZW (W3C PNG Specification (First Edition, 1996)). Первая редакция PNG была разработана для создания статичных изображений с поддержкой прозрачности, сжатия без потерь и широкого диапазона цветов. Представьте PNG как коробку с инструментами, где каждый инструмент — это кусочек данных, помогающий собрать идеальную картинку. Эти кусочки называются чанками, и в этом разделе мы разберём, как они работали в первой редакции, используя пример простого логотипа — красного квадрата 50 x 50 пикселей на прозрачном фоне 100 x 100 пикселей.

Структура PNG: чанки как строительные блоки

PNG-файл — это как пазл, где каждый кусочек (чанк) отвечает за свою часть изображения. Чанки — это блоки данных, которые содержат информацию о размере, цветах, прозрачности или самих пикселях. В первой редакции PNG, опубликованной в 1996 году, были определены основные чанки, необходимые для создания статичных изображений (PNG: The Definitive Guide, Chapter 7). Вот ключевые чанки и их функции:

  • IHDR (Image Header): это как инструкция, где указано, какого размера картинка и как её собирать. IHDR задаёт ширину, высоту, глубину цвета, тип цвета, метод сжатия (всегда DEFLATE), метод фильтра (обычно 0) и метод чередования (0 для отсутствия чередования).

  • PLTE (Palette): если изображение использует ограниченное число цветов (до 256), PLTE хранит палитру как коробку с красками, где каждая краска — это три байта (R, G, B).

  • tRNS (Transparency): — определяет прозрачность, позволяя сделать части изображения, например фон, полностью или частично прозрачными.

  • bKGD (Background): задаёт цвет фона, который показывается, если прозрачность не поддерживается программой.

  • IDAT (Image Data): это сердце изображения, сжатые данные пикселей, использующие алгоритм DEFLATE.

  • IEND (Image End): пустой чанк, обозначающий конец файла, как последняя страница книги.

Для нашего логотипа — красного квадрата 200 x 200 пикселей на прозрачном фоне 400 x 400 пикселей — структура файла выглядит так:

  • IHDR: ширина = 400, высота = 400, глубина цвета = 8 бит, тип цвета = 6 (RGBA), метод сжатия = 0, метод фильтра = 0, метод чередования = 0.

  • tRNS: прозрачный фон (альфа-канал = 0 для пикселей фона).

  • IDAT: сжатые данные пикселей (красный квадрат: R = 255, G = 0, B = 0, A = 255; фон: A = 0).

  • IEND: конец файла.

Цветовые типы и глубина цвета

PNG поддерживает разные способы представления цветов, что делает его гибким для разных задач (PNG FAQ). Первая редакция определила пять цветовых типов:

  • Тип 0 (Grayscale): чёрно-белое изображение, где каждый пиксель — это оттенок серого. Глубина цвета может быть 1, 2, 4, 8 или 16 бит, позволяя использовать от 2 до 65 536 оттенков серого.

  • Тип 2 (RGB): полноцветное изображение, где каждый пиксель состоит из красного, зелёного и синего каналов (8 или 16 бит на канал).

  • Тип 3 (Indexed): использует палитру до 256 цветов, где каждый пиксель ссылается на индекс в палитре PLTE. Глубина цвета — 1, 2, 4 или 8 бит.

  • Тип 4 (Grayscale with Alpha): серое изображение с альфа-каналом для прозрачности, 8 или 16 бит на канал.

  • Тип 6 (RGBA): полноцветное изображение с альфа-каналом, 8 или 16 бит на канал.

Для нашего красного квадрата мы используем тип 6 (RGBA, 8 бит), где каждый пиксель — это 4 байта: красный ®, зелёный (G), синий (B) и альфа (A). Например, пиксель квадрата имеет значения (255, 0, 0, 255) — полностью непрозрачный красный, а пиксель фона — (0, 0, 0, 0) — полностью прозрачный. В сравнении с GIF, который ограничен 256 цветами и бинарной прозрачностью (цвет либо прозрачный, либо нет), PNG обеспечивает плавную прозрачность и миллионы цветов (16,7 миллиона для 24-битного RGB), что делает его идеальным для веб-графики (Linux Journal: PNG — A Replacement for GIF).

Прозрачность и сжатие в PNG

3
3

Для нашего красного квадрата мы используем тип 6 (RGBA, 8 бит), где каждый пиксель — это 4 байта: красный ®, зелёный (G), синий (B) и альфа (A). Например, пиксель квадрата имеет значения (255, 0, 0, 255) — полностью непрозрачный красный, а пиксель фона — (0, 0, 0, 0) — полностью прозрачный. В сравнении с GIF, который ограничен 256 цветами и бинарной прозрачностью (цвет либо прозрачный, либо нет), PNG обеспечивает плавную прозрачность и миллионы цветов (16,7 миллиона для 24-битного RGB), что делает его идеальным для веб-графики (Linux Journal: PNG — A Replacement for GIF).

Сжатие в PNG основано на алгоритме DEFLATE, который объединяет LZ77 и кодировку Хаффмана. LZ77 ищет повторяющиеся последовательности в данных и заменяет их ссылками на предыдущие вхождения, а Хаффман присваивает короткие коды часто встречающимся символам. Для нашего логотипа DEFLATE эффективно сжимает большие области прозрачного фона, так как они состоят из одинаковых значений (0, 0, 0, 0). В сравнении с LZW, используемым в GIF, DEFLATE обеспечивает на 10–20% лучшее сжатие для изображений с большими однотонными областями, сохраняя качество (PNG Introduction).

Пример: Создание и разбор PNG-файла

Давайте создадим наш логотип — красный квадрат 200x200 пикселей на прозрачном фоне 400x400 пикселей — с помощью Python и библиотеки Pillow. Этот пример покажет, как задать цвет и прозрачность, а затем мы разберём структуру файла с помощью библиотеки pypng.

Создание PNG с помощью Pillow:


from PIL import Image

# Создаём изображение 400x400 с прозрачным фоном
img = Image.new('RGBA',  (400,  400),  (0,  0,  0,  0))  # Прозрачный фон
# Добавляем красный квадрат 200x200 в центре
square = Image.new('RGBA',  (200,  200),  (255,  0,  0,  255))  # Красный, непрозрачный
img.paste(square,  (100,  100))  # Размещаем квадрат в координатах (100, 100)
img.save('out/red_square.png')

Этот код создаёт PNG-файл с красным квадратом. Структура файла будет включать:

  • IHDR: ширина = 400, высота = 400, глубина = 8 бит, тип = 6 (RGBA).

  • tRNS: указывает прозрачный фон (альфа = 0).

  • IDAT: сжатые данные пикселей, где квадрат — (255, 0, 0, 255), а фон — (0, 0, 0, 0).

  • IEND: конец файла.

Разбор структуры с помощью pypng:

import png


# Чтение PNG-файла
reader = png.Reader(filename='out/red_square.png')
png_data = reader.read()
print("IHDR:", png_data[3])  # Информация о заголовке
for chunk_type, chunk_data in reader.chunks():
print(f"Chunk: {chunk_type}, Length: {len(chunk_data)} bytes")

Этот код выводит структуру файла:

IHDR: {'greyscale': False, 'alpha': True, 'planes': 4, 'bitdepth': 8, 'interlace': 0, 'size': (400, 400)}
Chunk: b'IDAT', Length: 1056 bytes
Chunk: b'IEND', Length: 0 bytes

Показывая, какие чанки присутствуют и их размер. Например, для нашего логотипа вы увидите IHDR, IDAT и IEND, а tRNS может быть добавлен для прозрачности. Тестовые изображения из PNG Suite (PNG Suite) подтверждают, что такие файлы корректно отображаются в браузерах, с плавной прозрачностью на любом фоне.

Ограничения первой редакции

Первая редакция PNG была мощным шагом вперёд по сравнению с GIF, но имела ограничения:

  • Отсутствие анимации: PNG поддерживал только статичные изображения, в отличие от GIF, который мог создавать простые анимации, например, мигающие баннеры.

  • Нет HDR: Глубина цвета (8 или 16 бит на канал) не позволяла создавать изображения с расширенным динамическим диапазоном, как в современных дисплеях.

  • Минимальные метаданные: Чанки tEXt и zTXt поддерживали только простые текстовые данные, такие как автор или описание, но не сложные метаданные, например, EXIF для фотографий.

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

Первая редакция PNG заложила фундамент для веб-дизайна конца 90-х. Её поддержка в браузерах, таких как Internet Explorer 4.0, сделала PNG стандартом для логотипов и иконок с прозрачным фоном. Например, логотип Yahoo в 1997 году мог быть создан в PNG, чтобы выглядеть гладко на любом фоне сайта. Первая редакция означала переход от ограничений GIF к более гибкому формату, который обеспечивал лучшее сжатие и качество. Этот раздел подготовит читателя к сравнению с последующими редакциями, где были добавлены новые возможности, такие как анимация и HDR.

Вторая редакция (2003): умный формат с точными цветами

Вторая редакция PNG, опубликованная W3C 10 ноября 2003 года, сделала формат более универсальным, добавив новые возможности для управления цветом и хранения текстовых метаданных (W3C PNG Specification (Second Edition, 2003)). Если первая редакция PNG была базовым инструментом для создания статичных изображений с прозрачностью, то вторая редакция усовершенствовала его, добавив поддержку точной цветопередачи и интернационализации текстов. Это как если бы набор инструментов для рисования картинок получил новые краски, которые выглядят одинаково на всех экранах, и возможность подписывать изображения на любом языке мира. В этом разделе мы разберём новые чанки (iCCP, sRGB, iTXt), их применение на примере логотипа — красного квадрата 200 x 200 пикселей на прозрачном фоне 400 x 400 пикселей — и покажем, как можно использовать эти функции с помощью Python.

Новые чанки: iCCP, sRGB, iTXt

Вторая редакция PNG ввела три новых чанка, которые значительно расширили возможности формата (PNG: The Definitive Guide, Chapter 7):

  • iCCP (Embedded ICC Profile): Этот чанк хранит профиль цвета по стандарту ICC (International Color Consortium), который указывает, как должны отображаться цвета на разных устройствах, таких как мониторы, принтеры или смартфоны. Без цветового профиля красный цвет в нашем логотипе может выглядеть оранжевым на одном экране и бордовым на другом. iCCP решает эту проблему, добавляя инструкцию, как правильно интерпретировать цвета.

  • sRGB (Standard RGB): Указывает, что изображение использует стандартное цветовое пространство sRGB, широко применяемое в веб-браузерах и цифровых устройствах. Это упрощает отображение цветов, так как большинство устройств оптимизированы для sRGB.

  • iTXt (International Text): Позволяет хранить текстовые метаданные в формате UTF-8, с поддержкой сжатия и языковых тегов. В отличие от чанков tEXt и zTXt из первой редакции, iTXt поддерживает тексты на любом языке, например, русском или китайском, и может быть сжат для экономии места.

Представьте, что iCCP и sRGB — это как инструкция для художника, чтобы он использовал правильные оттенки красок, а iTXt — это записка, которую можно написать на любом языке, чтобы рассказать, кто создал картинку или что она означает.

Улучшения в управлении цветом

Управление цветом стало ключевым улучшением второй редакции. В первой редакции (1996) PNG не содержал информации о том, как должны отображаться цвета на разных устройствах, что приводило к искажениям. Например, красный квадрат в нашем логотипе (R=255, G=0, B=0) мог выглядеть по-разному на мониторе и в печати из-за отсутствия цветового профиля (Linux Journal: PNG — A Replacement for GIF). Чанк iCCP решает эту проблему, включая профиль ICC, который описывает цветовое пространство, например, sRGB или Adobe RGB. Это гарантирует, что красный цвет логотипа будет одинаковым в браузерах Firefox, Safari или на печатной странице.

Чанк sRGB — это упрощённый способ указать, что изображение создано в стандартном цветовом пространстве sRGB, которое поддерживается большинством веб-браузеров и устройств. Для веб-дизайнеров это означало, что логотипы и иконки, созданные в PNG, будут отображаться корректно без дополнительных настроек. Например, наш красный квадрат с sRGB будет выглядеть одинаково на сайте, открытом на ноутбуке или смартфоне, что было особенно важно для международных проектов в 2000-х годах.

Поддержка текстов с iTXt

Чанк iTXt сделал PNG более подходящим для международных приложений. В первой редакции чанки tEXt и zTXt поддерживали только простые текстовые метаданные в формате ISO 8859-1, что ограничивало использование не-латинских символов, таких как кириллица или иероглифы. iTXt, напротив, использует UTF-8, что позволяет добавлять тексты на любом языке, например, «Автор: Иван Иванов» на русском или «描述: 红色正方形» на китайском. Кроме того, iTXt поддерживает сжатие и языковые теги, указывающие, на каком языке написан текст (PNG FAQ).

Для нашего логотипа iTXt можно использовать, чтобы добавить метаданные, такие как:

  • «Author: Ivan Ivanov» (на английском, тег языка: en).

  • «Автор: Иван Иванов» (на русском, тег языка: ru).

  • «Created: 2003-11-10» (дата создания).

Это делает PNG удобным для хранения подписей, комментариев или описаний, особенно для международных сайтов или программ.

Пример: Создание PNG с iCCP и iTXt

Давайте создадим тот же логотип — красный квадрат 200x200 пикселей на прозрачном фоне 400x400 пикселей — с использованием новых чанков второй редакции. Мы добавим профиль sRGB (через iCCP) и метаданные iTXt с помощью Python и библиотек Pillow и pypng.

Создание PNG с iCCP и iTXt:

from PIL import Image, ImageCms, PngImagePlugin
import png
import numpy as np
  

# Создаём изображение 400x400 с прозрачным фоном
img = Image.new('RGBA',  (400,  400),  (0,  0,  0,  0))  # Прозрачный фон
square = Image.new('RGBA',  (200,  200),  (255,  0,  0,  255))  # Красный квадрат
img.paste(square,  (100,  100))  # Размещаем квадрат в центре
profile = ImageCms.getOpenProfile("/usr/share/color/icc/colord/sRGB.icc")
img.save('out/red_square_srgb.png',  icc_profile=profile.tobytes())

# Добавляем iTXt с помощью pypng
reader = png.Reader(filename='out/red_square_srgb.png')
width, height, rows, info = reader.read()
# Преобразуем итератор строк в numpy-массив
rows_list =  list(rows)
arr = np.vstack(rows_list).astype(np.uint8)

# Для RGBA нужно reshape с учетом количества каналов
channels = info['planes']  # например, 4 для RGBA
arr = arr.reshape((height, width, channels))

# Создаем изображение Pillow из массива
mode =  'RGBA'  if channels ==  4  else  'RGB'
img = Image.fromarray(arr,  mode=mode)

# Создаем объект метаданных и добавляем iTXt
meta = PngImagePlugin.PngInfo()
meta.add_itxt("Author",  "Ivan Ivanov",  lang="en",  tkey="Author")
 
# Сохраняем в новый файл с метаданными
img.save('out/red_square_itxt.png',  icc_profile=profile.tobytes(),  pnginfo=meta)

Этот код создаёт PNG-файл с профилем sRGB (через iCCP) и метаданными iTXt, указывающими автора. Структура файла будет такой:

  • IHDR: ширина = 400, высота = 400, глубина = 8 бит, тип = 6 (RGBA).

  • iCCP: профиль sRGB для точной цветопередачи.

  • iTXt: метаданные, например, «Author: Ivan Ivanov» (язык: en).

  • IDAT: сжатые данные пикселей (красный квадрат: R = 255, G = 0, B = 0, A = 255).

  • IEND: конец файла.

Чтение чанков для проверки:

import png  # Установите: pip install pypng

def read_png_metadata(filename):
    reader = png.Reader(filename=filename)
    chunks = reader.chunks()
    for chunk_type, chunk_data in chunks:
        print(f"Тип: {chunk_type}, Длина: {len(chunk_data)}")
        if chunk_type == b'iTXt':
            print(";".join(
                data for data in chunk_data.decode('latin1').split("\x00") if data
                ))

# Пример использования
read_png_metadata('out/red_square_itxt.png')

Этот код выводит структуру файла

Тип: b'IHDR', Длина: 13
Тип: b'iCCP', Длина: 6817
Тип: b'iTXt', Длина: 30
Author;en;Author;Ivan Ivanov
Тип: b'IDAT', Длина: 1056
Тип: b'IEND', Длина: 0

Показывая наличие iCCP и iTXt. Тестовые изображения из PNG Suite (PNG Suite) подтверждают, что такие файлы корректно отображаются в браузерах, таких как Firefox 3.0 (2008), с правильной цветопередачей.

Сравнение с первой редакцией

Вторая редакция значительно улучшила PNG по сравнению с первой:

  • Цветопередача: iCCP и sRGB обеспечивают одинаковое отображение цветов на разных устройствах, что было невозможно в 1996 году.

  • Интернационализация: iTXt позволяет добавлять метаданные на любом языке, в отличие от ограниченных tEXt/zTXt.

  • Совместимость: Файлы второй редакции читаются программами, поддерживающими первую редакцию, так как новые чанки (iCCP, sRGB, iTXt) являются необязательными (W3C PNG Specification (Second Edition, 2003)).

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

Ограничения второй редакции

Несмотря на улучшения, вторая редакция имела ограничения:

  • Отсутствие анимации: Официально PNG не поддерживал анимации. APNG, предложенный в 2004 году, оставался неофициальным расширением (APNG Specification).

  • Нет HDR: Глубина цвета (8 или 16 бит на канал) не позволяла создавать изображения с расширенным динамическим диапазоном.

  • Нет EXIF: Метаданные ограничивались текстовыми чанками (iTXt, tEXt, zTXt), без поддержки сложных стандартов, таких как EXIF для фотографий.

Эти ограничения делали PNG менее подходящим для анимаций или профессиональной фотографии, но идеальным для веб-дизайна и печати.

Вторая редакция PNG сделала формат стандартом для веб-дизайна и печати в 2000-х годах. Чанки iCCP и sRGB обеспечили точную цветопередачу, что было критично для создания логотипов и графики, выглядящих одинаково в браузерах, таких как Firefox и Safari, или на печатных материалах. iTXt упростил добавление метаданных для международных проектов, например, подписей к изображениям на разных языках. Это означало возможность создавать универсальные изображения, подходящие для глобальных сайтов и приложений. Этот раздел подготовит читателя к третьей редакции, где были добавлены поддержка анимации (APNG) и HDR.

Третья редакция (2025): Революционные изменения

Третья редакция PNG, опубликованная W3C 24 июня 2025 года, превратила формат в универсальный инструмент для современных технологий, добавив поддержку HDR (High Dynamic Range), стандартизировав анимации APNG и внедрив метаданные EXIF (W3C PNG Specification (Third Edition, 2025)). Эти изменения сделали PNG идеальным для веб-дизайна, игр, профессиональной фотографии и мультимедиа. Представьте PNG как швейцарский нож для изображений: он теперь умеет создавать яркие картинки, анимации и хранить историю снимков. В этом разделе мы разберём новые чанки (mDCV, cLLI, cICP, acTL, fcTL, fdAT, eXIf), их применение на примере анимированного логотипа — красного квадрата 200 x 200 пикселей на прозрачном фоне 400 x 400 пикселей, меняющего цвета и движущегося, — и покажем, как можно использовать эти функции с помощью Python.

Новые чанки третьей редакции

Третья редакция ввела чанки, которые радикально расширили возможности PNG:

  • HDR-чанки:

  • mDCV (Mastering Display Color Volume): Хранит данные о цветовом объёме и яркости (12 байт для цветового пространства, 4 байта для максимальной яркости). Это позволяет изображению выглядеть реалистично на HDR-дисплеях, таких как 4K-телевизоры.

  • cLLI (Content Light Level Info): Указывает максимальную (MaxCLL, 4 байта) и среднюю (MaxFALL, 4 байта) яркость, обеспечивая оптимальное отображение на устройствах с разной яркостью.

  • cICP (Critical ICC Profile): Упрощённый профиль цвета для HDR, оптимизированный для современных дисплеев, таких как OLED.

  • APNG-чанки:

  • acTL (Animation Control): Указывает количество кадров и число повторов анимации (например, бесконечный цикл).

  • fcTL (Frame Control): Определяет размер, позицию, задержку и метод наложения для каждого кадра.

  • fdAT (Frame Data): Содержит сжатые данные каждого кадра анимации, аналогично IDAT (APNG Specification).

  • eXIf (EXIF Metadata): Хранит метаданные, такие как дата съёмки, модель камеры или геолокация, в формате, совместимом с JPEG.

Эти чанки можно сравнить с инструментами: mDCV и cLLI настраивают изображение для ярких дисплеев, acTL и fcTL задают сценарий для анимации, а eXIf записывает историю изображения, как дневник.

HDR: яркие изображения для современных устройств

Поддержка HDR в третьей редакции позволяет PNG создавать изображения с расширенным динамическим диапазоном, используя 16 бит на канал и широкий цветовой охват. Это делает картинки яркими и реалистичными, как на современных телевизорах или игровых мониторах. Например, наш красный квадрат в HDR-режиме может иметь более насыщенный цвет и яркость, которые подстраиваются под дисплей, создавая эффект, будто квадрат светится. Это особенно важно для игр, где HDR усиливает визуальные эффекты, или для фотографии, где требуется точная передача света и теней (PNG News). В отличие от первой и второй редакций, ограниченных 8 или 16 битами без HDR, третья редакция поддерживает стандарты, такие как Rec. 2020, для современных устройств.

APNG: стандартизация анимаций

APNG (Animated PNG), впервые предложенный в 2004 году как неофициальное расширение, стал стандартом в третьей редакции. APNG поддерживает анимации с миллионами цветов и альфа-каналом, превосходя GIF по качеству и сжатию. Например, анимация, где наш красный квадрат меняет цвета (красный, зелёный, синий) и движется по диагонали, будет выглядеть плавно и ярко, с прозрачным фоном. APNG используется в мессенджерах, таких как Telegram, для стикеров или в веб-дизайне для анимированных иконок. Чанки acTL, fcTL и fdAT позволяют точно управлять кадрами, задавая задержку и позиции (APNG Specification).

EXIF: метаданные для фотографий

Чанк eXIf позволяет хранить метаданные, аналогичные JPEG, такие как дата съёмки, модель камеры или геолокация. Это делает PNG подходящим для профессиональной фотографии, где важно сохранять информацию о снимке. Например, к нашему логотипу можно добавить eXIf с данными «Дата: 2025-01-01» или «Автор: Иван Иванов». В отличие от iTXt, eXIf использует стандартизированный формат, что упрощает интеграцию с фоторедакторами, такими как Adobe Photoshop.

Пример: создание анимированного HDR PNG с EXIF

Давайте создадим анимацию APNG, где красный квадрат меняет цвета (красный, зелёный, синий) и движется по диагонали, с HDR-эффектами и EXIF-метаданными, используя Python и библиотеки pyAPNG, Pillow и imageio.

Создание APNG с pyAPNG:

from PIL import Image
from apng import APNG
import numpy as np

# Создаём три кадра 400x400 с движущимся квадратом
frames = []
colors = [(255, 0, 0, 255), (0, 255, 0, 255), (0, 0, 255, 255)]  # Красный, зелёный, синий
positions = [(100, 100), (150, 150), (200, 200)]  # Движение по диагонали

for i in range(3):
    frame = Image.new('RGBA', (400, 400), (0, 0, 0, 0))  # Прозрачный фон
    frame.paste(Image.new('RGBA', (200, 200), colors[i]), positions[i])  # Квадрат
    frame.save(f'out/frame{i}.png')
    frames.append(f'out/frame{i}.png')

# Создаём APNG
apng = APNG()
for frame in frames:
    apng.append_file(frame, delay=100)  # Задержка 100 мс
apng.save('out/moving_square.apng')

Добавление EXIF с Pillow и apng:

from PIL import Image
import apng
from io import BytesIO
import os

# 1. Создаём папку для временных файлов
os.makedirs("out/temp_frames", exist_ok=True)

# 2. Читаем APNG
png = apng.APNG.open("out/moving_square.apng")

# 3. Обрабатываем каждый кадр
for i, (png_frame, control) in enumerate(png.frames):
    img = Image.open(BytesIO(png_frame.to_bytes()))  # Конвертируем в PIL.Image

    # Добавляем EXIF
    exif = img.getexif()
    exif[0x0132] = '2025:01:01 12:00:00'  # DateTime
    exif[0x010f] = 'HelloHabr'  # Author

    # Сохраняем кадр
    # Сохраняем кадр во временный файл
    frame_path = f"out/temp_frames/frame_{i}.png"
    img.save(frame_path, exif=exif)

# 4. Собираем обратно в APNG (с сохранением задержек)
output_files = []
for i, (_, control) in enumerate(png.frames):
    frame_path = f"out/temp_frames/frame_{i}.png"
    output_files.append((frame_path, control.delay))  # Кортеж (путь, задержка)

apng = apng.APNG()
for file, delay in output_files:
    apng.append_file(file, delay=delay)  # Задержка 100 мс
apng.save('out/moving_square_with_exif.apng')
# 5. Удаляем временные файлы (опционально)
for i in range(len(png.frames)):
    os.remove(f"out/temp_frames/frame_{i}.png")
os.rmdir("out/temp_frames")

Синтетический HDR с imageio:

import imageio.v3 as iio
import numpy as np
from PIL import Image

# 1. Создаём синтетическое HDR-изображение (400x400 пикселей, 3 канала)
hdr_image = np.random.rand(400, 400, 3).astype(np.float32) * 10.0  # Яркость до 10 нит

# 2. Конвертируем в 16-битный формат
max_val = np.max(hdr_image)
normalized = hdr_image / max_val  # Нормализуем в [0, 1]
uint16_image = (normalized * 65535).astype(np.uint16)  # Конвертируем в uint16

# 3. Меняем порядок каналов для Pillow (RGB -> PIL-совместимый формат)
#    Pillow ожидает (height, width, channels) -> (100, 100, 3)
if uint16_image.shape[-1] == 3:  # Если последняя размерность - каналы
    uint16_image = np.ascontiguousarray(uint16_image)  # Делаем массив непрерывным

# 4. Сохраняем через Pillow с явным указанием режима
with Image.fromarray(uint16_image, mode='RGB') as img:
    img.save('out/hdr_square.png', bitdepth=16)

# 5. Проверка
read_hdr = iio.imread('out/hdr_square.png')
print(f"Image shape: {read_hdr.shape}, dtype: {read_hdr.dtype}")

Примечание: Добавление специфических чанков mDCV, cLLI, cICP требует низкоуровневой работы с pypng, так как стандартные библиотеки (Pillow, imageio) пока не полностью поддерживают HDR-чанки третьей редакции.

Пример ниже показывает, как добавить mDCV вручную:

import zlib
import struct
import png  # pip install pypng

def add_mdcv_chunk(input_path, output_path):
    # Читаем исходный PNG
    reader = png.Reader(filename=input_path)
    chunks = list(reader.chunks())  # Получаем все чанки

    # Создаем данные для mDCV чанка (6 float + 1 uint32)
    mdcv_data = struct.pack('>6fI',
        0.708, 0.292,  # Красный
        0.170, 0.797,  # Зеленый
        0.131, 0.046,  # Синий
        1000           # Максимальная яркость в нитах
    )

    # Вычисляем CRC для mDCV чанка
    chunk_type = b'mDCV'
    crc = zlib.crc32(chunk_type + mdcv_data) & 0xffffffff

    # Создаем кортеж чанка (тип, данные)
    mdcv_chunk = (chunk_type, mdcv_data)

    # Вставляем после IHDR (позиция 1)
    chunks.insert(1, mdcv_chunk)

    # Записываем новый файл
    with open(output_path, 'wb') as f:
        # Сигнатура PNG
        f.write(b'\x89PNG\r\n\x1a\n')

        # Записываем все чанки с правильными CRC
        for chunk_type, chunk_data in chunks:
            # Длина данных
            f.write(struct.pack('>I', len(chunk_data)))
            # Тип чанка
            f.write(chunk_type)
            # Данные
            f.write(chunk_data)
            # CRC (пересчитываем для всех чанков)
            crc = zlib.crc32(chunk_type + chunk_data) & 0xffffffff
            f.write(struct.pack('>I', crc))

# Пример использования
add_mdcv_chunk('out/red_square.png', 'out/red_square_hdr.png')

Этот код создаёт анимированный PNG с тремя кадрами, добавляет EXIF-метаданные и синтетическое HDR-изображение. Структура файла включает:

  • IHDR: Ширина = 100, Высота = 100, Глубина = 16 бит, Тип = 6 (RGBA).

  • mDCV, cLLI, cICP: HDR-данные (цветовой объём, яркость).

  • acTL: 3 кадра, бесконечный цикл.

  • fcTL: Задержка 100 мс, позиции (25,25), (35,35), (45,45).

  • fdAT: Данные кадров.

  • eXIf: Метаданные («Дата: 2025-01-01»).

  • IDAT, IEND: Данные первого кадра и конец файла.

Тестовые изображения из PNG Suite (PNG Suite) подтверждают корректное отображение APNG в браузерах, таких как Chrome, и HDR на современных дисплеях.

Сравнение с предыдущими редакциями

Третья редакция сделала PNG универсальным:

  • HDR: Первая и вторая редакции ограничены 8/16 битами без поддержки расширенного диапазона яркости.

  • APNG: Первая редакция не поддерживала анимации, вторая — только неофициально через APNG.

  • EXIF: Ранее метаданные ограничивались текстовыми чанками (tEXt, zTXt, iTXt).

  • Совместимость: Новые чанки (mDCV, cLLI, cICP, eXIf) игнорируются старыми программами, обеспечивая обратную совместимость.

Например, наш анимированный логотип с HDR и EXIF невозможен в первых двух редакциях, так как они не поддерживают анимацию и расширенные метаданные.

Влияние: веб, игры, фотография

Третья редакция открыла новые возможности:

  • Веб-дизайн: APNG используется для анимированных стикеров в мессенджерах (например, Telegram) или иконок на сайтах, превосходя GIF по качеству.

  • Игры: HDR-изображения усиливают визуальные эффекты на современных дисплеях, таких как игровые мониторы с поддержкой Rec. 2020.

  • Фотография: eXIf делает PNG альтернативой JPEG для хранения профессиональных снимков с метаданными.

Эти изменения закрепили PNG как формат будущего, способный конкурировать с JPEG, WebP и AVIF. Следующий раздел покажет, как можно реализовать эти возможности на Python.

Практический пример: создаём переливающийся и крутящийся логотип «PNG» на Python

Python — универсальный инструмент для создания креативных изображений в формате PNG, от статичных логотипов до анимированных стикеров с HDR-эффектами. Благодаря библиотекам Pillow, pyAPNG, imageio и pypng, разработчики могут реализовать возможности всех трёх редакций PNG (1996, 2003, 2025). В этом разделе мы создадим анимированный логотип с текстом «PNG» (шрифт Arial, размер 30) на прозрачном фоне 100x100 пикселей, который переливается цветами (градиент от красного к синему через зелёный) и вращается на 360 градусов. Представьте Python как анимационную студию, где чанки PNG — это кадры фильма, создающие визуальные эффекты. Эти примеры помогут применять PNG в веб-дизайне, мессенджерах и играх (PNG FAQ).

Дополнительный пример: создание анимированного логотипа «PNG» с переливанием и вращением (третья редакция, 2025)

Теперь создадим APNG с логотипом «PNG», который переливается цветами (градиент от красного к синему через зелёный) и вращается на 360 градусов за 6 кадров. Все размеры соответствуют актуальному коду.

Код для создания APNG с градиентом и вращением:

from PIL import Image, ImageDraw, ImageFont
from apng import APNG
import os

# Конфигурация анимации
WIDTH, HEIGHT = 400, 400
FRAME_COUNT = 6
DELAY_MS = 100  # Задержка между кадрами в миллисекундах
OUTPUT_FILE = 'out/logo_png_animated.apng'

# Цвета для каждого кадра
COLORS = [
    (255, 0, 0, 255),    # Красный
    (255, 255, 0, 255),  # Жёлтый
    (0, 255, 0, 255),    # Зелёный
    (0, 255, 255, 255),  # Циан
    (0, 0, 255, 255),    # Синий
    (255, 0, 255, 255)   # Пурпурный
]

def create_animation():
    # Создаём временную папку для кадров
    os.makedirs('out/temp_frames', exist_ok=True)

    # Генерируем кадры
    frame_files = []
    for i in range(FRAME_COUNT):
        angle = i * (360 / FRAME_COUNT)
        color = COLORS[i]

        # Создаём прозрачное изображение
        img = Image.new('RGBA', (WIDTH, HEIGHT), (0, 0, 0, 0))

        # Пытаемся загрузить шрифт (с fallback)
        try:
            font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf', 120)
        except Exception:
            font = ImageFont.load_default()

        # Создаём текст на отдельном изображении для вращения
        text_img = Image.new('RGBA', (WIDTH, HEIGHT), (0, 0, 0, 0))
        text_draw = ImageDraw.Draw(text_img)
        text_draw.text((80, 140), "PNG", font=font, fill=color)

        # Вращаем текст вокруг центра
        rotated = text_img.rotate(angle, center=(WIDTH//2, HEIGHT//2))

        # Комбинируем изображения
        img.paste(rotated, (0, 0), rotated)

        # Сохраняем кадр
        frame_path = f'out/temp_frames/frame_{i:02d}.png'
        try:
            img.save(frame_path)
            frame_files.append(frame_path)
        except Exception as e:
            print(f"Ошибка при сохранении кадра {frame_path}: {e}")

    # Создаём APNG
    try:
        apng = APNG()
        for frame in frame_files:
            apng.append_file(frame, delay=DELAY_MS)
        apng.save(OUTPUT_FILE)
        print(f"Анимация успешно сохранена как {OUTPUT_FILE}")
    except Exception as e:
        print(f"Ошибка при создании APNG: {e}")
    finally:
        # Удаляем временные файлы с обработкой ошибок
        for frame in frame_files:
            try:
                os.remove(frame)
            except OSError as e:
                print(f"Не удалось удалить файл {frame}: {e}")

        try:
            os.rmdir('out/temp_frames')
        except OSError as e:
            print(f"Не удалось удалить директорию temp_frames: {e}")

if __name__ == "__main__":
    create_animation()

В этой анимации:

  • Каждый кадр — 400x400 пикселей

  • Текст “PNG” — шрифт 120, координаты (80, 140)

  • Цвета: красный, жёлтый, зелёный, циан, синий, пурпурный

  • Вращение текста по кругу

Дополнительный пример 2: создание анимированного RGB куба (третья редакция, 2025):

import asyncio
import math
import numpy as np
from PIL import Image
from io import BytesIO
from apng import APNG, PNG
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *

# Константы
FPS = 60
cubeWidth = 10  # Масштаб куба
width, height = 800, 600  # Размер окна
distanceFromCam = 50  # Расстояние камеры
K1 = 40  # Коэффициент проекции
A, B, C = 0.0, 0.0, 0.0  # Углы вращения
background_alpha = 0.0  # Прозрачность фона (0.0 - полностью прозрачный, 1.0 - полностью непрозрачный)

def calculateX(i, j, k):
    return j * math.sin(A) * math.sin(B) * math.cos(C) - k * math.cos(A) * math.sin(B) * math.cos(C) + \
           j * math.cos(A) * math.sin(C) + k * math.sin(A) * math.sin(C) + i * math.cos(B) * math.cos(C)

def calculateY(i, j, k):
    return j * math.cos(A) * math.cos(C) + k * math.sin(A) * math.cos(C) - \
           j * math.sin(A) * math.sin(B) * math.sin(C) + k * math.cos(A) * math.sin(B) * math.sin(C) - \
           i * math.cos(B) * math.sin(C)

def calculateZ(i, j, k):
    return k * math.cos(A) * math.cos(B) - j * math.sin(A) * math.cos(B) + i * math.sin(B)

def Cube():
    glBegin(GL_QUADS)
    for i, surface in enumerate(surfaces):
        for vertex in surface:
            x, y, z = vertices[vertex]
            # Применяем вращение через calculateX/Y/Z
            rotated_x = calculateX(x, y, z)
            rotated_y = calculateY(x, y, z)
            rotated_z = calculateZ(x, y, z)
            # Динамическое изменение цвета с градиентом
            base_color = ((x / cubeWidth + 1) / 2, (z / cubeWidth + 1) / 2, (y / cubeWidth + 1) / 2)
            gradient = (i / len(surfaces))
            color = (
                base_color[0] * (1 - gradient) + gradient * 0.5,
                base_color[1] * (1 - gradient) + gradient * 0.5,
                base_color[2] * (1 - gradient) + gradient * 0.3
            )
            glColor3fv(color)
            glVertex3fv((rotated_x, rotated_y, rotated_z))
    glEnd()

# Вершины куба с координатами (x, y, z) в диапазоне [-cubeWidth, cubeWidth]
vertices = (
    (cubeWidth, -cubeWidth, -cubeWidth),  # 0: лево, верх, низ
    (cubeWidth, cubeWidth, -cubeWidth),   # 1: лево, низ, низ
    (-cubeWidth, cubeWidth, -cubeWidth),  # 2: право, низ, низ
    (-cubeWidth, -cubeWidth, -cubeWidth), # 3: право, верх, низ
    (cubeWidth, -cubeWidth, cubeWidth),   # 4: лево, верх, верх
    (cubeWidth, cubeWidth, cubeWidth),    # 5: лево, низ, верх
    (-cubeWidth, cubeWidth, cubeWidth),   # 6: право, низ, верх
    (-cubeWidth, -cubeWidth, cubeWidth),  # 7: право, верх, верх
)

# Грани куба (каждая — 4 вершины)
surfaces = (
    (0, 1, 2, 3),  # Нижняя грань
    (4, 5, 6, 7),  # Верхняя грань
    (0, 4, 5, 1),  # Левая грань
    (3, 7, 6, 2),  # Правая грань
    (1, 5, 6, 2),  # Задняя грань
    (0, 4, 7, 3),  # Передняя грань
)

async def main():
    pygame.init()
    display = (width, height)
    pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
    pygame.display.set_caption("RGB Cube - axes: R left, G up, B bottom-right")

    # Настройка проекции
    gluPerspective(60, (width / height), 0.1, 200.0)  # Адаптировано под distanceFromCam=50
    glTranslatef(0.0, 0.0, -distanceFromCam)
    glEnable(GL_DEPTH_TEST)
    glClearColor(0.1, 0.1, 0.1, background_alpha)

    frames = []
    num_frames = 1000  # количество кадров для плавности

    for frame_idx in range(num_frames):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        glPushMatrix()
        # Обновление углов вращения с меньшим шагом
        global A, B
        A += 0.0025  # Уменьшен шаг для медленного вращения
        B += 0.0025
        C = 0.0

        Cube()

        glPopMatrix()

        # Сохранение кадра
        data = glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE)
        pil_frame = Image.frombytes('RGBA', (width, height), data).transpose(Image.FLIP_TOP_BOTTOM)
        buf = BytesIO()
        pil_frame.save(buf, format='PNG')
        buf.seek(0)
        png_frame = PNG.from_bytes(buf.read())
        frames.append(png_frame)

        await asyncio.sleep(1.0 / FPS)  # Контроль частоты кадров

    # Сохранение анимации в APNG
    apng = APNG()
    for png_frame in frames:
        apng.append(png_frame, delay=1000 // FPS)  # Задержка 16.67 мс (60 FPS)
    apng.save('out/spinning_cube.apng')

    pygame.quit()

if __name__ == "__main__":
    asyncio.run(main())
это похожий пример того что получиться, а результат кода будет немного отличаться, но по сути похож, из-за большого веса получившегося файла приложить его не смог.
это похожий пример того что получиться, а результат кода будет немного отличаться, но по сути похож, из-за большого веса получившегося файла приложить его не смог.

Сравнительный анализ

Формат PNG эволюционировал от простого заменителя GIF в 1996 году до универсального инструмента для веб-дизайна, игр и фотографии в 2025 году. Каждая из трёх редакций PNG (1996, 2003, 2025) добавляла новые возможности, делая формат всё более гибким. Сравнение этих редакций поможет выбрать подходящую версию для конкретных задач, будь то создание статичного логотипа, анимации или HDR-графики. Представьте выбор редакции PNG как выбор инструмента в мастерской: каждый хорош для своей цели. В этом разделе мы сравним технические характеристики редакций, выделим их преимущества и ограничения, и дадим рекомендации по применению, используя пример анимированного логотипа «PNG» с переливанием цветов и вращением (PNG FAQ).

Сравнение редакций: технические характеристики

Каждая редакция PNG расширяла возможности формата, добавляя новые чанки и функции. Ниже приведена таблица сравнения, основанная на спецификациях W3C (W3C PNG Specification (First Edition, 1996), Second Edition, 2003, Third Edition, 2025).

Характеристика

Чанки

Цветовые типы

Глубина цвета

Прозрачность

Анимация

Управление цветом

Метаданные

Первая редакция (1996)

IHDR, PLTE, tRNS, bKGD, IDAT, IEND, tEXt, zTXt

Grayscale, RGB, Indexed, Grayscale+Alpha, RGBA

1, 2, 4, 8, 16 бит

Бинарная (tRNS), альфа-канал

Не поддерживается

DEFLATE (LZ77 + Хаффман)

tEXt, zTXt (ISO 8859-1)

Вторая редакция (2003)

+ iCCP, sRGB, iTXt

Без изменений

Без изменений

Без изменений

Не поддерживается (APNG неофициально)

iCCP, sRGB

iTXt (UTF-8, интернационализация)

Третья редакция (2025)

+ mDCV, cLLI, cICP, acTL, fcTL, fdAT, eXIf

Добавлен HDR (16 бит)

8, 16 бит, оптимизация для HDR

Без изменений, улучшено для APNG

Поддерживается (APNG: acTL, fcTL, fdAT)

+ mDCV, cLLI, cICP (HDR)

+ eXIf (стандарт JPEG)

Преимущества и ограничения каждой редакции

Первая редакция (1996) (PNG Introduction):

  • Преимущества:

  • Простота и совместимость с ранними браузерами (Netscape Navigator 4.04).

  • Прозрачность с альфа-каналом, превосходящая бинарную прозрачность GIF.

  • Эффективное сжатие DEFLATE, лучше LZW на 10–20%.

  • Подходит для простых логотипов и иконок.

  • Ограничения:

  • Только статичные изображения.

  • Нет управления цветом (искажения на разных устройствах).

  • Ограниченные метаданные (tEXt/zTXt, только ISO 8859-1).

Вторая редакция (2003):

  • Преимущества:

  • Точная цветопередача благодаря iCCP и sRGB, идеально для веб-дизайна и печати.

  • Многоязычные метаданные (iTXt, UTF-8) для международных проектов.

  • Полная совместимость с первой редакцией.

  • Ограничения:

  • Нет официальной поддержки анимации (APNG только неофициально).

  • Отсутствие HDR и сложных метаданных (EXIF).

Третья редакция (2025):

  • Преимущества:

  • Поддержка HDR (mDCV, cLLI, cICP) для ярких изображений на современных дисплеях.

  • Стандартизированная анимация (APNG) с миллионами цветов и альфа-каналом.

  • EXIF для профессиональной фотографии (дата, камера, геолокация).

  • Универсальность для веб, игр и мультимедиа.

  • Ограничения:

  • Сложность реализации (HDR-чанки требуют обновления библиотек).

  • Ограниченная поддержка HDR в текущих инструментах (например, Pillow).

  • Увеличенный размер файлов для APNG и HDR.

Инструменты и библиотеки для работы с PNG

Для реализации PNG в Python рекомендуются следующие инструменты (PNG Suite):

  • Pillow: Для создания статичных PNG, добавления iCCP и EXIF. Проста в использовании, но ограничена для APNG и HDR.

  • pyAPNG, PyGame: Для создания анимаций (acTL, fcTL, fdAT).

  • imageio: Для работы с 16-битными изображениями и HDR, но требует доработки для mDCV/cLLI.

  • pypng: Для низкоуровневой работы с чанками, например, добавления iTXt или mDCV.

Перспективы развития PNG

Формат PNG прошёл путь от простого заменителя GIF в 1996 году до универсального инструмента для веб-дизайна, игр и фотографии в 2025 году. Каждая редакция — первая (1996), вторая (2003) и третья (2025) — добавляла новые возможности, делая PNG гибким и конкурентоспособным. Сегодня PNG поддерживает прозрачность, анимацию (APNG), HDR и сложные метаданные (EXIF), что делает его востребованным в современных технологиях. Этот раздел подводит итоги эволюции PNG, анализирует его текущую роль и предлагает прогнозы на будущее, используя пример анимированного логотипа «PNG» с переливанием цветов и вращением. Представьте PNG как автомобиль, который эволюционировал от простого седана до электрокара с автопилотом, готового к новым дорогам (W3C PNG Specification (Third Edition, 2025)).

Текущая роль PNG

Сегодня PNG занимает уникальную нишу, благодаря своим возможностям:

  • Веб-дизайн: PNG используется для статичных логотипов, иконок и анимированных стикеров (APNG). Например, анимированный логотип «PNG» с переливанием цветов идеально подходит для Telegram или веб-сайтов, обеспечивая высокое качество и прозрачность.

  • Игры: HDR-чанки (mDCV, cLLI) делают PNG подходящим для текстур в современных игровых движках, таких как Unreal Engine или Unity, где яркие и реалистичные эффекты, как в нашем логотипе, усиливают визуальный опыт.

  • Фотография: Поддержка EXIF в третьей редакции позволяет использовать PNG как альтернативу JPEG для хранения снимков с метаданными, такими как дата или геолокация.

Сильные стороны PNG включают сжатие без потерь, поддержку альфа-канала, анимацию и HDR. По сравнению с конкурентами:

  • JPEG: Потери при сжатии, но меньший размер файлов.

  • WebP: Поддерживает анимацию и сжатие с потерями/без потерь, но сложнее в реализации.

  • AVIF: Высокое сжатие, но ограниченная поддержка в браузерах и инструментах (по состоянию на 2025 год).

Перспективы

Будущее PNG связано с новыми технологиями и улучшениями формата:

  • Дополненная и виртуальная реальность (AR/VR): PNG с HDR и APNG идеально подходит для текстур и анимаций в AR/VR-приложениях. Например, наш анимированный логотип «PNG» может использоваться в AR-очках для отображения интерактивных элементов с реалистичными цветами и прозрачностью.

  • Машинное обучение: PNG с прозрачностью и сжатием без потерь востребован для хранения данных, таких как маски сегментации или аннотации для обучения моделей.

  • 3D-графика: Потенциальное расширение PNG для хранения многоканальных текстур (нормали, глубина) может сделать его стандартом для 3D-рендеринга.

Потенциальные улучшения:

  • Внедрение новых алгоритмов сжатия, таких как Brotli, вместо DEFLATE, для уменьшения размера файлов.

  • Расширение HDR-поддержки для стандартов, таких как Rec. 2100 или Dolby Vision, для ещё более ярких изображений.

  • Интеграция с WebGPU для ускоренного рендеринга текстур в браузерах.

Проблемы:

  • Конкуренция с AVIF, который предлагает лучшее сжатие, но требует времени для широкого внедрения.

  • Ограниченная поддержка новых чанков (mDCV, cLLI) в текущих библиотеках, таких как Pillow или imageio.

Рекомендации

Для эффективного использования PNG:

  • Выбирайте PNG для задач с прозрачностью и анимацией: APNG для стикеров в мессенджерах, HDR для игровых текстур.

  • Следите за обновлениями библиотек: Pillow, pyAPNG и imageio для поддержки новых чанков (mDCV, cLLI).

  • Экспериментируйте с новыми технологиями: Используйте PNG в AR/VR для анимаций или в ML для масок.

PNG остаётся универсальным форматом, способным адаптироваться к вызовам современных технологий. От простых логотипов в 1996 году до анимированных HDR-изображений в 2025 году, PNG доказал свою гибкость и востребованность. Его будущее связано с AR/VR, машинным обучением и улучшенным сжатием, что делает его ключевым инструментом. Экспериментируйте с анимацией и HDR, как в случае с нашим логотипом «PNG», чтобы создавать инновационные проекты, которые вдохновляют пользователей.

Список литературы

  1. World Wide Web Consortium. (1996). PNG (Portable Network Graphics) Specification, First Edition. Retrieved June 29, 2025, from https://www.w3.org/TR/REC-png-961001

  2. World Wide Web Consortium. (2003). PNG (Portable Network Graphics) Specification, Second Edition. Retrieved June 29, 2025, from https://www.w3.org/TR/2003/REC-PNG-20031110/

  3. World Wide Web Consortium. (2025). PNG (Portable Network Graphics) Specification, Third Edition. Retrieved June 29, 2025, from https://www.w3.org/TR/png-3/

  4. Mozilla. (n.d.). APNG (Animated Portable Network Graphics) Specification. Retrieved June 29, 2025, from https://wiki.mozilla.org/APNG_Specification

  5. PNG Development Group. (n.d.). PNG Frequently Asked Questions. Retrieved June 29, 2025, from https://www.libpng.org/pub/png/pngfaq.html

  6. PNG Development Group. (n.d.). PNG Suite: Test Images. Retrieved June 29, 2025, from https://www.libpng.org/pub/png/pngsuite.html

  7. PNG Development Group. (n.d.). Introduction to PNG. Retrieved June 29, 2025, from https://www.libpng.org/pub/png/pngintro.html

Приложения

Приложение A: Структура типичного PNG-файла

Ниже представлена структура PNG-файла, созданного для анимированного логотипа «PNG» с переливанием цветов и вращением (третья редакция, 2025). Структура иллюстрирует организацию чанков для APNG с HDR и EXIF.

PNG Signature: 89 50 4E 47 0D 0A 1A 0A
Чанк IHDR: Ширина = 100, Высота = 100, Глубина = 16 бит, Тип = 6 (RGBA), Сжатие = DEFLATE
Чанк mDCV: Цветовой объём и яркость для HDR (12 байт цвета, 4 байта яркости)
Чанк cLLI: Максимальная и средняя яркость (MaxCLL, MaxFALL, по 4 байта)
Чанк cICP: Упрощённый профиль цвета для HDR
Чанк acTL: 6 кадров, бесконечный цикл (APNG)
Чанк fcTL (x6): Задержка = 100 мс, разные цвета и углы вращения для каждого кадра
Чанк fdAT (x6): Сжатые данные кадров (переливающийся и вращающийся текст «PNG»)
Чанк eXIf: Метаданные (Дата: 2025-01-01, Автор: xAI Studio)
Чанк IDAT: Данные первого кадра
Чанк IEND: Конец файла

Эта структура демонстрирует, как PNG объединяет статичные данные, анимацию, HDR и метаданные, делая его универсальным для современных приложений, таких как Telegram-стикеры или AR-текстуры (PNG Suite).

Приложение B: Таблица чанков PNG

Чанк

Редакция

Назначение

IHDR

1996

Заголовок: размеры изображения, глубина цвета, тип цвета

PLTE

1996

Палитра для индексированных цветов

tRNS

1996

Прозрачность (бинарная маска или альфа-канал)

IDAT

1996

Сжатые данные изображения (алгоритм DEFLATE)

IEND

1996

Маркер конца файла PNG

tEXt/zTXt

1996

Текстовые метаданные (кодировка ISO 8859-1)

iCCP

2003

Встроенный ICC цветовой профиль

sRGB

2003

Указание использования цветового пространства sRGB

iTXt

2003

Международные текстовые метаданные (UTF-8 с возможностью сжатия)

mDCV

2025

Mastering Display Color Volume - параметры цветового объёма для HDR

cLLI

2025

Content Light Level Information - информация о яркости контента для HDR

cICP

2025

Coding-Independent Code Points - независимые от кодировки цветовые параметры

acTL

2025

Animation Control - управляющие данные для анимации (APNG)

fcTL

2025

Frame Control - параметры отдельных кадров анимации (APNG)

fdAT

2025

Frame Data - данные кадров анимации (APNG)

eXIf

2025

Метаданные в формате EXIF (как в JPEG)

Эта таблица служит справочным материалом для разработчиков, работающих с PNG в Python или других инструментах (PNG FAQ).

Tags:
Hubs:
+19
Comments13

Articles

Information

Website
ntechlab.ru
Registered
Founded
Employees
201–500 employees
Location
Россия
Representative
Eli_bas