图片编辑增加压缩功能
This commit is contained in:
parent
9a23c6442a
commit
6ffd5f01f4
@ -3,11 +3,17 @@ package cn.com.tenlion.aishop.controller.api.goods;
|
||||
import cn.com.tenlion.aishop.pojo.dtos.goods.GoodsSimpleDTO;
|
||||
import cn.com.tenlion.aishop.pojo.vos.goods.GoodsCheckVO;
|
||||
import cn.com.tenlion.aishop.pojo.vos.goodslog.GoodslogVO;
|
||||
import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;
|
||||
import ink.wgink.annotation.CheckRequestBodyAnnotation;
|
||||
import ink.wgink.common.base.DefaultBaseController;
|
||||
import ink.wgink.common.component.SecurityComponent;
|
||||
import ink.wgink.exceptions.SaveException;
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.module.file.enums.UploadTypeEnum;
|
||||
import ink.wgink.module.file.service.IDefaultFileService;
|
||||
import ink.wgink.module.file.service.IFileService;
|
||||
import ink.wgink.pojo.ListPage;
|
||||
import ink.wgink.pojo.pos.FilePO;
|
||||
import ink.wgink.pojo.result.ErrorResult;
|
||||
import ink.wgink.pojo.result.SuccessResult;
|
||||
import ink.wgink.pojo.result.SuccessResultData;
|
||||
@ -15,13 +21,21 @@ import ink.wgink.pojo.result.SuccessResultList;
|
||||
import cn.com.tenlion.aishop.pojo.dtos.goods.GoodsDTO;
|
||||
import cn.com.tenlion.aishop.pojo.vos.goods.GoodsVO;
|
||||
import cn.com.tenlion.aishop.service.goods.IGoodsService;
|
||||
import ink.wgink.util.UUIDUtil;
|
||||
import io.swagger.annotations.*;
|
||||
import net.coobird.thumbnailator.Thumbnails;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @ClassName: GoodsController
|
||||
@ -39,6 +53,52 @@ public class GoodsController extends DefaultBaseController {
|
||||
private SecurityComponent securityComponent;
|
||||
@Autowired
|
||||
private IGoodsService goodsService;
|
||||
@Autowired
|
||||
private IFileService iFileService;
|
||||
@Autowired
|
||||
private IDefaultFileService iFileService2;
|
||||
@PostMapping({"upload-image"})
|
||||
public SuccessResultData<String> uploadFile(@RequestParam("file") MultipartFile file, Double picturesThumbnails) throws IOException {
|
||||
// 参数校验
|
||||
if (file.isEmpty()) {
|
||||
throw new SaveException("上传文件不能为空");
|
||||
}
|
||||
InputStream inputStream = file.getInputStream();
|
||||
BufferedImage bufferedImage = ImageIO.read(inputStream);
|
||||
if (bufferedImage == null) {
|
||||
throw new SaveException("无效的图片文件");
|
||||
}
|
||||
BufferedImage image = bufferedImage;
|
||||
if (picturesThumbnails != null) {
|
||||
try {
|
||||
image = Thumbnails.of(new BufferedImage[]{bufferedImage}).scale(1).outputQuality(picturesThumbnails / 100).outputFormat("jpg").asBufferedImage();
|
||||
} catch (IOException e) {
|
||||
throw new SaveException("图片压缩出现异常");
|
||||
}
|
||||
}
|
||||
MultipartFile file1 = new MockMultipartFile(
|
||||
"file", // 参数名(表单中的name)
|
||||
UUIDUtil.get32UUID() + ".jpg", // 原始文件名
|
||||
"image/jpeg",
|
||||
convertToInputStream(image, "jpg") // 文件输入流
|
||||
);
|
||||
Map<String, Object> params1 = new HashMap<>();
|
||||
String fileId1 = iFileService.uploadSingleByUserId(securityComponent.getCurrentUser().getUserId(), file1, UploadTypeEnum.IMAGE, params1);
|
||||
return new SuccessResultData(fileId1);
|
||||
}
|
||||
|
||||
public static InputStream convertToInputStream(BufferedImage image, String format) throws IOException {
|
||||
// 1. 创建字节数组输出流
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
|
||||
// 2. 将BufferedImage写入输出流(指定格式)
|
||||
if (!ImageIO.write(image, format, outputStream)) {
|
||||
throw new IOException("Unsupported image format: " + format);
|
||||
}
|
||||
|
||||
// 3. 转换为字节数组输入流
|
||||
return new ByteArrayInputStream(outputStream.toByteArray());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "置顶", notes = "置顶接口")
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
|
@ -14,6 +14,7 @@ import cn.com.tenlion.freemarker.util.TemplatePageUtil;
|
||||
import ink.wgink.annotation.CheckRequestBodyAnnotation;
|
||||
import ink.wgink.common.base.DefaultBaseController;
|
||||
import ink.wgink.common.component.SecurityComponent;
|
||||
import ink.wgink.exceptions.SaveException;
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.module.file.enums.UploadTypeEnum;
|
||||
import ink.wgink.module.file.pojo.vos.FileVO;
|
||||
@ -35,8 +36,10 @@ import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.ByteBuffer;
|
||||
@ -45,6 +48,7 @@ import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* @ClassName: OrderController
|
||||
@ -71,6 +75,75 @@ public class OrderController extends DefaultBaseController {
|
||||
private IFileService iFileService;
|
||||
@Autowired
|
||||
private IDefaultFileService iFileService2;
|
||||
|
||||
@ApiOperation(
|
||||
value = "上传文件",
|
||||
notes = "上传文件接口"
|
||||
)
|
||||
@ApiImplicitParams({@ApiImplicitParam(
|
||||
name = "file",
|
||||
value = "文件name",
|
||||
paramType = "query"
|
||||
)})
|
||||
@ApiResponses({@ApiResponse(
|
||||
code = 400,
|
||||
message = "请求失败",
|
||||
response = ErrorResult.class
|
||||
)})
|
||||
@PostMapping({"uploadfile"})
|
||||
public SuccessResultData<String> uploadFile(@RequestParam("file") MultipartFile file) {
|
||||
// 参数校验
|
||||
if (file.isEmpty()) {
|
||||
throw new SaveException("上传文件不能为空");
|
||||
}
|
||||
|
||||
// 文件类型校验(双重验证)
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
String contentType = file.getContentType();
|
||||
|
||||
if (originalFilename == null ||
|
||||
(!originalFilename.toLowerCase().endsWith(".jpg") &&
|
||||
!originalFilename.toLowerCase().endsWith(".jpeg"))) {
|
||||
throw new SaveException("文件类型必须为jpeg或jpg");
|
||||
}
|
||||
|
||||
if (contentType == null || !contentType.equalsIgnoreCase("image/jpeg")) {
|
||||
throw new SaveException("文件类型必须为jpeg或jpg");
|
||||
}
|
||||
|
||||
// 文件大小校验(200KB)
|
||||
long maxSize = 200 * 1024;
|
||||
if (file.getSize() > maxSize) {
|
||||
throw new SaveException("文件大小不能超过200KB");
|
||||
}
|
||||
|
||||
// 图片尺寸校验
|
||||
try {
|
||||
try (InputStream inputStream = file.getInputStream()) {
|
||||
BufferedImage image = ImageIO.read(inputStream);
|
||||
if (image == null) {
|
||||
throw new SaveException("无效的图片文件");
|
||||
}
|
||||
int width = image.getWidth();
|
||||
int height = image.getHeight();
|
||||
if (width < 500 || width > 1500 || height < 500 || height > 1500) {
|
||||
throw new SaveException( String.format("图片尺寸需在500×500至1500×1500之间,当前尺寸:%d×%d", width, height));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new SaveException("图片读取失败:" + e.getMessage());
|
||||
}
|
||||
// 其他参数处理(原代码中的params)
|
||||
Map<String, Object> params = this.requestParams();
|
||||
String fileId = iFileService.uploadSingleByUserId(securityComponent.getCurrentUser().getUserId(),
|
||||
file,
|
||||
UploadTypeEnum.IMAGE,
|
||||
params
|
||||
);
|
||||
return new SuccessResultData<>(fileId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 读取到字节数组
|
||||
* @param f 文件对象
|
||||
|
@ -49,9 +49,6 @@ public class GoodsonlineServiceImpl extends DefaultBaseService implements IGoods
|
||||
|
||||
@Override
|
||||
public SuccessResultList<List<GoodsSimpleDTO>> listPageAll(ListPage page) {
|
||||
if (page.getRows() > 12 ) {
|
||||
page.setRows(12);
|
||||
}
|
||||
Map<String, Object> params = page.getParams();
|
||||
if(params.get("goodsType") != null) {
|
||||
params.put("goodsTypes", Arrays.asList(params.get("goodsType").toString().split(",")));
|
||||
|
@ -338,7 +338,7 @@
|
||||
url: 'route/goods/image2?fileId='+ $('#goodsPhoto').val(),
|
||||
title: '上传软著上架电子版',
|
||||
width: '950px',
|
||||
height: '600px',
|
||||
height: '700px',
|
||||
onClose: function() {
|
||||
var uploadImage = localStorage.getItem('uploadImage');
|
||||
console.log('uploadImage', uploadImage);
|
||||
|
@ -9,7 +9,7 @@
|
||||
<link rel="stylesheet" type="text/css" href="assets/js/vendor/cropper/cropper.min.css"/>
|
||||
<style>
|
||||
.upload-image {height: 100%; opacity: 0;}
|
||||
.upload-image-preview {width: 200px;height: 200px;overflow: hidden;margin: 0 20px;display: inline-block;}
|
||||
.upload-image-preview {width: 200px;height: 200px;overflow: hidden;margin: 0 44px;display: inline-block;}
|
||||
#imageBox {height: 451px;overflow: auto;background-color: #F1F1F1;}
|
||||
#imagePreviewBox .upload-image-preview {background-color: #F1F1F1;}
|
||||
.cropper-container {
|
||||
@ -50,7 +50,6 @@
|
||||
<button type="button" class="btn btn-danger fa fa-refresh" onclick="reset()" title="重置图片"></button>
|
||||
<button id="mosaicBtn" type="button" class="btn btn-warning fa fa-th" onclick="toggleMosaic()" title="马赛克"></button>
|
||||
<button type="button" class="btn btn-info fa fa-reply" onclick="undoEdit()" title="撤销" id="undoBtn" disabled></button>
|
||||
|
||||
</div>
|
||||
<div class="col-xs-4" style="margin-top: 5px; text-align: center;">
|
||||
<div class="btn-group">
|
||||
@ -81,7 +80,13 @@
|
||||
<span id="mosaicSizeValue">10px</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12" style="margin-top: 5px; text-align: center;">
|
||||
<div class="form-group">
|
||||
<label for="imageSize">图片压缩:</label>
|
||||
<input type="range" id="imageSize" min="10" max="100" value="100" class="form-control">
|
||||
<span id="imageSizeValue">100%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="assets/js/jquery-3.5.1.min.js"></script>
|
||||
@ -458,7 +463,7 @@
|
||||
doUploadFile = function () {
|
||||
var loadLayerIndex;
|
||||
var formData = new FormData($('#uploadFileForm')[0]);
|
||||
restAjax.postFile('api/file/uploadimage', formData, {}, function (code, data) {
|
||||
restAjax.postFile('api/goods/upload-image', formData, {}, function (code, data) {
|
||||
dialog.msg('上传成功');
|
||||
cropper.replace('route/file/download/false/' + data.data, false);
|
||||
localStorage.setItem('uploadImage', data.data);
|
||||
@ -507,9 +512,10 @@
|
||||
|
||||
croppedCanvas.toBlob(function (cropBlob) {
|
||||
var formData = new FormData();
|
||||
formData.append("image", cropBlob);
|
||||
formData.append("file", cropBlob);
|
||||
formData.append("picturesThumbnails", $('#imageSize').val());
|
||||
var loadLayerIndex;
|
||||
restAjax.postFile('api/file/uploadimage', formData, {}, function (code, data) {
|
||||
restAjax.postFile('api/goods/upload-image', formData, {}, function (code, data) {
|
||||
dialog.msg('裁剪成功');
|
||||
|
||||
// 完全重置马赛克画布和历史记录
|
||||
@ -567,6 +573,11 @@
|
||||
$('#mosaicSizeValue').text(size + 'px');
|
||||
});
|
||||
|
||||
$('#imageSize').on('input', function() {
|
||||
var size = $(this).val();
|
||||
$('#imageSizeValue').text(size + '%');
|
||||
});
|
||||
|
||||
// 确保马赛克画布初始化
|
||||
setTimeout(function() {
|
||||
setupMosaicCanvas();
|
||||
|
Loading…
Reference in New Issue
Block a user