使用Node/Express将HTML5画布转换为图像上传到Azure [英] Upload HTML5 Canvas Converted to Image to Azure using Node/Express

查看:70
本文介绍了使用Node/Express将HTML5画布转换为图像上传到Azure的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

顾名思义,这是一个有趣的用例.我有一个HTML5画布,可以将其转换为图像.我将AngularJS用作前端,而在我的网站的后端使用Node/Express.将HTML5 Canvas转换为图像可以按预期工作,并且可以使用jQuery AJAX(不使用Node/Express)将其上传到单独的Web服务,如下所示:

As the title implies, this is an interesting use case. I have an HTML5 Canvas that I am able to convert to a image. I am using AngularJS as the front end, with Node/Express on the backend for my site. Converting the HTML5 Canvas to an image works as intended and I am able to upload this to a separate Web Service using jQuery AJAX (not using Node/Express) as follows:

 $scope.webService = function () {
        var send = function (blob) {
            var filename = 'Test.pdf';
            var formdata = new FormData();
            formdata.append('File1', blob, filename);

            $.ajax({
                url: 'http://awebservice.net/endpoint',
                type: "POST",
                data: formdata,
                mimeType: "multipart/form-data",
                processData: false,
                contentType: false,
                crossDomain: true,
                success: function (result) {
                    console.log("Upload complete!");
                },
                error: function (error) {
                    console.log("Something went wrong!");
                }
            })
        }

        var canvasImage = document.getElementById("c");
        if (!canvasImage.toBlob) {
            var dataURL = canvasImage.toDataURL();
            var bytes = atob(dataURL.split(',')[1])
            var arr = new Uint8Array(bytes.length);
            for (var i = 0; i < bytes.length; i++) {
                arr[i] = bytes.charCodeAt(i);
            }
            send(new Blob([arr], { type: 'image/png' }));
        }
        else
            canvasImage.toBlob(send);
        }

我在另一种情况下使用Node/Express,如果我使用带有提交按钮的标准输入表单,则可以通过Node将映像上传到Azure.这是上传到Azure Blob存储的节点/快速代码,用于用户通过文件输入和提交按钮手动上传的图像,其中在HTML5表单的表单操作中调用/upload:

I am using Node/Express in another scenario where I can upload an image to Azure via Node if I use a standard input form with a submit button. Here is the Node/Express code that uploads to Azure Blob Storage for an image manually uploaded by a user through an file input and submit button, where /upload is called on the form action of the HTML5 form:

app.post('/upload4', function (req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
    var options = {
        contentType: files.myfile.type,
        metadata: { fileName: files.myfile.name }
    };
    blobSvc.createBlockBlobFromLocalFile('blob5', files.myfile.name, files.myfile.path, options, function (error, result, response) {
        if (!error) {
            // file uploaded
            res.send('file uploaded!');
        }
    });
});
console.log(req);
});

但是,我需要将转换后的HTML5画布传递到幕后",而用户不必通过Web表单下载并重新上传HTML5画布图像,而只需单击一下,即可对Canvas进行转换,图像上载到Azure(有关使用不使用Node/Express的不同Web服务的工作示例,请参见上面的第一个示例,该Web Service不上载通过jQuery AJAX转换为图像的HTML5 Canvas).本质上,由于我使用Node/Express来管理Azure Blob存储,因此我希望在jQuery AJAX示例中可以使用上载功能.

However, I need to pass my converted HTML5 Canvas "behind the scenes" where users don't have to download and re-upload the HTML5 Canvas Image via a Web form, but rather on click, the Canvas is converted and the image is uploaded to Azure (see first example above for a working example using a different Web Service that doesn't use Node/Express that uploads an HTML5 Canvas converted to an image via jQuery AJAX). Essentially, since I am using Node/Express to manage Azure Blob Storage, I want the upload functionality that works in my jQuery AJAX example.

我设想可以按以下方式将图像数据/变量传递回Node/Express:

I was envisioning that I could pass the image data/variables back to Node/Express as follows:

AngularJS前端控制器代码(与名为"upload()"的ng-click按钮操作绑定):

$scope.upload = function () {
var canvasImage = document.getElementById("c");
var img = canvasImage.toDataURL("image/png");
var filename = 'Texture_0.png';

$http.post('/upload', { filename: filename, file: img }).success(function (data) {
console.log(data);
});
}

节点/快速后端代码:

app.post('/upload', function (req, res) {
var filename = req.filename;
var file = req.file;
blobSvc.createBlockBlobFromLocalFile('mycontainer', filename, file, function (error, result, response) {
    if (!error) {
        console.log("Uploaded" + result);
// file uploaded
    }
    else {
        console.log(error);
    }
});
});

当我单击魔术按钮"以将Canvas转换为图像(图像转换有效)并上传(上传不起作用)时,出现如下Node错误:

When I click the "magic button" to convert the Canvas to an image (image conversion works) and upload (upload doesn't work), I get a Node error as follows:

错误:函数createBlockBlobFromFile的必需参数blob为 未定义

Error: Required argument blob for function createBlockBlobFromFile is not defined

我也将文件名"和文件"登录到节点控制台,并得到未定义".

I also logged "filename" and "file" to the Node console and got "undefined".

客户端在浏览器的控制台中,我收到500 Internal Server Error.但是,使用网络"选项卡,我进行了更深入的挖掘,发现请求有效负载"具有文件" base64编码和文件名"正确.

Client side I get a 500 Internal Server Error in the console of my browser. However, using the Network tab I dug deeper and saw that the "Request Payload" had the "file" base64 encoded and the "filename" as correct.

我很大程度上怀疑我没有将变量正确地传递给Node/Express,这就是导致Azure调用中断的原因.我也想知道自从通过输入表单上传图像是否适用于Azure/Node后,是否应该以某种方式将转换后的Canvas作为formdata传递,但不确定如何实现/应该尝试.

I largely suspect that I am not passing in the variables to Node/Express properly, and that is what is tripping up the Azure call. I am also wondering if since uploading an image via an input form works with Azure/Node, if I should somehow pass the converted Canvas as formdata but unsure how I would achieve this/should attempt it.

我的问题是,如何传递正确的变量/数据,以便将画布从AngularJS前端上传到Azure Blob存储到Node/Express后端?

My question is, how do I pass the right variables/data so my canvas can be uploaded to Azure Blob Storage from AngularJS front end to Node/Express backend?

推荐答案

我有一个测试项目可以解决您的需求.我认为应该注意几个关键点.

I had a test project to work out your requirements. And there are several key points I think should be noticed.

节点/快速后端部分:

要在Express中获取POST数据,我们可以利用曾经用作Express框架内部部分的bodyParser中间件.

To get POST data in Express, we can leverage bodyParser middle-ware which is used to be internal part of Express framework.

var bodyParser = require('body-parser');
var router = express.Router();
router.use(bodyParser.json());
router.use(bodyParser.urlencoded({ extended: false }));
router.post('/postCanvas', function (req, res, next){
   var filename = req.body.filename;
    var file = req.body.file;
    var base64Data;
    fileBuffer = decodeBase64Image(file);
   blobsrv.createBlockBlobFromText('container', filename, fileBuffer.data, {'contentType': fileBuffer.type}, function (error, result, response) {
        if (!error) {
            console.log("Uploaded" + result);
       }
        else {
            console.log(error);
        }
    });
    /*
    fs.writeFileSync('upload/' + filename, fileBuffer.data);
    blobsrv.createBlockBlobFromLocalFile('container', filename, 'upload/' + filename, function (error, result, response) {
        if (!error) {
            console.log("Uploaded" + result);
        // file uploaded
        }
        else {
            console.log(error);
        }
    });*/
})
function decodeBase64Image(dataString) {
    var matches = dataString.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/),
        response = {};

    if (matches.length !== 3) {
        return new Error('Invalid input string');
    }

    response.type = matches[1];
    response.data = new Buffer(matches[2], 'base64');

    return response;
}

取消注释部分将通过base64字符串直接创建blob,注释部分将首先将图像另存为服务器上的文件,然后通过该文件创建blob.

The uncomment part will directly create a blob by base64 string, and the comment part will save the image as a file on server first, then create a blob by the file.

如果您的服务器托管在Azure上,则可能会遇到CROS问题.因此,我们需要允许在express.js框架中使用corss起源的资源.

Maybe you will meet CROS problem if your server is hosted on Azure. So we need to allow corss-origin resource sharing in express.js framework.

这是我的代码段:

app.use(function (req, res, next) {
    res.setHeader("Access-Control-Allow-Origin", "http://localhost:8801");
    res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With,   Content-Type, Accept");
    res.setHeader('Access-Control-Allow-Credentials', true);
    res.setHeader('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
    next();
});

棱角部分与您相同:

$scope.upload = function () {
        var canvasImage = document.getElementById("myCanvas");
        var img = canvasImage.toDataURL("image/jpeg");
        var filename = 'Texture_0.jpg';
        console.log(img);
        console.log(filename);
        $http.post('http://localhost:1337/postCanvas', { filename: filename, file: img }).success(function (data) {
            console.log(data);
        },function(err){
            console.log(err);
        });
    }

这篇关于使用Node/Express将HTML5画布转换为图像上传到Azure的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