【问题标题】:Unable to pass stream as parameter to JS in aspnet.core.NodeServices无法将流作为参数传递给 aspnet.core.NodeServices 中的 JS
【发布时间】:2018-01-16 04:33:27
【问题描述】:

我目前正处于将“旧”ASP MVC 项目迁移到新的 Core MVC (1.1) 的情况,从一个突破性的变化跨越到下一个。我现在停留在“图像处理”主题上,因为 System.Web.Helpers.WebImage 已被删除。我查看了几种可能的解决方案,并喜欢通过 this comment! 中描述的 Microsoft.AspNetCore.NodeServices 提出的方法。

在使用示例脚本并传入文件名时一切正常。我现在已经花了几个小时来尝试让同样的事情在我从 DB 读取图像数据并希望将其直接通过管道传递到 JS 时传递字节流。

使用JIMP库的JS:

var jimp = require("jimp");

module.exports = function (result, source, mimeType, maxWidth, maxHeight) {
// Invoke the 'jimp' NPM module, and have it pipe the resulting image data back to .NET
jimp.read(source.buffer).then(function (file) {
    var width = maxWidth || jimp.AUTO;
    var height = maxHeight || jimp.AUTO;
    file.resize(maxWidth, height)
         .getBuffer(mimeType, function (err, buffer) {
             var stream = result.stream;
             stream.write(buffer);
             stream.end();
         });
    }).catch(function (err) {
    console.error(err);
   });
};

我的图像控制器上的操作

var imageStream = await _nodeServices.InvokeAsync<Stream>(
                "Node/resizeImageBuffer",
                bild.BildDaten.Daten, // byte[]
                bild.Mimetype, // "image/jpeg"
                targetsize, // e.g. 400
                targetsize);

当我这样调用它时,我的 byte[] 被序列化为字符串并且不能作为节点中的缓冲区。

当我尝试包装一个流时,JS 甚至没有执行,因为它在序列化参数时中断。像这样:

var imageStream = await _nodeServices.InvokeAsync<Stream>(
            "Node/resizeImageBuffer",
            new MemoryStream(bild.BildDaten.Daten), // MemoryStream
            bild.Mimetype, // "image/jpeg"
            targetsize, // e.g. 400
            targetsize);

它抛出

JsonSerializationException: Error getting value from 'ReadTimeout' on 'System.IO.FileStream'.

我得到什么,从 Node 到 C# 的结果流有效并且是一个有效的 System.IO.Stream 对象,但同样不能作为输出参数... 也许有人有想法?

【问题讨论】:

    标签: c# node.js asp.net-mvc image-processing asp.net-core


    【解决方案1】:

    我最终做的是使用System.BitConverter.ToString() 将图像 byte[] 转换为其十六进制字符串表示,并将 that 传递给节点脚本。

    var byteString = System.BitConverter.ToString(image.Bytes);
    var img = await _nodeServices.InvokeAsync<Stream>(
        "./NodeServices/thumbnail",
         "image/jpeg",
         byteString,
         width,
         height
    );
    

    然后在节点脚本中,我将十六进制字符串解析回一个字节数组,用它创建一个缓冲区,然后能够将缓冲区传递给 jimp。

    const jimp = require('jimp')
    
    module.exports = function (result, mimeType, bytes, maxWidth, maxHeight) {
       const parsedBytes = bytes.split('-').map(e => parseInt(`0x${e}`))
       const buffer = Buffer.from(parsedBytes)
    
       jimp.read(buffer)
           .then((img) => {
               var width = maxWidth || jimp.AUTO
               var height = maxHeight || jimp.AUTO
               img.resize(width, height)
                  .getBuffer(mimeType, function (err, buffer) {
                      const stream = result.stream
                      stream.write(buffer)
                      stream.end()
                  })
        })
        .catch(err => {
            console.error(err)
        })
    }
    

    我希望找到一种将 byte[] 数组本身传递给节点脚本的方法,但现在我很高兴这可行。

    【讨论】:

      猜你喜欢
      • 2018-04-19
      • 2021-03-22
      • 2015-01-20
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      • 2014-06-27
      • 1970-01-01
      • 2013-02-28
      相关资源
      最近更新 更多