nodejs+express+canvas实现将经纬度转换坐标系并生成图片上传至七牛云

2022-10-22,,,,

node+canvas后台绘图功能

后台的canvas的使用不做详细说明。使用方式基本与前端使用一样,我主要说明一下自己在开发过程中遇到的一些坑

安装

npm install canvas

引入canvas到项目

const Canvas = require('canvas'); // 引入canvas模块
//第一步创建画布
const canvas = Canvas.createCanvas(200, 200)
const ctx = canvas.getContext('2d')
//第二步设置绘制线条颜色
ctx.strokeStyle = 'red'

let listArray = [[25,35],[26,37],[27,89],[40,79]]
listArray.map(x=>{
	ctx.lineTo(x[0],x[1])
})
ctx.closePath();
ctx.stroke();

// 获取图片
let getFile = canvas.toBuffer()

遇到的问题:

1. npm安装canvas模块 node-pre-gyp WARN Using needle for node-pre-gyp https download

解决方式:使用淘宝镜像安装canvas
npm install canvas --canvas_binary_host_mirror=https://npm.taobao.org/mirrors/node-canvas-prebuilt/

2.服务端部署时一定要检查gcc版本是否是4.7以上!

gcc -v

nodejs中对接七牛oss存储

这里基本没有什么问题,只要仔细看下七牛提供的开发文档就可以了,一下是连接
七牛云开发文档(nodejs)

需要注意的

七牛Zone对象千万别写错了,七牛目前只提供四个机房:华东(Zone_z0)、华北(Zone_z1)、华南(Zone_z2)、北美(Zone_na0)

综上实现将经纬度转换坐标系生成图片上传至七牛云整套代码

1.routes目录下创建一个upload.js文件

req.body 为调用你的接口所发送过来的数据 这个数据格式我会贴在代码下面

let express = require('express');
let router = express.Router();
let Canvas = require('canvas');
const fs = require('fs')
const path = require('path')

// 引入七牛模块  
let qiniu = require("qiniu");

/* GET users listing. */
router.post('/', function(req, res, next) {
  console.log(req.body)
  // req.body 为调用你的接口所发送过来的数据 
  console.log(req.ip)
  //要上传的空间名
  // let bucket = 'igy'; 
  let imageUrl = req.body.resImgUrl; // 域名名称
  let Zone = null
  switch (req.body.zone) { 
    case '华东':
      Zone = qiniu.zone.Zone_z0;
      break;
    case '华北':
      Zone = qiniu.zone.Zone_z1;
      break;
    case '华南':
      Zone = qiniu.zone.Zone_z2;
      break;
    case '北美':
      Zone = qiniu.zone.Zone_na0;
      break;
    default:
      Zone = null;
      break;
  }
  console.log(Zone)
  let accessKey = req.body.QNaccessKey;
  let secretKey = req.body.QNsecretKey;
  let mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
  let options = {
    scope: req.body.bucket,
    expires: 7200
  };
  let putPolicy = new qiniu.rs.PutPolicy(options);
  let uploadToken = putPolicy.uploadToken(mac);

  let config = new qiniu.conf.Config();
  config.zone = Zone;
  if (req.body.zone && req.body.strokeColor && req.body.bucket && req.body.QNaccessKey && req.body.QNsecretKey && req.body.bounds) {
    const Image = Canvas.Image
    const canvas = Canvas.createCanvas(200, 200)
    const ctx = canvas.getContext('2d')
    ctx.strokeStyle = req.body.strokeColor;
    let fillColor = null;
    
    
    let bounds = req.body.bounds
    let maxLongitude = 0;
    let minLongitude = 0;
    let maxLatitude = 0;
    let minLatitude = 0;
    bounds.map(x=>{
      // console.log(x)
      if (x[0] > maxLongitude) {
        maxLongitude = x[0]
        if (minLongitude == 0) { 
          minLongitude = x[0]
        }
      } else if (x[0] < minLongitude) { 
        minLongitude = x[0]
      }
      if (x[1] > maxLatitude) {
        maxLatitude = x[1]
        if (minLatitude == 0) {
          minLatitude = x[1]
        }
      } else if (x[1] < minLatitude) { 
        minLatitude = x[1]
      }
      // })
    })
    let xScale = 100 / Math.abs(maxLongitude - minLongitude)
    let yScale = 100 / Math.abs(maxLatitude - minLatitude)
    let scale = xScale < yScale ? xScale : yScale
    let xoffset=200/2.0-Math.abs(maxLongitude - minLongitude)/2*scale
    let yoffset=200/2.0-Math.abs(maxLatitude - minLatitude)/2*scale
    bounds.map(y => { 
      ctx.lineTo((y[0] - minLongitude) * scale+xoffset, (maxLatitude - y[1]) * scale+yoffset);
    })
    ctx.closePath();
    if (req.body.fillColor && req.body.fillColor != '') {
      fillColor = req.body.fillColor
      ctx.fillStyle=fillColor;
      ctx.fill();
    }
    ctx.stroke();
    // 构建图片名
    let fileName = Date.now() + '.png';
    if (req.body.fileName && req.body.fileName != '') { 
      fileName = req.body.fileName + '.png'
    }
    
    let filePath =  __dirname + '/'  + fileName;
    
    fs.writeFile(filePath, canvas.toBuffer(),(err)=>{
      if(err){
        res.json({status: 500, message: '图片保存失败'});
      } else {
        let localFile = filePath;
        let formUploader = new qiniu.form_up.FormUploader(config);
        let putExtra = new qiniu.form_up.PutExtra();
        let key = fileName;
        // 文件上传
        formUploader.putFile(uploadToken, key, localFile, putExtra, function(respErr,
          respBody, respInfo) {
          if (respErr) {
            res.json({status:'-2',message:'上传失败',error:respErr});   
          }
          // console.log(respInfo)
          if (respInfo.statusCode == 200) {
            let imageSrc = imageUrl + respBody.key;
            res.json({ status: '200', message: '上传成功', data: {imgUrl:imageSrc,hash:respBody.hash,imgName:respBody.key}}); 
          } else {
            res.json({status:'-1',message:'上传失败',error:JSON.stringify(respBody)});   
          }
          // 上传之后删除本地文件
          fs.unlinkSync(filePath);
        });
      }
    });
  }else{
    res.json({status: 401, message: '参数错误!',data:req.body});
  }
});

module.exports = router;

以下是请求参数

{
    "bounds": [
        [
            122.652281,
            45.244661
        ],
        [
            122.630859,
            45.236583
        ],
        [
            122.616037,
            45.258384
        ],
        [
            122.633296,
            45.270245
        ]
    ],
    "strokeColor": "red",
    "fillColor":"rgba(128, 100, 162, 0.7)",
    "bucket":"空间名称",
    "resImgUrl":"你的七牛配置的CNAME",
    "zone":"华南",
    "QNaccessKey":"七牛的accessKey",
    "QNsecretKey":"七牛的secretKey",
    "fileName":""
}

本文地址:https://blog.csdn.net/qq_41205069/article/details/112030509

《nodejs+express+canvas实现将经纬度转换坐标系并生成图片上传至七牛云.doc》

下载本文的Word格式文档,以方便收藏与打印。