美文网首页Node学习之路
Node.js学习第九天笔记之切图功能

Node.js学习第九天笔记之切图功能

作者: 果木山 | 来源:发表于2018-12-18 23:19 被阅读0次

    1 切图

    • 图像的裁切功能
      • 前提条件:下载安装GraphicsMagick
      • 模块:第三方模块gm模块;
      • 步骤:
        1. 引入模块;引入gm模块;var gm = require('gm');
        2. 使用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":"截图成功"})
                   }
               })
          

    2 扒网站,实现截图效果

    • 前端开发仓库
    • node.js实现切图;
      • 思路:
        • 发送get请求"/index",渲染页面;
        • 给按钮添加点击事件,在事件触发后,通过ajax发送get请求,将数据传到服务器;
        • 获取原代码中的截图元素,获取其宽高和定位left,top值;作为切图的数值;
        • 服务器拿到数据,通过gm模块进行裁切原图;然后保存;
        • 裁切成功后,响应给页面,通过ajax中success拿到数据,弹出提示,刷新页面;
      • 注意:
        • 必须在点击事件中,获取元素,拿到数据;不能再点击事件外拿,否则,拿到的数据均为0;
        • 如果图片在页面中被缩放,需要拿到比例,传给服务器,因为,服务器是在原图上裁切的;
      • 知识点:
        • 如果一个元素设置定位,在jQuery中通过$("xx").position().left$("xx").position().top来获取left和top值;
      • 代码:
        • 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;
      • 注意:必须在图片的目录下;运行命令;

    相关文章

      网友评论

        本文标题:Node.js学习第九天笔记之切图功能

        本文链接:https://www.haomeiwen.com/subject/junrkqtx.html