Javascript 如何将二进制缓冲区保存到nodejs中的png文件?

Javascript 如何将二进制缓冲区保存到nodejs中的png文件?,javascript,node.js,buffer,Javascript,Node.js,Buffer,我有一个包含位图信息的二进制nodejs缓冲区对象。如何从缓冲区生成图像并将其保存到文件 编辑: 我尝试使用@herchu所说的文件系统包,但如果我这样做: let robot = require("robotjs") let fs = require('fs') let size = 200 let img = robot.screen.capture(0, 0, size, size) let path = 'myfile.png' let buffer = img.image fs

我有一个包含位图信息的二进制nodejs缓冲区对象。如何从缓冲区生成图像并将其保存到文件

编辑:

我尝试使用@herchu所说的文件系统包,但如果我这样做:

let robot = require("robotjs")
let fs = require('fs')

let size = 200
let img = robot.screen.capture(0, 0, size, size)


let path = 'myfile.png'
let buffer = img.image

fs.open(path, 'w', function (err, fd) {
  if (err) {
    // Something wrong creating the file
  }

  fs.write(fd, buffer, 0, buffer.length, null, function (err) {
    // Something wrong writing contents!
  })
})
我明白了

注意:我正在根据您上次编辑的内容编辑我的答案

如果您使用的是Robotjs,请检查它是否包含原始像素数据的缓冲区——不是PNG或任何其他文件格式的内容,只是相邻的像素(在您的示例中正好是200 x 200个元素)

我还没有在Robotjs库中找到任何以其他格式编写内容的函数(我也不知道),因此在这个回答中,我使用了另一个库来处理图像

let robot = require("robotjs")
let fs = require('fs')
let Jimp = require('jimp')

let size = 200
let rimg = robot.screen.capture(0, 0, size, size)
let path = 'myfile.png'

// Create a new blank image, same size as Robotjs' one
let jimg = new Jimp(size, size);
for (var x=0; x<size; x++) {
        for (var y=0; y<size; y++) {
                // hex is a string, rrggbb format
                var hex = rimg.colorAt(x, y);
                // Jimp expects an Int, with RGBA data,
                // so add FF as 'full opaque' to RGB color
                var num = parseInt(hex+"ff", 16)
                // Set pixel manually
                jimg.setPixelColor(num, x, y);
        }
    }
jimg.write(path)
let robot=require(“robotjs”)
设fs=require('fs')
设Jimp=require('Jimp')
让尺寸=200
让rimg=robot.screen.capture(0,0,size,size)
let path='myfile.png'
//创建一个新的空白图像,与Robotjs的图像大小相同
设jimg=新Jimp(尺寸,尺寸);

对于(var x=0;x将此添加为@herchu接受答案的附录,此代码示例可以更快地处理/转换原始字节(对于我来说,全屏小于1s)。希望这对其他人有所帮助

var jimg = new Jimp(width, height);
for (var x=0; x<width; x++) {
    for (var y=0; y<height; y++) {
        var index = (y * rimg.byteWidth) + (x * rimg.bytesPerPixel);
        var r = rimg.image[index];
        var g = rimg.image[index+1];
        var b = rimg.image[index+2];
        var num = (r*256) + (g*256*256) + (b*256*256*256) + 255;
        jimg.setPixelColor(num, x, y);
    }
}
var jimg=新Jimp(宽度、高度);

对于(var x=0;x虽然@herchu和@Jake的解决方案有效,但它们的速度非常慢(以我的经验,是10-15秒)


开箱即用,工作速度更快(亚秒)

快四倍! 如果使用此脚本,全屏1920x1080约280ms和550Kb。 当我将每个字节2个字节的线程与前额进行比较时,我发现了这种模式

const robotjs = require('robotjs');
const Jimp = require('jimp');
const app = require('express').Router();

app.get('/screenCapture', (req, res)=>{
  let image = robotjs.screen.capture();
  for(let i=0; i < image.image.length; i++){
      if(i%4 == 0){
          [image.image[i], image.image[i+2]] = [image.image[i+2], image.image[i]];
      }
  }

  var jimg = new Jimp(image.width, image.height);
  jimg.bitmap.data = image.image;
  jimg.getBuffer(Jimp.MIME_PNG, (err, result)=>{
      res.set('Content-Type', Jimp.MIME_PNG);
      res.send(result);
  });
});

我发现了这个很棒的库。我做了一个简单的颜色机器人,然后我决定做一些更智能的东西,所以我在nodejs中设置了模板匹配。我可以拍摄屏幕的照片,但库返回一个缓冲区。我恐怕我不能使用文件系统。我编辑了我的问题。如果你知道一些关于C或其他更难的语言,因为我已经在这个问题上花了几个小时。:/我已经编辑了这个问题。代码现在基于您的,使用robotjs并生成一个工作PNG文件。(原始问题中没有指定您的缓冲区不是PNG文件…而是一个原始robotjs缓冲区)我接受了这个答案,因为你解释了很多。遗憾的是,当你看到像600x600或更高的图片时,速度会变慢。我将使用shelljs并生成截图归档。然后我可能会使用express server将它们发送到我的客户机。或者只是使用socket.io发送它们。我在下面为proce添加了另一个代码示例使用运行速度更快的像素(对于大多数实际应用来说应该足够快)。感谢@herchu为我指明了正确的开始方向。:)我有这样一个错误:没有找到匹配的构造函数重载。请参阅文档,了解如何调用Jimp构造函数。这要快100000倍。这对我来说在Ubuntu 18.04上不太好。起初,生成的图像是透明的。我注意到alpha通道始终为0,所以我将其更新为255,只是为了发现ors是错误的。出于某种原因,robotjs创建的缓冲区使用bgra而不是rgba。使用以下代码修复了这一问题,并且仍然比这里建议的其他解决方案工作得更快:let fixedImg=new Uint8Array(img.length);For(let i=0;iconst robotjs = require('robotjs'); const Jimp = require('jimp'); const app = require('express').Router(); app.get('/screenCapture', (req, res)=>{ let image = robotjs.screen.capture(); for(let i=0; i < image.image.length; i++){ if(i%4 == 0){ [image.image[i], image.image[i+2]] = [image.image[i+2], image.image[i]]; } } var jimg = new Jimp(image.width, image.height); jimg.bitmap.data = image.image; jimg.getBuffer(Jimp.MIME_PNG, (err, result)=>{ res.set('Content-Type', Jimp.MIME_PNG); res.send(result); }); });
  jimg.rgba(true);
  jimg.filterType(1); 
  jimg.deflateLevel(5);
  jimg.deflateStrategy(1);