服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服务器之家 - 编程语言 - JAVA教程 - spring(java,js,html) 截图上传图片实例详解

spring(java,js,html) 截图上传图片实例详解

2020-05-27 11:12小静1234 JAVA教程

这篇文章主要介绍了spring(java,js,html) 截图上传图片实例详解的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下

html

?
1
<#-- 上传头像 测试页 使用imgareaselect 插件 -->

最后 上传了这个插件 共学习参考

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
<link rel="stylesheet" type="text/css" href="${frontRes}/imgareaselect/css/imgareaselect-animated.css" />
<link rel="stylesheet" type="text/css" href="${frontRes}/imgareaselect/css/index.css" />
<script type="text/javascript" src="${frontRes}/imgareaselect/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="${frontRes}/imgareaselect/jquery.imgareaselect.pack.js"></script>
<script type="text/javascript" src="${frontRes}/imgareaselect/ajaxfileupload.js"></script>
<script>
function addFile(obj){
//document.getElementById('img').src = path;
$.ajaxFileUpload({
url:'${huluUrl}/trainer/upload/ajaxUpload', //用于文件上传的服务器端请求地址
secureuri: false, //是否需要安全协议,一般设置为false
fileElementId: 'photoFile', //文件上传域的ID
dataType: 'json', //返回值类型 一般设置为json
success: function (data){//服务器成功响应处理函数
var infoArray = eval("("+data+")"); //包数据解析为json格式
var arr = infoArray.data;
$("#img").attr("src","/images/"+arr.photo);
},
error: function (){//服务器响应失败处理函数
alert('与服务器通信失败,请稍后再试!');
parent.location.reload();
}
});
}
function preview(img, selection) {
if (!selection.width || !selection.height)
return;
//预览
var scaleX = 100 / selection.width;
var scaleY = 100 / selection.height;
//var imgx = document.getElementById("photo").style.width;
var imgx = parseInt($("#photo").css("width").split("px")[0]);
var imgy = parseInt($("#photo").css("height").split("px")[0]);
console.debug(imgx+"===="+imgy);
$('#preview img').css({
width : Math.round(scaleX * imgx),
height : Math.round(scaleY * imgy),
marginLeft : -Math.round(scaleX * selection.x1),
marginTop : -Math.round(scaleY * selection.y1)
});
$('#x1').val(selection.x1);
$('#y1').val(selection.y1);
$('#x2').val(selection.x2);
$('#y2').val(selection.y2);
$('#w').val(selection.width);
$('#h').val(selection.height);
//后台数据
$('#x1s').val(selection.x1);
$('#y1s').val(selection.y1);
$('#x2s').val(selection.x2);
$('#y2s').val(selection.y2);
$('#imgx').val(parseInt(imgx));//原图width宽度
$('#imgy').val(parseInt(imgy));//原图高度height
}
$(function(selection) {
var imgx = $("#photo").css("width").split("px")[0];
var imgy = $("#photo").css("height").split("px")[0];
var ares = 0;
console.debug(imgx+"===="+imgy);
if(imgx>imgy){
ares = imgy;
}else{
ares = imgx;
}
var ias = $('#photo').imgAreaSelect({
aspectRatio : '1:1',
handles : true,
fadeSpeed : 200,
onSelectChange : preview,
instance : true
});
ias.setSelection(0, 0, ares-1, ares-1);//初始化选择区域
ias.setOptions({
show : true
});
ias.update();
$(".imgareaselect-outer").css("cursor","Crosshair");
$(".imgareaselect-outer").css("background-color","rgba(255,255,255,0.9)");
//预览
var scaleX = 100 / ares;
var scaleY = 100 / ares;
$('#preview img').css({
width : Math.round(scaleX * imgx),
height : Math.round(scaleY * imgy),
marginLeft : -Math.round(scaleX * 0),
marginTop : -Math.round(scaleY * 0)
});
//后台数据
$('#x1s').val(0);
$('#y1s').val(0);
$('#x2s').val(ares-1);
$('#y2s').val(ares-1);
$('#imgx').val(imgx);//原图width宽度
$('#imgy').val(imgy);//原图高度height
});
</script>
<div class="container" style="margin-top:20px;">
<div class="row">
<div class="col-xs-9 pull-right">
<div class="media media-heading">
<h4 style="font-weight: 600;float: left">上传照片</h4>
</div>
<div class="row" style="margin-top: 15px">
<div class="col-lg-12">
<div class="btn-group" style="float: left">
<div class="btn btn-default" role="button" style="position: relative; overflow: hidden;background-color: #8DC21F;color: #ffffff;">
<span>+添加照片</span>
<input id="photoFile" type="file" name="photoFile" onchange="addFile(this);" style="height:34px;position: absolute; right: 0px; top: 0px; margin: 0px; padding: 0px; cursor: pointer; opacity: 0;">
</div>
</div>
<span style="float: left; margin-left: 15px; color: #888888">
<ul>
<li>建议本人照片</li>
<li>只支持JPG、PNG、GIF,大小不超过5M</li>
</ul>
</span>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="shangchuantouxiang">
<img src="/images/${(trainer.photo)!""}" alt="..." id ="img" class="img-circle" style="width: 320px; height: 320px">
</div>
</div>
</div>
<form action ="${huluUrl}/trainer/upload/uploadPhotoTest" method="post" enctype="multipart/form-data" >
<input type="text" id="x1s" name = "x1s" value="-" />
<input type="text" id="y1s" name = "y1s" value="-" />
<input type="text" id="x2s" name = "x2s" value="-" />
<input type="text" id="y2s" name = "y2s" value="-" />
<input type="text" id="imgx" name = "imgx" value="-" />
<input type="text" id="imgy" name = "imgy" value="-" />
<div class="row" style="margin-top: 15px; margin-left: 80px">
<div class="col-lg-5">
<div class="btn-group">
<button type="button" class="btn btn-default"id="chongxinshangchuan">重新上传</button>
</div>
<div class="btn-group">
<button type="submit" class="btn btn-default" id="baocun"> 保存 </button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<div id="root">
<div id="main">
<div class="container demo">
<div style="float: left; width: 50%;">
<p class="instructions">Click and drag on the image to select an area.</p>
<div style="width: 302px;height: 302px;">
<div style="width: 302px;height:302px;border: 1px solid #aaa;">
<div style="line-height: 300px; text-align: center; overflow: hidden; z-index: 1001; width: 300px; height: 300px; position: relative; left: 50%; top: 50%; margin-left: -150px; margin-top: -150px; ">
<img id="photo" src="/images/${(trainer.photo)!""}" style="max-height:300px;max-width: 300px;" />
</div>
</div>
</div>
</div>
<div style="float: left; width: 50%;">
<p style="font-size: 110%; font-weight: bold; padding-left: 0.1em;">Selection Preview</p>
<div style="width: 100px; height: 100px;">
<div id="preview" style="width: 100px; height: 100px; overflow: hidden;">
<img src="/images/${trainer.photo!}" style="width: 100px; height: 100px;" />
</div>
</div>
<table>
<thead>
<tr>
<th colspan="2" style="font-size: 110%; font-weight: bold; text-align: left; padding-left: 0.1em;">Coordinates</th>
<th colspan="2" style="font-size: 110%; font-weight: bold; text-align: left; padding-left: 0.1em;">Dimensions</th>
</tr>
</thead>
<tbody>
<tr>
<td style="width: 10%;"><b>X<sub>1</sub>:</b></td>
<td style="width: 30%;"><input type="text" id="x1" value="-" /></td>
<td style="width: 20%;"><b>Width:</b></td>
<td><input type="text" value="-" id="w" /></td>
</tr>
<tr>
<td><b>Y<sub>1</sub>:</b></td>
<td><input type="text" id="y1" value="-" /></td>
<td><b>Height:</b></td>
<td><input type="text" id="h" value="-" /></td>
</tr>
<tr>
<td><b>X<sub>2</sub>:</b></td>
<td><input type="text" id="x2" value="-" /></td>
<td></td>
<td></td>
</tr>
<tr>
<td><b>Y<sub>2</sub>:</b></td>
<td><input type="text" id="y2" value="-" /></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>

