楔子
写一个CMS或者博客,其中一个环节就是附件管理功能,附件又包含了图片、视频等多媒体文件,还包括压缩包啊、文档等文件,而在附件管理功能当中,又以文件的上传为核心。
Golang自带有gzip的工具可以进行压缩,但是在web项目当中其实是不建议使用的。由于前后端的原因,所以程序控制上传文件大小,让用户自行压缩到是一种比较好的方式。
在图片和视频方面,除了上传之外,展示也是一个很重要的方面,为了呈现效果及效率,这时候就需要进行图片压缩、缩略图、视频转码等操作。
对应Google在java中的thumbnail工具类,在Golang里面也有一款针对图片处理的工具类,就是Imaging.v1.6.0,咱们今天就来看看搭配Bootstrap-FileInput.v5.0.0前端上传工具和缩略图生成及保存的相关功能。
忽略没有显示的图片吧,那是因为我把本地图片删掉了,但是数据库里面没有清除的原因。
Bootstrap-FileInput
这是一个超级好用且颜值很高的前端上传工具,同时支持多语言,目前是5.0的版本,使用起来非常简单。
首先定义引入js和css
<!-- bootstrap-fileinput插件 -->
<script src="/static/plugins/bootstrap-fileinput/js/fileinput.js"></script>
<script src="/static/plugins/bootstrap-fileinput/js/locales/zh.js" type="text/javascript"></script>
<!-- bootstrap-fileinput插件 -->
<link href="/static/plugins/bootstrap-fileinput/css/fileinput.css" rel="stylesheet"/>
注意上面两个js文件的引用顺序
然后在html里面的目标位置把容器放进去
<!-- 文件上传面板 -->
<div class="row" id="uploadForm" style="display: none;">
<div class="col-md-12">
<form enctype="multipart/form-data">
<div class="file-loading">
<input id="uploadImg" name="fileImageUrl" type="file" multiple>
</div>
</form>
</div>
</div>
最后在script里面初始化这个容器,并定义好上传方法及回调方法
//初始化上传面板
$('#uploadImg').fileinput({
language: 'zh',//设置显示语言为中文
uploadUrl: '{{ urlfor "AttachController.UploadFile" }}',//设置上传路径
uploadAsync: true,//设置开启异步上传
allowedFileExtensions: ['jpg', 'gif', 'png', 'jpeg', 'svg', 'psd'],//设置允许使用的文件类型
maxFileCount: 100,//设置上传文件数
enctype: 'multipart/form-data',
autoOrientImage: false,
showClose: false,
multiple: true,//设置同时上传多个文件
uploadExtraData: {
'uploadToken': 'SOME-TOKEN', // for access control / security
},
}).on('filebatchuploadcomplete', function (event, preview, config, tags, extraData) {
$(".fileinput-remove-button").click();
$("#uploadForm").hide(400)
window.location.reload();
});
Imaging
这是基于Golang的图片处理工具,首先来下载Imaging:
go get -u github.com/disintegration/imaging
然后你就会发现…. 报错信息,你可能会认为是网络有点慢,毕竟咱们连接github一向很慢。但是我跟你说,不用白费力气了,只要你在国内,你下载的一定是会报错的…原因,嗯,你应该知道原因是什么了。
在io.go这个文件里,引用了一个被墙掉的主包golang.org/x
这个包除非挂VPN否则就不用白费力气了,它包含了两个子包:
"golang.org/x/image/bmp"
"golang.org/x/image/tiff"
分别是处理位图和tiff的处理方法,所以我的做法是...不处理这两类文件...
直接打包下载最新的release版本,把文件夹直接拖到项目根目录当中,注释掉这两个引用和相关方法,嗯,岁月静好。
使用方法非常简单:
//读取图片文件
imgData, _ := ioutil.ReadFile(filePath)
//字节流
buf := bytes.NewBuffer(imgData)
imagedecode, err := imaging.Decode(buf)
if err != nil {
fmt.Println(err)
return
}
//定义图片保存地址
thumbnail := "static/upload/" + year + "/" + month + "/thumbnail/small-" + timestamp + h.Filename
//生成缩略图,尺寸256*256,并保存
image := imaging.Resize(imagedecode, 256, 256, imaging.Lanczos)
//保存缩略图
err = imaging.Save(image, thumbnail)
if err != nil {
fmt.Println(err)
}
使用详见注释,首先读出文件流,转为图片类型,然后开始生成缩略图,最后保存,然后把缩略图路径等相关信息保存在数据库即可。
需要注意的是,如果你之前尝试过go get imaging
那么这里主要import
的时候要选择你项目里面的,如果选下载的那个残次品,是会报错的,或者说,记得删除那个残次品。
Pagination.js
这是一个Jquery的分页插件,我们用它来实现图片动态分页显示,他支持多种数据源,也可以发起请求从后端拿数据,不过咱们既然使用了beego,那么就直接在后台把数据注入Data里面,这里就可以直接使用了,使用方法和bootstrap-fileinput类似:
首先定义引入js和css
<!-- 前台分页插件 -->
<script src="/static/plugins/pagination/pagination.js"></script>
<!-- 分页插件 -->
<link href="/static/plugins/pagination/pagination.css" rel="stylesheet"/>
然后在html里面的目标位置把容器放进去
<!-- 文件显示面板 -->
<div id="wrapper">
<section>
<div class="data-container"></div>
<div id="pagination"></div>
</section>
</div>
最后在script里面初始化这个容器,并定义好上传方法及回调方法
//一次性取出json文件,然后分页显示
$(function () {
(function (name) {
var container = $('#pagination');//指定容器
var options = {
dataSource: {{ .json.rows}},//设置数据源,模版引擎语法
pageSize: 12,//设置单页多少个
hideWhenLessThanOnePage: true,
className: 'paginationjs-theme-silvery paginationjs-small',//样式类
callback: function (response, pagination) {
//循环生成html div
var dataHtml = '<div class="row" style="margin-top: 10px">';
$.each(response, function (index, item) {
dataHtml += '<div class="col-lg-2 col-md-3 col-sm-6 col-xs-6 div-thumbnail">' +
'<a href="javascript:void(0)" class="thumbnail"><img src="/' + item.Thumbnail
+ '" class="img-responsive"></li></a></div>';
});
dataHtml += '</div>';
container.prev().html(dataHtml);
}
};
container.pagination(options);
})('pagination');
})
注意pagination的样式里面没有银色,他的蓝色有些太丑,所以我直接在文件里面添加了银色样式:
@Silvery_color_base: #dddddd;
@Silvery_color_font: @Silvery_color_base;
@Silvery_color_border: @Silvery_color_base;
@Silvery_bgColor_active: @Silvery_color_base;
@Silvery_bgColor_hover: #E9F4FC;
@Silvery_bgColor_buttonHover: #e3e3e3;
所以如果想用的朋友可以参考上面这个写自己的颜色样式
尾巴
很久不写代码了,重新搭一套平台看起来容易,实现起来还是很多东西需要做的,尤其是利用业余时间来做,我也不知道多久能做完,每天下班后的状态也不一样,只能说,即便做不完,也就当学习Golang了吧。
有疑问加站长微信联系(非本文作者)