MCO Image Codec Demo

Draw a small indexed image, encode it as legacy im: or current im3:, then decode and render it back.

Canvas

Used colors (0)
Transparent color none

Encoded text

Decoded preview

Binary hex view

MCOimg.pack md5

Universal codec helpers

Ниже — три базовых сценария использования. Основные преобразования выполняет сам кодек. Browser-helper в примерах нужен только там, где надо показать PNG на HTML canvas.

<script src="./mcoimg-codec.global.js"></script>
<script src="./mcoimg-v3-codec.global.js"></script>
<script src="./mcoimg-browser.global.js"></script>

Version-neutral API: v1/v2/v3

const text = await MCOImgBrowser.encodeCanvas(sourceCanvas, {
  formatVersion: 3,
  compressionLevel: 'extreme',
  paletteProfile: MCOImg.PaletteProfile.master8,
  transparentColor: null,
  output: 'text', // text | binary | png | image | encoded
  useWorkers: true,
  workerCount: 4,
});

const binary = await MCOImgBrowser.convertPayload(text, { output: 'binary' });
const png = await MCOImgBrowser.convertPayload(binary, { output: 'png' });
const info = MCOImgBrowser.inspectPayload(text);

1. Canvas → RGBA → im: text или binary

Полный путь: берём готовое растровое изображение с canvas, читаем из него RGBA-массив, затем передаём эти данные в универсальный helper кодека.

// Берём API кодека.
const {
  MCOImageCodec,
  PaletteProfile,
  MCOImageRgbaOutputFormat,
} = window.MCOImg;

// Создаём экземпляр кодека.
const codec = new MCOImageCodec();

// Берём canvas, в котором уже находится итоговая картинка.
// Важно: кодируется реальный backing size canvas: canvas.width × canvas.height.
// CSS-масштаб на кодирование не влияет.
const sourceCanvas = document.querySelector('#source');

// Получаем 2D-контекст и читаем RGBA-данные из canvas.
// imageData.data — это плоский массив вида:
// [R, G, B, A, R, G, B, A, ...]
const sourceContext = sourceCanvas.getContext('2d');
const imageData = sourceContext.getImageData(
  0,
  0,
  sourceCanvas.width,
  sourceCanvas.height,
);

// Готовим вход для helper-функции кодека.
// Сам массив imageData.data не содержит размеры, поэтому
// width и height нужно передать явно.
const rgbaInput = {
  width: imageData.width,
  height: imageData.height,
  data: imageData.data,
};

// Вариант A: кодируем сразу в обычную строку формата "im:...".
const imText = codec.encodeRgbaPixels(
  rgbaInput,                         // RGBA + width/height
  PaletteProfile.master8,           // профиль палитры
  null,                             // transparentColor; null = без прозрачности
  MCOImageRgbaOutputFormat.text,    // хотим результат как строку "im:..."
);
console.log(imText);

// Вариант B: кодируем те же RGBA-данные сразу в binary payload.
// Результат — Uint8Array без "im:" и без base91.
const binaryPayload = codec.encodeRgbaPixels(
  rgbaInput,
  PaletteProfile.master8,
  null,
  MCOImageRgbaOutputFormat.binary,  // хотим получить binary
);
console.log(binaryPayload);

2. im: text → PNG bytes → вывод PNG в canvas

Полный путь: декодируем строку im:... в PNG натурального размера, а затем показываем этот PNG в canvas.

// Берём кодек и browser-helper.
const { MCOImageCodec, MCOImageTextOutputFormat } = window.MCOImg;
const { drawPngBytesToCanvas } = window.MCOImgBrowser;

// Создаём экземпляр кодека.
const codec = new MCOImageCodec();

// Это входная строка MCOimg, полученная откуда угодно:
// из сети, из базы, из текстового поля и т.д.
const textPayload = 'im:...';

// Шаг 1. Конвертируем "im:..." в PNG-байты.
// Результат — Uint8Array с валидным PNG-файлом.
// PNG создаётся в исходном размере изображения, без апскейла.
const pngBytes = codec.convertTextPayload(
  textPayload,
  MCOImageTextOutputFormat.png,
);
console.log(pngBytes);