java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//显示图片需要在服务端配置一个虚拟路径
(tomcat) server.xml
<Context debug="0" docBase="G:\Image" path="/images" reloadable="true"/>
回显一下数据
[java] view plain copy 在CODE上查看代码片派生到我的代码片
/**
* 跳到上传头像2(可截取图片)
*
* @return
*/
@RequestMapping(value = "toUploadPhoto", method = RequestMethod.GET)
public ModelAndView toUploadTest() {
ModelAndView mav = leftMenu("/trainer/upload/uploadPhoto");
//
Trainer trainer = null;
try {
Long userId = FrontShiroUtil.getUserId();
if (null != userId) {
trainer = trainerRepo.findOne(userId);
trainerDbSvc.updateLastLoginTime(userId);
}
} catch (Exception e) {
e.printStackTrace();
}
mav.addObject("trainer", trainer);
return mav;
}
// 局部刷新上传图片
@RequestMapping("/ajaxUpload")
public @ResponseBody AjaxResult ajaxUpload(MultipartHttpServletRequest request) {
Trainer trainer = new Trainer();
// 获得第1张图片(根据前台的name名称得到上传的文件)
MultipartFile file = request.getFile("photoFile");
if (file.getSize() != 0) {
// 获得文件名:
String filename = file.getOriginalFilename();
String timeType = null;
if (null != filename && !filename.equals("")) {
String imgtype = filename.substring(filename.lastIndexOf("."));
// 获取路径
String ctxPath = "E:/rudongImage/photo/";
// 创建文件
File dirPath = new File(ctxPath);
if (!dirPath.exists()) {
dirPath.mkdirs();
}
// 以时间为文件名
Date date = new Date();
SimpleDateFormat sdformat = new SimpleDateFormat("yyyyMMddHHmmss");// 24小时制
String LgTime = sdformat.format(date);
timeType = LgTime + imgtype;
File uploadFile = new File(ctxPath + timeType);
try {
FileCopyUtils.copy(file.getBytes(), uploadFile);
} catch (IOException e) {
e.printStackTrace();
}
}
String headPhotoPath = "photo/" + timeType;
trainer.setPhoto(headPhotoPath);
}
try {
// 根据UserId查询培训师
Long userId = FrontShiroUtil.getUserId();
if (null != userId) {
trainer.setUserId(userId);
// 更新培训师头像
trainerDbSvc.updateTrainerPhoto(trainer);
}
} catch (Exception e) {
e.printStackTrace();
}
return AjaxResult.createSuccess(trainer);//<span style="font-family: Arial, Helvetica, sans-serif;">AjaxResult 可修改</span>
}
/**
* 截取区域上传图片测试
*
* @return
*/
@RequestMapping(value = "uploadPhotoTest", method = RequestMethod.POST)
public ModelAndView uploadPhotoTest(MultipartHttpServletRequest request, @RequestParam("x1s") Integer x1,
@RequestParam("y1s") Integer y1, @RequestParam("x2s") Integer x2, @RequestParam("y2s") Integer y2,
@RequestParam("imgx") Integer imgWidth, @RequestParam("imgy") Integer imgHeight) {
ModelAndView mav = leftMenu("redirect:/trainer/upload/toUploadPhoto");
Trainer trainer = null;
try {
// 根据UserId查询培训师
Long userId = FrontShiroUtil.getUserId();
if (null != userId) {
trainer = trainerRepo.findOne(userId);
}
} catch (Exception e) {
e.printStackTrace();
}
File uploadFile = new File("E:/rudongImage/" + trainer.getPhoto());
InputStream is = null;
BufferedImage src = null;
int w = -1;
int h = -1;
try {
is = new FileInputStream(uploadFile);
src = javax.imageio.ImageIO.read(is);
w = src.getWidth(null); // 得到源图宽
h = src.getHeight(null); // 得到源图高
is.close();
} catch (Exception e) {
e.printStackTrace();
}
Integer l = 0;
// 以小边为准(原图尺寸)
if (w < h) {
l = w;
} else {
l = h;
}
// 以小边为准(缩略图尺寸)
Integer l2 = 0;
if (imgWidth < imgHeight) {
l2 = imgWidth;
} else {
l2 = imgHeight;
}
Integer x = (x1 * l) / l2;// 起点x
Integer y = (y1 * l) / l2;// 起点y
Integer xs = (x2 * l) / l2;// 终点x 对角线位置
Integer ys = (y2 * l) / l2;// 终点y 对角线位置
ImageUtil imageUtil = new ImageUtil();
// 返回截取后的文件名
String photoName = "";
imageUtil.cutImage(uploadFile, "E:/rudongImage/photo/", x, y, xs - x, ys - y);
String headPhotoPath = "photo/" + photoName;
trainer.setPhoto(headPhotoPath);
// 更新培训师头像
trainerDbSvc.updateTrainerPhoto(trainer);
return mav;
}

