Node.js学习第九天笔记之切图功能
2018-12-18 本文已影响0人
果木山
1 切图
- 图像的裁切功能
- 前提条件:下载安装GraphicsMagick
- 模块:第三方模块gm模块;
- 步骤:
- 引入模块;引入gm模块;
var gm = require('gm');
- 使用gm();
- gm括号中为需要裁切的图片的地址,
- resize()为裁切后的宽高,里面设置"!",则为强制,按照设置大小生成文件,否则,等比例生成文件;
- crop()为裁切的尺寸,分别为宽,高,左边距,上边距;
- write("path",function(err){}):指的是生成文件放置的地址和名称,匿名函数中设置裁切成功后的操作;
- 代码:
var gm = require('gm'); gm("./img/meinv.jpg") .crop(240,100,720,415) .resize(200, 200,"!")//强制变为200*200的文件; .write("./img/meinv2.jpg",function (err) { if(err){ res.send({"bok":false,"msg":err}); }else{ res.send({"bok":true,"msg":"截图成功"}) } })
- 引入模块;引入gm模块;
2 扒网站,实现截图效果
- 前端开发仓库
- 网站地址:前端开发仓库
- 在网站上扒下截图的文件;jQuery Jcrop 图像裁剪
- node.js实现切图;
- 思路:
- 发送get请求"/index",渲染页面;
- 给按钮添加点击事件,在事件触发后,通过ajax发送get请求,将数据传到服务器;
- 获取原代码中的截图元素,获取其宽高和定位left,top值;作为切图的数值;
- 服务器拿到数据,通过gm模块进行裁切原图;然后保存;
- 裁切成功后,响应给页面,通过ajax中success拿到数据,弹出提示,刷新页面;
- 注意:
- 必须在点击事件中,获取元素,拿到数据;不能再点击事件外拿,否则,拿到的数据均为0;
- 如果图片在页面中被缩放,需要拿到比例,传给服务器,因为,服务器是在原图上裁切的;
- 知识点:
- 如果一个元素设置定位,在jQuery中通过
$("xx").position().left
和$("xx").position().top
来获取left和top值;
- 如果一个元素设置定位,在jQuery中通过
- 代码:
- ejs中自己写的script代码:
<script> //必须在点击事件触发后,在获取元素拿值,否则,无法拿到值; $("#btn").click(function () { var $img=$("#target"); var imgw=$img.width(); var bl=1366/imgw;//获取到一个比例; var $div=$(".jcrop-holder>div:eq(0)"); var w=$div.width()*bl; var h=$div.height()*bl; var l=$div.position().left*bl; var t=$div.position().top*bl; $.ajax({ url:"/jietu", type:"get", data:{w,h,l,t}, success:function (val) { if(val.bok){ alert(val.msg); window.location.href="/index";//更新页面; }else{ console.log(val.msg); } } }) }) </script>
- 服务器代码:
const express=require("express"); const fs=require("fs"); const gm=require("gm"); const app=express(); app.listen(8080); //设置ejs模板引擎 app.set("view engine","ejs"); //设置静态资源目录 app.use(express.static("./public"));//此静态资源是为了引入css和js等; //设置静态资源目录 app.use(express.static("./img"));//此静态资源是为了引入图片; //发送请求渲染页面; app.get("/index",function (req, res) { res.render("index"); }); //ajax发送请求,截图 app.get("/jietu",function (req, res) { //获取到参数值 var {w,h,l,t}=req.query; //切图 gm("./img/meinv.jpg") .crop(w,h,l,t) .write("./img/meinv2.jpg",function (err) { if(err){ res.send({"bok":false,"msg":err}); }else{ res.send({"bok":true,"msg":"截图成功"}) } }) });
- 思路:
3 封装后的裁图文件
- 封装后的文件
- 文件存储github地址:cutImg
- 服务器cutapp.js
//1.express三步创建服务器基本构架 const express=require("express"); const app=express(); app.listen(3333,function () { console.log("3333 server is running"); }); //2.引入node系统模块 const path=require("path"); const fs=require("fs"); //3.引入第三方模块 const formidable=require("formidable"); const sd=require("silly-datetime"); const gm=require("gm"); //4.设置ejs模板引擎 app.set("view engine","ejs"); //5.设置静态资源目录 //1)加载ejs文件中的css,js等静态资源 app.use("/public",express.static("./public")); //2)加载uploads文件夹中上传的图片 app.use("/uploads",express.static("./uploads")); //3)加载avatar文件夹上的裁切后的图片 app.use("/avatar",express.static("./avatar")); //6.设置路由 //1)加载上传文件目录 app.get('/tofile',function (req, res, next) { res.render('tofile',{}); }); //2)提交上传文件数据 app.post('/todata',function (req, res, next) { //新建form对象 var form=new formidable.IncomingForm(); //设置文件上传路径 form.uploadDir="./uploads/"; //解析上传的文件参数 form.parse(req,function (err, fields, files) { if(err){ console.log('formidble错误'); return; } var oldPath=files.myfile.path; var originName=files.myfile.name; var originNameObj=path.parse(originName); var newName="gms"+sd.format(new Date(),"YYYYMMDD_HHmmss")+originNameObj.ext; var newPath=form.uploadDir+newName; //更换上传的文件路径和名字 fs.rename(oldPath,newPath,function (err) { if(err){ console.log('图片重命名失败'); return; } res.send({'bok':true,'msg':'上传图片成功!!!','imgsrc':newName}); }); }) }); //3)渲染裁切图页面 app.get('/showcutimg',function (req, res, next) { var cutimgSrc=req.query.cursrc; res.render('mycut',{ imgsrc:cutimgSrc }) }); //4)裁切图片 app.get('/cutimg',function (req, res, next) { var curobj=req.query; gm("./uploads/"+curobj.imgsrc) .crop(curobj.w,curobj.h,curobj.x,curobj.y) .resize(curobj.xsize,curobj.ysize,"!") .write("./avatar/"+curobj.imgsrc,function (err) { if(err){ res.send({"bok":false,"msg":err}); }else{ res.send({"bok":true,"msg":"截图成功"}) } }); });
- 上传页面tofile.ejs
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <title>文件上传页面</title> <!-- Bootstrap --> <link href="/public/vender/bootstrap/css/bootstrap.css" rel="stylesheet"> <!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 --> <!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 --> <!--[if lt IE 9]> <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script> <![endif]--> </head> <body> <div class="container files"> <div class="row"> <form class="form-horizontal col-xs-4 col-xs-offset-4"> <div class="form-group"> <h1 style="margin-top: 150px">请上传图像</h1> <label for="myimg">上传文件</label> <input type="file" id="myimg" name="myfile"> <div class="checkbox"> <label> <input type="checkbox"> Check me out </label> </div> <button type="button" class="btn btn-primary" id="toBtn">上传</button> </div> </form> </div> </div> <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) --> <script src="/public/vender/jquery/jquery.js"></script> <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 --> <script src="/public/vender/bootstrap/js/bootstrap.js"></script> <script> //通过ajax上传file文件信息 $('#toBtn').on('click',function () { //获取form表单的数据 var formData=new FormData(); formData.append('myfile',$('#myimg')[0].files[0]) //ajax发送请求 $.ajax({ url: '/todata', type: 'POST', data:formData, dataType: 'json', contentType: false,//不需要头; processData: false,//不转换数据 success: function (data) { alert(data.msg); window.location.href='/showcutimg?cursrc='+data.imgsrc; }, error: function (err) { console.log(err); } }) }) </script> </body> </html>
- 裁切页面cutimg.ejs
<!DOCTYPE html> <html lang="en"> <head> <title>截图页面</title> <meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> <script src="/public/js/jquery.min.js"></script> <script src="/public/js/jquery.Jcrop.js"></script> <script src="/public/js/jquery-cut.js"></script> <script src="/public/js/mycut.js"></script> <link rel="stylesheet" href="/public/css/main.css" type="text/css" /> <link rel="stylesheet" href="/public/css/demos.css" type="text/css" /> <link rel="stylesheet" href="/public/css/jquery.Jcrop.css" type="text/css" /> <link rel="stylesheet" href="/public/css/jquery-cut.css" type="text/css" /> <link rel="stylesheet" href="/public/css/mycut.css" type="text/css" /> <style rel="stylesheet" type="text/css"> #preview-pane .preview-container{ width: 200px; height: 200px; } .jcrop-holder #preview-pane{ top: 30%; right: -300px; } </style> </head> <body> <div class="container"> <div class="row"> <div class="span12"> <div class="jc-demo-box"> <img src="/uploads/<%= imgsrc%>" data-imgsrc="<%= imgsrc%>" id="target" alt="cuttu" /> <div id="preview-pane"> <div class="preview-container"> <img src="/uploads/<%= imgsrc%>" class="jcrop-preview" alt="Preview" /> </div> </div> <div class="description"> <button id="btn">提交截图</button> </div> <div class="clearfix"></div> </div> </div> </div> </div> </body> <script> //必须先声明 var curobj; $("#btn").click(function () { curobj.imgsrc=$("#target").data("imgsrc"); $.ajax({ url:"/cutimg", type:"get", data:curobj, dataType: "json", success:function (val) { if(val.bok){ alert(val.msg); window.location.href="/tofile";//裁切成功后,跳转回上传文件页面 }else{ console.log(val.msg); } }, error:function (err) { console.log(err); } }) }); </script> </html>
- 项目介绍
1.项目介绍:完成图片上传到裁切的功能; 2.项目依赖 express gm ejs formidable silly-datetime 3.项目运行 1)下载node,运行cutapp.js服务器 2)网页地址:http://localhost:3333/tofile 加载上传文件页面 4.目录分析 uploads: 图片上传后的地址 avatar: 图片裁切后,保存的地址
4 知识点
- gm的一些命令
- 显示图像文件详细信息:
gm identify a.jpg
; - 格式转换:
gm convert a.jpg a.png
; - 注意:必须在图片的目录下;运行命令;
- 显示图像文件详细信息: