【问题标题】:readPixels to base64 (WebGL Server side buffer conversion)readPixels 到 base64(WebGL 服务器端缓冲区转换)
【发布时间】:2018-04-13 21:38:31
【问题描述】:

我正在使用 headless-gl 在 Node.js 上运行 webGL,在服务器上动态创建图像。创建后,图像将存储在数据库(MongoDB)中,然后用户再次通过 API 访问图像。

下面是生成图片的部分:

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

然后将像素转换为 base64(因为这似乎是在客户端 HTML 中由 Image 加载的推荐方式)。

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

但是,此缓冲区生成的字符串无法解码以生成图像。可能像素不是“二进制”类型?或者我应该只是将像素字符串保存在数据库中,然后尝试在客户端中逐个像素地重绘画布中的像素(我认为这不是最好的方法)?

【问题讨论】:

  • 您所说的“回读以生成图像”是什么意思?我的意思是代码。
  • 我已将“回读”编辑为解码,希望它澄清!
  • 下面是生成图像的部分:不,这不是生成的图像,它是图像数据(每像素的颜色数据)。此数据可以与 frameBuffer 一起使用。这并不容易 。您的基础图像文件是否来自您的服务器(域),如果不是,您无法确定生成图像。您是否尝试调试可变像素并查看它是什么?
  • 嗨,可变像素包含我之前生成的图像的每个像素的颜色数据(未附加代码)。我想将这个变量像素变成一个字符串,以便图像可以保存在数据库中,然后再由客户端的浏览器下载。想知道如何转换它以及使用正确的格式——在我在线进行了一些初步搜索后,似乎推荐使用 base64

标签: html webgl glreadpixels server-rendering


【解决方案1】:

你从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 + '"/>');

【讨论】:

    【解决方案2】:

    使用 readPixels 得到的是原始位图数据,如果您的目标是通过浏览器显示,则必须将原始数据重新封装为已知的图像文件格式,例如 BMP、TGA、JPEG、PNG等。所以你必须以二进制模式构建一个文件(对于 BMP 或 TGA 格式,这很容易)。

    【讨论】:

    • 我实际上想将原始位图数据转换为base64字符串,以便在客户端在浏览器中显示之前将其保存在数据库中。你知道如何从原始位图数据构造 base64 字符串吗?
    • 将二进制(八位字节流)转换为 base64 的方式似乎是正确的,这里还有另一个示例:stackoverflow.com/questions/8305988/… 所以您可以将结果存储在数据库中。但正如我所说,如果您希望将其显示为图像,一旦再次解码(二进制),您必须将像素数据封装为浏览器知道的图像格式。
    • 或者您可以在客户端的纹理中重用原始像素数据...在这里,您有一些选择,具体取决于您在最后阶段要做什么。但是浏览器不知道如何处理未识别的原始字节缓冲区,您必须告诉他,告诉他,您必须封装到例如 BMP 文件中。但是,将像素数据封装成位图格式是一种低级的二进制操作,你只会发现 C 等低级语言的例子,你必须使用 JS 提供的工具来适应:en.wikipedia.org/wiki/BMP_file_format
    • 啊好的,谢谢你的解释,很有帮助。不幸的是,虽然我的转换看起来是正确的,但你是对的,我需要先找到一个特定的,然后它才能被浏览器读取。简单地将缓冲区转换为 base64 是没有用的。
    猜你喜欢
    • 2018-01-16
    • 1970-01-01
    • 2014-12-30
    • 1970-01-01
    • 1970-01-01
    • 2016-08-05
    • 1970-01-01
    • 2016-12-07
    • 1970-01-01
    相关资源
    最近更新 更多