工具类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 图片截取工具类
*/
public class ImageUtil {
private Logger log = LoggerFactory.getLogger(getClass());
private static String DEFAULT_THUMB_PREVFIX = "thumb_";
private static String DEFAULT_CUT_PREVFIX = "cut_";
private static Boolean DEFAULT_FORCE = false;
/**
* <p>Title: cutImage</p>
* <p>Description: 根据原图与裁切size截取局部图片</p>
* @param srcImg 源图片
* @param output 图片输出流
* @param rect 需要截取部分的坐标和大小
*/
public void cutImage(File srcImg, OutputStream output, java.awt.Rectangle rect){
if(srcImg.exists()){
java.io.FileInputStream fis = null;
ImageInputStream iis = null;
try {
fis = new FileInputStream(srcImg);
// ImageIO 支持的图片类型 : [BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG, JPEG, WBMP, GIF, gif]
String types = Arrays.toString(ImageIO.getReaderFormatNames()).replace("]", ",");
String suffix = null;
// 获取图片后缀
if(srcImg.getName().indexOf(".") > -1) {
suffix = srcImg.getName().substring(srcImg.getName().lastIndexOf(".") + 1);
}// 类型和图片后缀全部小写,然后判断后缀是否合法
if(suffix == null || types.toLowerCase().indexOf(suffix.toLowerCase()+",") < 0){
log.info("Sorry, the image suffix is illegal. the standard image suffix is {}." + types);
return ;
}
// 将FileInputStream 转换为ImageInputStream
iis = ImageIO.createImageInputStream(fis);
// 根据图片类型获取该种类型的ImageReader
ImageReader reader = ImageIO.getImageReadersBySuffix(suffix).next();
reader.setInput(iis,true);
ImageReadParam param = reader.getDefaultReadParam();
param.setSourceRegion(rect);
BufferedImage bi = reader.read(0, param);
ImageIO.write(bi, suffix, output);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fis != null) fis.close();
if(iis != null) iis.close();
if(output != null) output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}else {
log.info("the src image is not exist.");
}
}
public void cutImage(File srcImg, OutputStream output, int x, int y, int width, int height){
cutImage(srcImg, output, new java.awt.Rectangle(x, y, width, height));
}
public void cutImage(File srcImg, String destImgPath, java.awt.Rectangle rect){
File destImg = new File(destImgPath);
if(destImg.exists()){
String p = destImg.getPath();
try {
if(!destImg.isDirectory()) p = destImg.getParent();
if(!p.endsWith(File.separator)) p = p + File.separator;
cutImage(srcImg, new java.io.FileOutputStream(p + DEFAULT_CUT_PREVFIX + "_" + new java.util.Date().getTime() + "_" + srcImg.getName()), rect);
} catch (FileNotFoundException e) {
log.info("the dest image is not exist.");
}
}else log.info("the dest image folder is not exist.");
}
public void cutImage(File srcImg, String destImg, int x, int y, int width, int height){
cutImage(srcImg, destImg, new java.awt.Rectangle(x, y, width, height));
}
public void cutImage(String srcImg, String destImg, int x, int y, int width, int height){
cutImage(new File(srcImg), destImg, new java.awt.Rectangle(x, y, width, height));
}
/**
* <p>Title: thumbnailImage</p>
* <p>Description: 根据图片路径生成缩略图 </p>
* @param imagePath 原图片路径
* @param w 缩略图宽
* @param h 缩略图高
* @param prevfix 生成缩略图的前缀
* @param force 是否强制按照宽高生成缩略图(如果为false,则生成最佳比例缩略图)
*/
public void thumbnailImage(File srcImg, OutputStream output, int w, int h, String prevfix, boolean force){
if(srcImg.exists()){
try {
// ImageIO 支持的图片类型 : [BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG, JPEG, WBMP, GIF, gif]
String types = Arrays.toString(ImageIO.getReaderFormatNames()).replace("]", ",");
String suffix = null;
// 获取图片后缀
if(srcImg.getName().indexOf(".") > -1) {
suffix = srcImg.getName().substring(srcImg.getName().lastIndexOf(".") + 1);
}// 类型和图片后缀全部小写,然后判断后缀是否合法
if(suffix == null || types.toLowerCase().indexOf(suffix.toLowerCase()+",") < 0){
log.info("Sorry, the image suffix is illegal. the standard image suffix is {}." + types);
return ;
}
log.info("target image's size, width:{}, height:{}.",w,h);
Image img = ImageIO.read(srcImg);
// 根据原图与要求的缩略图比例,找到最合适的缩略图比例
if(!force){
int width = img.getWidth(null);
int height = img.getHeight(null);
if((width*1.0)/w < (height*1.0)/h){
if(width > w){
h = Integer.parseInt(new java.text.DecimalFormat("0").format(height * w/(width*1.0)));
log.info("change image's height, width:{}, height:{}.",w,h);
}
} else {
if(height > h){
w = Integer.parseInt(new java.text.DecimalFormat("0").format(width * h/(height*1.0)));
log.info("change image's width, width:{}, height:{}.",w,h);
}
}
}
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics g = bi.getGraphics();
g.drawImage(img, 0, 0, w, h, Color.LIGHT_GRAY, null);
g.dispose();
// 将图片保存在原目录并加上前缀
ImageIO.write(bi, suffix, output);
output.close();
} catch (IOException e) {
System.out.println("generate thumbnail image failed."+e);
}
}else{
System.out.println("the src image is not exist.");
}
}
public void thumbnailImage(File srcImg, int w, int h, String prevfix, boolean force){
String p = srcImg.getAbsolutePath();
try {
if(!srcImg.isDirectory()) p = srcImg.getParent();
if(!p.endsWith(File.separator)) p = p + File.separator;
thumbnailImage(srcImg, new java.io.FileOutputStream(p + prevfix +srcImg.getName()), w, h, prevfix, force);
} catch (FileNotFoundException e) {
log.info("the dest image is not exist."+e);
}
}
public void thumbnailImage(String imagePath, int w, int h, String prevfix, boolean force){
File srcImg = new File(imagePath);
thumbnailImage(srcImg, w, h, prevfix, force);
}
public void thumbnailImage(String imagePath, int w, int h, boolean force){
thumbnailImage(imagePath, w, h, DEFAULT_THUMB_PREVFIX, DEFAULT_FORCE);
}
public void thumbnailImage(String imagePath, int w, int h){
thumbnailImage(imagePath, w, h, DEFAULT_FORCE);
}
public void readUsingImageReader(String src, String dest, int w, int h)throws Exception {
// 取得图片读入器
Iterator readers = ImageIO.getImageReadersByFormatName("png");
ImageReader reader = (ImageReader) readers.next();
// 取得图片读入流
InputStream source = new FileInputStream(src);
ImageInputStream iis = ImageIO.createImageInputStream(source);
reader.setInput(iis, true);
// 图片参数
ImageReadParam param = reader.getDefaultReadParam();
// 100,200是左上起始位置,300就是取宽度为300的,就是从100开始取300宽,就是横向100~400,同理纵向200~350的区域就取高度150
// Rectangle rect = new Rectangle(100, 200, 300, 150);//
int hh = 0;
if (h > 100)
hh = (h - 100) / 3;
Rectangle rect = new Rectangle(0, hh, 227, 100);
param.setSourceRegion(rect);
BufferedImage bi = reader.read(0, param);
ImageIO.write(bi,"jpg", new File(dest));
}
public static void main(String[] args) throws Exception {
//new ImageUtil().thumbnailImage("imgs/Tulips.jpg", 150, 100);
//new ImageUtil().cutImage("imgs/Tulips.jpg","imgs", 250, 70, 300, 400);
//new ImageUtil().readUsingImageReader("e://rudongImage/photo/20160302090226.png", "e://rudongImage/photo/2.png", 227, 163);
}
}

xml配置

?
1
2
3
4
5
6
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- one of the properties available; the maximum file size in bytes
<property name="maxUploadSize" value="9999999999"/>
-->
</bean>

插件连接

http://download.csdn.net/download/u014596302/9572377

样式没调 有点丑功能都有。

spring(java,js,html) 截图上传图片实例详解

原文链接:http://blog.csdn.net/u014596302/article/details/51873369

延伸 · 阅读

精彩推荐