readPixels to base64 (преобразование буфера на стороне сервера WebGL)

Я использую headless-gl для запуска webGL на Node.js, динамически создавая изображение на сервере. После создания изображение должно храниться в базе данных (MongoDB), прежде чем пользователь снова получит доступ к изображению через API.

Ниже приведена часть, где создается изображение:

var pixels = new Uint8Array(width * height * 4)
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels)

Затем пиксели преобразуются в base64 (поскольку это рекомендуемый способ загрузки изображения в клиентском HTML).

var base64Image = new Buffer(pixels, 'binary').toString('base64');

Однако строка, созданная этим буфером, не может быть декодирована для создания изображения. Может быть, пиксели не являются «бинарными»? Или я должен просто сохранить строку пикселей в базе данных и попытаться перерисовать пиксель в холсте попиксельно в клиенте (я не думаю, что это лучший способ)?


person cristie09    schedule 01.11.2017    source источник
comment
Что вы подразумеваете под повторным чтением для создания изображения? Я имею в виду код.   -  person Jake Weary    schedule 01.11.2017
comment
Я отредактировал «прочитать» на «расшифровано», надеюсь, это прояснит!   -  person cristie09    schedule 01.11.2017
comment
Ниже приведена часть, где генерируется изображение: Нет, это не сгенерированное изображение, это данные изображения (данные о цвете на пиксель). Эти данные можно использовать с frameBuffer. Это не легко . Ваш базовый файл изображения поступил с вашего сервера (домена), если нет, вы не можете точно сгенерировать изображение. Вы пытались отладить переменные пиксели и посмотреть, что это такое?   -  person Nikola Lukic    schedule 02.11.2017
comment
привет, переменные пиксели содержат данные о цвете на пиксель изображения, которое я сгенерировал ранее (код не прилагается). Я хотел бы превратить эту переменную пикселей в строку, чтобы изображение можно было сохранить в базе данных, прежде чем оно будет загружено браузером клиента. Хотел бы знать, как его преобразовать и какой формат использовать - похоже, base64 рекомендуется после некоторого первоначального поиска, который я провел в Интернете.   -  person cristie09    schedule 02.11.2017


Ответы (2)


Что вы получаете от gl.readPixels, так это растровые данные. Я использую библиотеку Jimp для преобразования данных в другой формат, а затем получаю из нее строку изображения base64.

NodeJS-код

var Jimp = require("jimp")

//Create context
var width = 50
var height = 50

var gl = require('gl')(width, height, { preserveDrawingBuffer: true })

//Clear screen to red
gl.clearColor(1, 0, 0, 1)
gl.clear(gl.COLOR_BUFFER_BIT)

// get bitmap data 
var bitmapData = new Uint8Array(width * height * 4)
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, bitmapData)

// use Jimp library to create an image with a specific mime type
var image = new Jimp(width, height, function (err, image) {

    // assign the bitmap as data for the image 
    image.bitmap.data = bitmapData
    // generate base64
    image.getBase64("image/png", function (error, str) {
        // result
        console.log(str)
    })
})

Проверьте в браузере, работает ли он у вас (код JS):

var base64Img = "" // TODO paste the result from NodeJS

document.body.innerHTML = ""
document.write('<img src="' + base64Img + '"/>');
person Entity Black    schedule 03.11.2017

То, что вы получаете, используя readPixels, — это необработанные растровые данные. Если ваша цель — отобразить их через браузер, вам необходимо повторно инкапсулировать необработанные данные в известный формат файла изображения, такой как BMP, TGA, JPEG, PNG и т. д. Таким образом, вы должны создать файл в двоичном режиме (для формата BMP или TGA это довольно просто).

person Sedenion    schedule 02.11.2017
comment
На самом деле я хотел бы преобразовать необработанные данные растрового изображения в строку base64, чтобы их можно было сохранить в базе данных, прежде чем клиент отобразит их в браузере. Знаете ли вы, как построить строку base64 из необработанных данных растрового изображения? - person cristie09; 02.11.2017
comment
То, как вы конвертируете двоичный (октетный поток) в base64, кажется правильным, здесь есть еще один пример: stackoverflow.com/questions/8305988/ Таким образом, вы можете сохранить результат в базе данных. Но, как я уже сказал, если вы хотите, чтобы это отображалось как изображение после повторного декодирования (в двоичном формате), вы должны инкапсулировать пиксельные данные в формате изображения, известном браузеру. - person Sedenion; 03.11.2017
comment
Или вы можете повторно использовать необработанные пиксельные данные в текстуре на стороне клиента... здесь у вас есть некоторый выбор в зависимости от того, что вы хотите сделать на финальном этапе. Но браузеры не знают, что делать с неопознанным буфером необработанных байтов, вы должны сказать ему, чтобы сказать ему, вы должны инкапсулировать, например, в файл BMP. Тем не менее, инкапсуляция пиксельных данных в растровый формат — это низкоуровневая двоичная операция, вы найдете только примеры на низкоуровневом языке, таком как C, вы должны адаптироваться с помощью инструментов, которые предоставляет вам JS: en.wikipedia.org/wiki/BMP_file_format - person Sedenion; 03.11.2017
comment
ах хорошо, спасибо за ваше объяснение, это полезно. К сожалению, хотя преобразование, которое я сделал, казалось правильным, вы правы в том, что мне нужно сначала найти определенное, прежде чем оно будет доступно для чтения в браузере. Простое преобразование буфера в base64 бесполезно. - person cristie09; 05.11.2017