使用纯JavaScript在客户端w/o上使用canvas在内存中裁剪Base64 PNG

时间:2021-03-31 17:11:34

Context: JavaScript, as part of a SDK (can be on node.js or browser).

上下文:JavaScript,作为SDK的一部分(可以在节点上)。js或浏览器)。

Start point: I have a base64 string that's actually a base64 encoded PNG image (I got it from selenium webdriver - takeScreenshot).

起点:我有一个base64字符串,它实际上是一个经过base64编码的PNG图像(我是从selenium webdriver - takeScreenshot获得的)。

Question: How do I crop it?

问题:我如何裁剪它?

The techniques involving the canvas seem irrelevant (or am I wrong?). My code runs as part of tests - probably on node.js. The canvas approach doesn't seem to fit here and might also cause additional noise in the image.

涉及画布的技术似乎无关紧要(还是我错了?)我的代码作为测试的一部分运行——可能在node.js上。画布的方法似乎并不适合这里,也可能会在图像中造成额外的噪声。

All the libraries I found either deal with streams (maybe I should convert the string to stream somehow?) or deal directly with the UI by adding a control (irrelevant for me).

我找到的所有库要么处理流(也许我应该以某种方式将字符串转换为流?)要么通过添加控件(对我来说无关紧要)直接处理UI。

Isn't there something like (promises and callbacks omitted for brevity):

难道没有类似的东西(为了简洁,省略了承诺和回调):

 var base64png = driver.takeScreenshot();
 var png = new PNG(base64png);
 return png.crop(50, 100, 20, 80).toBase64();

?

吗?

Thanks!

谢谢!

2 个解决方案

#1


1  

Adding my previous comment as an answer:

加上我之前的评论作为回答:

Anyone looking to do this will need to decode the image to get the raw image data using a library such as node-pngjs and manipulate the data yourself (perhaps there is a library for such operations that doesn't rely on the canvas).

任何想要这样做的人都需要对图像进行解码,以便使用像node-pngjs这样的库获取原始的图像数据,并自己操作数据(可能有一个库用于不依赖于画布的操作)。

#2


4  

Considering you wish to start with base64 string and end with cropped base64 string (image), here is the following code:

考虑到您希望从base64字符串开始,以裁剪过的base64字符串(图像)结束,这里有以下代码:

var Stream = require('stream');
var gm = require('gm');

var base64png = driver.takeScreenshot();
var stream = new Stream();

stream.on('data', function(data) {
  print data
});

gm(stream, 'my_image.png').crop(WIDTH, HEIGHT, X, Y).stream(function (err, stdout, stderr) {
  var data = '';

  stdout.on('readable', function() {
    data += stream.read().toString('base64');
  });
  stream.on('end', function() {
    // DO something with your new base64 cropped img
  });
});

stream.emit('data', base64png);

Be aware that it is unfinished, and might need some polishing or debugging (I am in no means a node.js guru), but the idea is next:

请注意,它尚未完成,可能需要进行一些修改或调试(我绝不是节点)。但下一个想法是:

  1. Convert string into stream
  2. 将字符串转换成流
  3. Read stream into GM module
  4. 将流读入GM模块
  5. Manipulate the image
  6. 处理图像
  7. Save it into a stream
  8. 把它保存到流中
  9. Convert stream back into 64base string
  10. 将流转换回64基字符串

#1


1  

Adding my previous comment as an answer:

加上我之前的评论作为回答:

Anyone looking to do this will need to decode the image to get the raw image data using a library such as node-pngjs and manipulate the data yourself (perhaps there is a library for such operations that doesn't rely on the canvas).

任何想要这样做的人都需要对图像进行解码,以便使用像node-pngjs这样的库获取原始的图像数据,并自己操作数据(可能有一个库用于不依赖于画布的操作)。

#2


4  

Considering you wish to start with base64 string and end with cropped base64 string (image), here is the following code:

考虑到您希望从base64字符串开始,以裁剪过的base64字符串(图像)结束,这里有以下代码:

var Stream = require('stream');
var gm = require('gm');

var base64png = driver.takeScreenshot();
var stream = new Stream();

stream.on('data', function(data) {
  print data
});

gm(stream, 'my_image.png').crop(WIDTH, HEIGHT, X, Y).stream(function (err, stdout, stderr) {
  var data = '';

  stdout.on('readable', function() {
    data += stream.read().toString('base64');
  });
  stream.on('end', function() {
    // DO something with your new base64 cropped img
  });
});

stream.emit('data', base64png);

Be aware that it is unfinished, and might need some polishing or debugging (I am in no means a node.js guru), but the idea is next:

请注意,它尚未完成,可能需要进行一些修改或调试(我绝不是节点)。但下一个想法是:

  1. Convert string into stream
  2. 将字符串转换成流
  3. Read stream into GM module
  4. 将流读入GM模块
  5. Manipulate the image
  6. 处理图像
  7. Save it into a stream
  8. 把它保存到流中
  9. Convert stream back into 64base string
  10. 将流转换回64基字符串