提示:以下是本篇文章正文内容,下面案例可供参考
一、前端代码构建
<div class="product-info">
<div class="fl preview-wrap">
<!--放大镜效果-->
<div class="zoom">
<!--默认第一个预览-->
<div id="preview" class="spec-preview">
<span class="jqzoom">
<img jqimg="/img/table/b1.png" src="/img/table/s1.png" width="400px" height="400px"/>
</span>
</div>
<!--下方的缩略图-->
<div class="spec-scroll">
<a class="prev"><</a>
<!--左右按钮-->
<div class="items">
<ul>
<#list list as x>
<li><img src="${x.address}" bimg="${x.src}" onmousemove="preview(this)" /></li>
</#list>
</ul>
</div>
<a class="next">></a>
</div>
</div>
</div>
</div>
<form action="upload" method="post" enctype="multipart/form-data">
选择图片:<input type="file" name="file" accept="image/*" /> <br>
<input type="submit" value="立刻上传">
</form>
这里只是简单的前端代码,做的是一个freemarker的模板,数据库使用的是Oracle,使用了一些插件。具体效果如下图
具体数据如何插入下面会说明。
使用的css、js如下
<link rel="stylesheet" type="text/css" href="/sfsComponents/webbase.css" />
<link rel="stylesheet" type="text/css" href="/sfsComponents/pages-item.css" />
<link rel="stylesheet" type="text/css" href="/sfsComponents/pages-zoom.css" />
<link rel="stylesheet" type="text/css" href="/sfsComponents/widget-cartPanelView.css" />
<script src="/axios.min.js"></script>
<script src="/common.js"></script>
<script type="text/javascript" src="/model/cartModel.js"></script>
<script type="text/javascript" src="/plugins/jquery.easing/jquery.easing.min.js"></script>
<script type="text/javascript" src="/plugins/sui/sui.min.js"></script>
<script type="text/javascript" src="/plugins/jquery.jqzoom/jquery.jqzoom.js"></script>
<script type="text/javascript" src="/plugins/jquery.jqzoom/zoom.js"></script>
二、后端代码
用的是springboot框架
@Controller
public class TestController {
@Autowired
private Photo_twoService photo_twoService;
@Autowired
private Change change;
@RequestMapping("items")
public String Test(Model model) throws Exception {
List<S_PHOTO_TWO> all = photo_twoService.findAll();
model.addAttribute("list",all);
return "items";
}
@PostMapping("/upload") // 等价于 @RequestMapping(value = "/upload", method = RequestMethod.POST)
public String uplaod(HttpServletRequest req, @RequestParam("file") MultipartFile file, Model m) throws Exception {//1. 接受上传的文@RequestParam("file") MultipartFile file
try {
//2.根据时间戳创建新的文件名,这样即便是第二次上传相同名称的文件,也不会把第一次的文件覆盖了
String fileName = System.currentTimeMillis() + file.getOriginalFilename();
//将MultipartFile转为File
File files = new File(fileName);
OutputStream out = null;
try{
//获取文件流,以文件流的方式输出到新文件
out = new FileOutputStream(files);
byte[] ss = file.getBytes();
for(int i = 0; i < ss.length; i++){
out.write(ss[i]);
}
}catch(IOException e){
e.printStackTrace();
}finally {
if (out != null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//3.通过req.getServletContext().getRealPath("") 获取当前项目的真实路径,然后拼接前面的文件名
String destFileName = "C:\\sfs-common-dbcomponent-demo-four\\src\\main\\resources\\static\\img\\table\\" + fileName;
//缩略图别名
String fileName2 ="1" +fileName ;
//转为缩略图
Thumbnails.of(files).size(200,200).toFile("C:\\sfs-common-dbcomponent-demo-four\\src\\main\\resources\\static\\img\\table\\"+fileName2);
String saveFileName2 = "/img/table/" + fileName2;
String saveFileName = "/img/table/" + fileName;
//传入数据库,储存俩图的位置
photo_twoService.save(saveFileName2,saveFileName);
//4.第一次运行的时候,这个文件所在的目录往往是不存在的,这里需要创建一下目录(创建到了webapp下uploaded文件夹下)
File destFile = new File(destFileName);
destFile.getParentFile().mkdirs();
//5.把浏览器上传的文件复制到希望的位置
file.transferTo(destFile);
//灰度图
change.grayImage(files);
//转File操作会多出一个files文件,是多余的,这里进行删除
File f = new File(files.toURI());
if (f.delete()){
System.out.println("删除成功");
}else {
System.out.println("删除失败");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
return "上传失败," + e.getMessage();
} catch (IOException e) {
e.printStackTrace();
return "上传失败," + e.getMessage();
}
return Test(m);
}
}
我把所有的操作基本写在了controller,还未优化,service层和dao层的代码只是简单的数据库查询操作。
简单解析一下上面的代码
@RequestMapping("items")
public String Test(Model model) throws Exception {
List<S_PHOTO_TWO> all = photo_twoService.findAll();
model.addAttribute("list",all);
return "items";
}
这里是查询操作,数据库内放的是俩个图片(图片一个是大的,一个是缩略图的形式)的相对地址
//将MultipartFile转为File
File files = new File(fileName);
OutputStream out = null;
try{
//获取文件流,以文件流的方式输出到新文件
out = new FileOutputStream(files);
byte[] ss = file.getBytes();
for(int i = 0; i < ss.length; i++){
out.write(ss[i]);
}
}catch(IOException e){
e.printStackTrace();
}finally {
if (out != null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这里是一个MultipartFile转File的格式转换,在客户端进行图片导入的时候。用的是MultipartFile进行接受。转为File是为了Thumbnails的使用需要。
Thumbnails.of(files).size(200,200).toFile("C:\\sfs-common-dbcomponent-demo-four\\src\\main\\resources\\static\\img\\table\\"+fileName2);
这里就是 Thumbnails转缩略图的一个操作,只有一行代码,比较简单。files为转化的格式,size是转化后的图片大小,但是这里会根据你的图片进行自调,后面是生成缩略图后存放的路径
photo_twoService.save(saveFileName2,saveFileName);
将原图和缩略图路径放入数据库中,用于下次显示
这样子缩略图的形式就可以完成了,但是使用spring boot传入图片数据的时候,是需要重新启动服务器才会进行显示,不然他是不会自动加载加入配置里面,所以需要加入一个配置。
@Configuration
public class webConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
System.out.println("配置文件已经生效");
//关于图片上传后需要重启服务器才能刷新图片
//这是一种保护机制,为了防止绝对路径被看出来,目录结构暴露
//解决方法:将虚拟路径/images/
//向绝对路径 (C:\sfs-common-dbcomponent-demo-four\src\main\resources\static\img\table\\)映射
String path="C:\\sfs-common-dbcomponent-demo-four\\src\\main\\resources\\static\\img\\table\\";
registry.addResourceHandler("/img/table/**").addResourceLocations("file:"+path);
}
}
才可直接刷新显示
再说说灰度图,在上面的代码中,我用到了这个
//灰度图
change.grayImage(files);
原方法是这样子的
//传统灰度图
public void grayImage(File path) throws IOException {
File file = new File(String.valueOf(path));
BufferedImage image = ImageIO.read(file);
int width = image.getWidth();
int height = image.getHeight();
BufferedImage grayImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
for ( int i= 0 ; i < width ; i++){
for ( int j = 0 ; j < height; j++){
int rgb = image.getRGB(i, j);
grayImage.setRGB(i, j, rgb);
}
}
File newFile = new File(System.getProperty( "user.dir" )+ "/System.currentTimeMillis().jpg" );
ImageIO.write(grayImage, "jpg" , newFile);
File f = new File(file.toURI());
if (f.delete()){
System.out.println("删除成功");
}else {
System.out.println("删除失败");
}
}
这个是一个传统灰度图的做法,用到的是BufferedImage这个类,比较复杂。
现在说的是一个openCV的方式来做一个灰度图的效果,openCV这个包很复杂,这里只是简单说明一下灰度图的生成
这里用的是2.4.13这个版本,我试过4的版本,但是缺少了一个类包,找不到在那里,然后还是用回了2.4.13的版本
<dependency>
<groupId>org.opencv</groupId>
<artifactId>opencv-2413</artifactId>
<version>1.0.0</version>
</dependency>
具体代码如下
//openCV灰度图
public void openCVGrayImage(String file,String newfile){
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat img = Highgui.imread(file);
//路径不能带有中文字符,不然会报错
Imgproc.cvtColor(img, img, Imgproc.COLOR_RGB2GRAY);
Imgproc.adaptiveThreshold(img, img, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, 25, 10);
Highgui.imwrite(newfile+"\\new_image.png", img);
}
这里值得注意的是路径不能带中文字符。
这样子就可以做出灰度图了,具体的使用还在研究,但是功能已经可以实现了。