// Шаг 2. Показываем полученный PNG в canvas.
// Helper создаст Blob из PNG-байтов, декодирует его средствами браузера
// и нарисует в targetCanvas.
const previewCanvas = document.querySelector('#previewFromText');
await drawPngBytesToCanvas(pngBytes, previewCanvas);

// После этого в previewCanvas будет видна картинка
// с исходными width/height из MCOimg.

3. Binary payload → PNG bytes → вывод PNG в canvas

Полный путь: берём бинарный payload MCOimg, конвертируем его в PNG, а затем выводим этот PNG на canvas.

// Берём кодек и browser-helper.
const { MCOImageCodec, MCOImageBinaryOutputFormat } = window.MCOImg;
const { drawPngBytesToCanvas } = window.MCOImgBrowser;

// Создаём экземпляр кодека.
const codec = new MCOImageCodec();

// Это входной binary payload MCOimg.
// Обычно это Uint8Array, полученный из файла, из сокета,
// из бинарного сообщения и т.д.
const binaryPayload = new Uint8Array([
  /* ... байты MCOimg ... */
]);

// Шаг 1. Конвертируем binary MCOimg в PNG-байты.
const pngBytes = codec.convertBinaryPayload(
  binaryPayload,
  MCOImageBinaryOutputFormat.png,
);
console.log(pngBytes);

// Шаг 2. Рисуем полученный PNG в canvas.
// PNG сохраняет натуральный размер изображения.
const previewCanvas = document.querySelector('#previewFromBinary');
await drawPngBytesToCanvas(pngBytes, previewCanvas);

// Шаг 3. Сохраняем тот же PNG как обычный файл.
// downloadBytes создаёт Blob и запускает браузерное скачивание.
window.MCOImgBrowser.downloadBytes(
  pngBytes,
  'mcoimg-from-binary.png',
  'image/png',
);

4. Полный channel binary packet → чистый MCOimg binary payload

Channel packet содержит транспортный заголовок, имя отправителя и только затем бинарное тело MCOimg. Перед вызовом codec.convertBinaryPayload() нужно выделить именно это тело.

// Берём функцию извлечения из browser-helper.
const {
  extractMcoImagePayload,
  inspectMcoImageChannelPacket,
  drawPngBytesToCanvas,
  downloadBytes,
} = window.MCOImgBrowser;

const {
  MCOImageCodec,
  MCOImageBinaryOutputFormat,
} = window.MCOImg;

const codec = new MCOImageCodec();

// fullPacket — полный Uint8Array, полученный из channel binary transport.
// Helper поддерживает:
//   1) channelData:
//      [channel_idx][data_type u16][sender_len varuint][sender UTF-8][MCOimg]
//   2) outgoingCommand:
//      [cmd][channel_idx][path_len][path...][data_type u16]
//      [sender_len varuint][sender UTF-8][MCOimg]
//   3) только envelope:
//      [sender_len varuint][sender UTF-8][MCOimg]
const fullPacket = new Uint8Array([
  /* ... полный пакет ... */
]);

// Вариант A: получить только чистый MCOimg payload.
// По умолчанию layout и byte order определяются автоматически.
// data_type должен быть равен 0xFFF0.
const mcoBinary = extractMcoImagePayload(fullPacket);

// Теперь этот результат можно напрямую передать в основной кодек.
const pngBytes = codec.convertBinaryPayload(
  mcoBinary,
  MCOImageBinaryOutputFormat.png,
);

// Показываем PNG натурального размера.
await drawPngBytesToCanvas(
  pngBytes,
  document.querySelector('#previewFromChannelPacket'),
);

// При необходимости сохраняем PNG на диск.
downloadBytes(
  pngBytes,
  'mcoimg-from-channel-packet.png',
  'image/png',
);

// Вариант B: получить не только payload, но и метаданные пакета.
const packetInfo = inspectMcoImageChannelPacket(fullPacket);

console.log(packetInfo.layout);       // channelData / outgoingCommand / envelope
console.log(packetInfo.dataType);     // 0xFFF0
console.log(packetInfo.channelIndex); // индекс канала, если есть
console.log(packetInfo.senderName);   // имя из envelope
console.log(packetInfo.payload);      // чистый Uint8Array MCOimg
В первых трёх сценариях browser-helper отвечает только за браузерные операции: canvas, Blob и скачивание. В четвёртом сценарии он также разбирает channel binary envelope, потому что это транспортная оболочка, а не часть формата MCOimg.