Как предоставить правильные данные, когда ImageData недоступен? - PullRequest
0 голосов
/ 19 октября 2019

Я использую библиотеку JS для векторизации растрового изображения, и библиотека возвращает сплошную цветную заливку вместо желаемого результата.

Я думаю, что это связано с ArrayBuffer.

Я загружаю изображение в двоичный файл следующим образом:

const arrayBuffer = await image.read({ format: filesystem.formats.binary });

Библиотека ожидает объект ImageData , но среда находится в canvas и ImageData не поддерживаются, поэтому я пытаюсь создать поддельный объект ImageData для передачи в библиотеку:

var imageData = {data: arrayBuffer, width: sceneNode.globalBounds.width, height: sceneNode.globalBounds.height};
var results = library.apply(imageData);

Я пытаюсь запустить библиотеку, и она показывает ошибку, которая, как ожидается, будет иметь объект данныхсвойство length, поэтому я добавляю это заранее:

 arrayBuffer.length = arrayBuffer.bytesLength;

После этого в библиотеке, по-видимому, нет ошибок, поскольку она возвращает данные SVG. Но SVG - это просто путь границ изображения.

Я предполагаю, что проблема с ArrayBuffer в поддельном объекте ImageData является проблемой, и мне нужно преобразовать его в правильный формат.

В документах говорится об этом свойстве ImageData.data:

ImageData.data - это Uint8ClampedArray, представляющий одномерный массив, содержащий данные в порядке RGBA, с целочисленными значениями между 0и 255 (включительно).

Похоже, мне нужно преобразовать буфер массива в "Uint8ClampedArray, представляющий одномерный массив, содержащий данные в порядке RGBA, с целочисленными значениямиот 0 до 255 ".

Кроме того, если я читаю файл в двоичном формате на JavaScript, это стандартный ArrayBuffer правильно?

ОБНОВЛЕНИЕ :
Возможно, файл изображения загружен в буфер массива, но его необходимо декодировать из формата изображения (PNG или JPEG), а затем преобразовать в Uint8ClampedArray. ? и затем данные пикселей могут быть прочитаны, Как я могу создать холст imageData массив из представления arrayBuffer JPG . Это похоже на то, что делает класс ImageData.

Библиотека UPNG , кажется, декодирует PNG, но свойство данных является объектом, а не массивом?

Библиотека является ImageTracer - https://github.com/jankovicsandras/imagetracerjs

1 Ответ

1 голос
/ 20 октября 2019

Да, вы почти ответили на свой вопрос. :)

  1. Создать TypedArray представление из ArrayBuffer:

    imageData.data = new Uint8ClampedArray (arrayBuffer);

или

var imageData = {data: new Uint8ClampedArray(arrayBuffer), width: sceneNode.globalBounds.width, height: sceneNode.globalBounds.height};
Предварительно декодируйте файл изображения, поскольку байты в сжатых форматах, таких как JPEG или PNG, не являются непосредственно значениями RGBA. Или вы можете попробовать несжатый BMP RGBA32, но сначала удалите заголовок, отбросьте первые 54 байта из массива.

Я думаю, что это похоже на UPNG, но я не проверял это:

var img  = UPNG.decode(buff);        // put ArrayBuffer of the PNG file into UPNG.decode
var rgba = UPNG.toRGBA8(img)[0];     // UPNG.toRGBA8 returns array of frames, size: width * height * 4 bytes.

var myImageData = { width:img.width, height:img.height, data:rgba };

var traceoptions = 'default'; // or whatever
var svgstr = ImageTracer.imagedataToSVG( myImageData, traceoptions );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...