onlineSchool 项目课 四 :对项目图片的处理
一,实现图片的预览。
1, 标签预留图片上传的位置。
<img id="imagePreview" style="width: 220px;height: 90px;background-size: contain;background-image: url('/file/attachment/${(entity.picture)!}/0');">
2,选择的input,可以选择图片文件。
<input id="file" type="file" style="margin-top: 3px">
3,设置隐藏的input 可以把图片数据提交到后台。
<input id="recommendPicture" type="hidden">
4,jquery 的 change事件判断有没有选择图片文件。取出文件名。
验证上传的是否是图片文件。photoValid:检查文件名是以JPG,JEPG,PNG结尾。
5,使用jQuery获取图片文件的内容。
6,processImageFile:处理图片的内容。传入图片文件的内容,把内容读成数据,读到内存,读到img标签,读到Java代码。
7,通过css把图片数据显示出来。把图片数据设置到隐藏的 input。
$("#file").change(function (evt) {let f = $('#file').val()if (_os.photoValid(f)){let file = $("#file").get(0).files[0]_os.processImageFile(file,function (r) {$("#imagePreview").css('background-image','url('+r.image+')');$("#imagePreview").show();$("#recommendPicture").val(r.data)})}})
8,提交 form 表单,因为图片的数据量大,form表单中使用post提交。
<form id="recommendForm" class="panel-body" action="${base}/mergeRecommend" method="post">
$("#recommendForm").submit()
二,完成图片资源的入库。
recommend picture 栏的数字= attachment的id,可以获取到对应的attachment数据
获取到attachment的 resourceId,获取到resource,获取到resource的content。
1,controller中接收前端提交的图片数据,判断前端有没有提交图片数据。有提交图片的数据:就调用方法,创建图片的资源表,附件表。方法中传入图片的数据,和哪个单元上传的图片来源名称,返回图片附件表的id。将 id 设置到对应的添加或修改的对象。
if (StringUtils.isNotBlank(recommendPicture)){Long atId = attachmentService.createAttachment("recommendPicture",recommendPicture);entity.setPicture(atId.toString());}
2,在事务中创建图片的资源表,附件表。
HashUtils 获取图片的Hash值。(每一张图片的数据都有独一无二的hash值。) getByHash 查询数据库的图片资源表,判断图片资源是否已存在于数据库。不存在就创建图片资源表的数据。
@Transactionalpublic Long createAttachment(String name,String recommendPicture){String hash = HashUtil.sha256(recommendPicture);Resource r = resourceDao.getByHash(hash);if (null == r){r = new Resource();r.setId(IdUtil.nextId());r.setEncoding("Base64");r.setHash(hash);r.setContent(recommendPicture);r.setCreateAt(new Date());r.setUpdateAt(new Date());this.resourceDao.create(r);}
使用domain创建数据库表的数据。创建图片的资源表resource表的数据:
图片资源的id使用 IdUtils 自动生成。
编码格式使用Base64编码。
设置图片资源的hash值。
前端传过来的图片数据作为图片内容。
设置当前时间,作为创建和更新图片资源的时间。
create方法创建图片资源表数据。
3,创建图片资源的附件表。
由于前端提交过来的图片数据都是经过编码的,所以要对图片的数据进行解码,返回到char数组中,使用base64对图片数据解码。
ImageUtils 读取解码后的图片数据。图片的宽高,大小数据,返回到 ImageBean 中。
使用domain创建数据库表的数据。创建图片资源附件表attachment表。设置attachment表字段的值。create方法创建图片附件表的数据,返回attachment的id。
byte[] data = Base64.getDecoder().decode(recommendPicture);ImageBean bean = ImageUtil.readImage(data);Attachment a = new Attachment();a.setResourceId(r.getId());a.setUserId(0L);a.setName(name);a.setHeight(bean.height);a.setWidth(bean.width);a.setMime(bean.mime);a.setSize(bean.size);a.setCreateAt(new Date());a.setUpdateAt(new Date());this.entityDao.create(a);return a.getId();}
ImageBean封装图片宽高大小格式的数据。
public class ImageBean {public BufferedImage image;public int width;public int height;public int size;public String mime;}
4,在controller中判断没有图片数据传过来时,为什么不把图片的数据设为0?
@RequestMapping("/mergeRecommend")public ModelAndView mergeRecommend(Recommend entity,String recommendPicture){//修改以后重定向到课程推荐页面ModelAndView mv = new ModelAndView("redirect:/manage_recommend");//处理图片的数据if (StringUtils.isNotBlank(recommendPicture)){Long atId = attachmentService.createAttachment("recommendPicture",recommendPicture);entity.setPicture(atId.toString());}//保存修改或添加的数据到数据库if(null == entity.getId()){if (StringUtils.isBlank(recommendPicture)){entity.setPicture("0");this.recommendService.create(entity);}}else {this.recommendService.update(entity);}return mv;}
因为修改时也可以不修改图片的数据,也没有图片的数据传过来,这样设置会把原先上传好的图片直接改掉,判断创建时不允许picture为空就可以了。
5,两种方式可以实现图片的加载,需不需要 ${base} 容易搞混
<img id="imagePreview" src="${base}/file/attachment/${item.picture!}/m" />
<div style="background-image: url('/file/attachment/${item.picture!}/m');background-size: contain"></div>
三,定义一个公共的,加载项目所有图片的controller,FileController。
1,FileController介绍:
id 的正则表达式:对传入的 picture 数字作限制。[0-9] 表示传入的内容必须是数字,{1~17} 表示有1 至17位数字。
通过get请求,请求(“/file/attachment/” + ID + “/0”)地址,可以直接请求到图片,在相应的位置上写上对应的url地址,就可以把图片显示出来。
但是在修改时获取图片内容,要做 if 判断,判断图片数据是否存在且不等于0。因为创建时不允许picture为空,如果用户没有上传图片,图片数据会设置成0,添加到数据库。或者如果没有图片数据,就展示一个默认的图片。
char类型 size的含义:0原图,m最小图,s小图(有些网站会对图片数据做压缩)
通过responseIO流,把图片输出出来,有输出流要抛 IOE异常。
直接拷贝使用。
@Controller
public class FileController {protected static final String ID = "{id:[0-9]{1,17}}";@AutowiredAttachmentService attachmentService;//原图@GetMapping("/file/attachment/" + ID + "/0")public void process0(@PathVariable("id")long id, HttpServletResponse response) throws IOException {process(id,'0', response);}void process(long id, char size, HttpServletResponse response) throws IOException{DownloadBean bean = attachmentService.downloadAttachment(id,size);response.setContentType(bean.mime);response.setContentLength(bean.data.length);response.setHeader("Cache-Control", "max-age=" + 3600*24*30);ServletOutputStream output = response.getOutputStream();output.write(bean.data);output.flush();}
}
在process中,调用获取图片加载数据和格式的方法。设置输出的内容格式,内容长度,对内容做缓存,减少对服务器流量的影响。通过 outputStream 输出图片的数据,刷新,实现图片的加载。
2,如何获取图片加载的数据和格式
downloadBean 封装图片加载的数据和格式。
public class DownloadBean {public final String mime;public final byte[] data;public DownloadBean(String mime, byte[] data) {this.mime = mime;this.data = data;}
DownloadBean bean = attachmentService.downloadAttachment(id,size);
通过请求过来的 picture 数字,也就是attachment的id,可以获取到对应的 attachment 数据。
根据 attachment 的 resourceId,获取到 resource,获取到resource的content,对resource的content做解码。
获取的过程中可能会出现读取图片的异常,用自定义的异常类,APIException,使用 ApiErro 检测用户上传的是不是图片内容。
获取到attachment中图片的格式,和解码的图片资源数据,返回一个封装的downloadBean。
public DownloadBean downloadAttachment(Long id,char size){Attachment a = entityDao.getById(id);if (null == a){throw new ApiException(ApiError.PARAMETER_INVALID,"id","resource is not found");}Resource r = resourceDao.getById(a.getResourceId());if (null == r){throw new ApiException(ApiError.PARAMETER_INVALID,"id","resource is not found");}byte[] data = Base64.getDecoder().decode(r.getContent());if(size == '0'){return new DownloadBean(a.getMime(),data);}
onlineSchool 项目课 四 :对项目图片的处理相关推荐
- vue 加载页面时触发时间_解析Vue项目的四个方面优化
在本篇文章里我们给大家整理了一篇关于优化VUE项目的四个总要点,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. 运行时优化 1.使用v-if代替v ...
- 201671030111 李蓉 实验十四 团队项目评审课程学习总结
项目 内容 这个作业属于哪个课程 软件工程 这个作业的要求在哪里 实验十四 团队项目评审&课程学习总结 作业学习目标 掌握软件项目评审会流程,反思总结课程学习内容. 任务一:结合本学期课程学习 ...
- 201671010417 金振兴 实验十四 团队项目评审课程学习总结
项目 内容 软件工程 https://www.cnblogs.com/nwnu-daizh/ 作业要求 https://www.cnblogs.com/sunmiaokun/p/11095027.ht ...
- 201671030107 胡文艳 实验十四 团队项目评审课程项目总结
项目 内容 这个作业属于哪个课程 2016级计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 实验十四 团队项目评审&课程学习总结 作业学习目标 1.掌握软件项目评审会议流程 ...
- 201671030116 宋菲菲 实验十四 团队项目评审课程学习总结
项目 内容 作业所属课程 所属课程 作业要求 作业要求 课程学习目标 (1)掌握软件项目评审会流程:(2)反思总结课程学习内容 任务一:团队项目审核已完成.项目验收过程意见表已上交. 任务二:课程学习 ...
- 实验十四 团队项目评审课程学习总结
项目 内容 这个作业属于哪个课程? 2016级计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里? 实验四 软件工程结对项目 作业学习目标是? (1)掌握软件项目评审会流程:(2)反思 ...
- 第四部分 项目范围管理
转载自: 图片地址 目录 一 范围管理基本概念 二 范围管理过程 三 规划范围管理 四 收集需求 五 定义范围 六 创建WBS 七 确认范围 八 控制范围 一 范围管理基本概念 范围:确定要做什么 ...
- 201671010402-陈靖 实验十四 团队项目评审课程学习总结
项目 内容 任课教师博客主页链接 https://www.cnblogs.com/nwnu-daizh/ 作业要求链接地址 https://www.cnblogs.com/nwnu-daizh/p/1 ...
- 201671010426 孙锦喆 实验十四 团队项目评审课程学习总结
项目 内容 这个作业属于哪个课程 2016计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 实验十四 团队项目评审&课程学习总结 作业学习目标 (1)掌握软件项目评审会流程 ...
最新文章
- 微信小程序(canvas)画图保存到本地相册(wepy)
- 树状数组 ---- 树状数组+动态维护前缀中位数 D. Omkar and Medians
- Python中字符串切片详解
- 常用开源Jabber服务器介绍
- MySQL调优(五):MySQL查询优化分析
- 几种限流器(RateLimiter)原理与实现
- Alibaba Cloud Linux 2 开源后又有什么新动作?
- AD19自动布线出错,有些线未连接
- python手机版做小游戏代码大全-20行python代码的入门级小游戏的详解
- CISSP考试心得分享
- pppoe网络无法使用 zmap
- html svg 线条动画,HTML5 SVG简单的动态绘制轮廓线条动画插件
- Failing OffsetCommit request since the consumer is not part of an active group
- c语言飞机源代码,C语言写的飞机源码
- java pdf 修改内容_生成PDF全攻略之在已有PDF上添加内容的实现方法
- 【运筹学】指派问题匈牙利法
- git中push和pull的区别是什么
- 使用AW9523B芯片驱动16路LED时,LED出现误点亮的问题
- 周末愉快:洗碗就是洗碗
- PJSIP开源库详解