前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Egg上传图片与使用 Jimp 生成缩略图

Egg上传图片与使用 Jimp 生成缩略图

作者头像
越陌度阡
发布2020-11-26 10:47:06
1.6K0
发布2020-11-26 10:47:06
举报

1. 定义模板文件

代码语言:javascript
复制
<form action="/admin/focus/doAdd?_csrf=<%=csrf%>" method="post" enctype="multipart/form-data">
    <ul>
        <li> 分类:<select name="type" id="type" style="width:300px;height:26px">
                <option value="1">网站</option>
                <option value="2">APP</option>
                <option value="3">小程序</option>
            </select>
        </li>
        <li>名称:<input type="text" name="title" style="width:300px;height:26px" /></li>
        <li>链接:<input type="text" name="link" style="width:300px;height:26px" /></li>
        <li>上传:<input type="file" name="focus_img" style="width:300px;height:26px;" /></li>
        <li>排序:<input type="text" name="sort" value="1000" style="width:300px;height:26px" /></li>
        
        <li style="display:flex;flex-direction:row;"> 
            状态:     
            <input type="radio" name="status" checked value="1" id="a" style="margin-right:10px" ; />
            <label for="a" style="margin-right:10px">显示</label>
            <input type="radio" name="status" value="0" id="b" style="margin-right:10px" />
            <label for="b" style="margin-right:10px">隐藏</label>   
        </li>

        <li>
            <button type="submit" class="btn btn-primary">提交</button>
        </li>
    </ul>
</form>

2. 定义上传图片数据库的model

代码语言:javascript
复制
// app/model/focus.js

module.exports = app => {
    const mongoose = app.mongoose;
    const Schema = mongoose.Schema;
    // 配置轮播图和Schema
    const now = (new Date()).getTime();
    const FocusSchema = new Schema({
        title: { type: String },
        type: { type: Number },
        focus_img: { type: String },
        link: { type: String },
        sort: { type: Number },
        status: { type: Number, default: 1 },
        add_time: {
            type: Number,
            default: now
        }
    });

    return mongoose.model('Focus', FocusSchema, 'focus');
}

3. 配置上传路由

代码语言:javascript
复制
// router.js

'use strict';
module.exports = app => {
    const { router, controller } = app;
    router.post('/admin/focus/doAdd',controller.admin.focus.doAdd);
};

4. 配置上传地址、格式及大小设置

代码语言:javascript
复制
// config/config.default.js
'use strict';
module.exports = appInfo => {

    const config = exports = {};
    // use for cookie sign key, should change to your own and keep security
    config.keys = appInfo.name + '_1585450669767_9677';


    // 上传文件存放的全局地址
    config.uploadDir = 'app/public/admin/upload';

    // 上传文件的配置
    // https://github.com/eggjs/egg-multipart
    config.multipart = {
        // 允许上传的图片格式
        whitelist:['.png','.jpg','.jpeg'],
        // 文件允许大小
        fileSize:'50mb'
    }

    // 配置两种模板引擎(参考官方文档)
    config.view = {
        mapping: {
            '.html': 'ejs',
            '.nj': 'nunjucks'
        }
    }

    return config

};

5. 定义控制器

代码语言:javascript
复制
// app/controller/admin/focus.js

'use strict';
const Fs = require('fs');
// cnpm i mz-modules --save
// 此模块解决上传卡死
const Pump = require('mz-modules/pump');

const Controller = require('egg').Controller;

class FocusController extends Controller {

    // 添加轮播图提交
    async doAdd() {
        // autoFields: true 表示除了文件的其它字段
        let parts = this.ctx.multipart({ autoFields: true });
        let files = {}, stream;
        // 循环获取数据流
        while ((stream = await parts()) != null) {
            if (!stream.filename) {
                // 多文件上传时,只能break,不能return
                break;
            }
            // 文件表单的name
            let fieldname = stream.fieldname;

            // 获取上传文件路径与入库保存路径
            let dir = await this.service.tools.getUploadFile(stream.filename);
            // 上传路径
            let target = dir.uploadDir;

            // 写入上传文件
            let writeStream = Fs.createWriteStream(target);
            await Pump(stream, writeStream);

            // 将多个上传图片统一拼接为一个对象,便于访问
            files = Object.assign(files, {
                [fieldname]: dir.saveDir
            })

            // 生成缩略图 target为图片地址
            this.service.tools.jimpImg(target);
        }

        // 将上传的图片与提交的其它字段合并
        let focus = new this.ctx.model.Focus(Object.assign(files, parts.field));
        let result = await focus.save();

        // 对result做出结果判断(略)
        
        this.ctx.body={
            "message":"上传图片成功",
            "success":true
        }
    }

}
module.exports = FocusController;

6. 在控制器中需要调用的服务中的方法

代码语言:javascript
复制
// app/service/tools.js

'use strict';
const Path = require('path');
const Service = require('egg').Service;


// 引入格式化时间模块
// cnpm i silly-datetime --save
const Sd = require('silly-datetime');

// 引入模块智能生成上传文件夹
// cnpm i mz-modules --save
const Mkdirp = require('mz-modules/mkdirp');


// 引入生成缩略图的模块
// cnpm install jimp --save
// https://github.com/oliver-moran/jimp/tree/master/packages/jimp
const Jimp = require('jimp');


class ToolService extends Service {

    // 获取当前时间戳
    async getTime(){
        let now = new Date();
        return now.getTime();
    }

    // 处理要上传的文件名
    async getUploadFile(filename){
        // 获取当前日期
        let now = Sd.format(new Date(),'YYYYMMDD');
        // 创建文件目录(将存放地址与日期进行拼接);
        let dir = Path.join(this.config.uploadDir,now);
        // 按dir去创建文件夹,如果没有则生成,如果有则忽略
        await Mkdirp(dir);

        // 以时间戳命名文件
        let timestamp = await this.getTime();

        // 图片的保存路径(文件夹 + 时间戳 + 后辍名)
        let uploadDir = Path.join(dir,timestamp + Path.extname(filename));

        return{
            // 上传的地址
            uploadDir:uploadDir,
            // 保存在数据库的地址
            saveDir:uploadDir.slice(3).replace(/\\/g,'/')
        }
    }


    // 生成缩略图方法
    async jimpImg(target){
        Jimp.read(target, (err, lenna) => {
            if (err) throw err;
            // 生成200乘以200大小,品质为90,并重命名文件
            lenna.resize(200,200).quality(90).write(target+'_200x200'+Path.extname(target)); 
        })

    }

}

module.exports = ToolService;
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/04/09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档