图片处理
Thumbnails
在进行Java开发时可以使用Thumbnails工具类对图片进行处理,旋转、裁剪、格式转换、加水印等。
使用步骤
导包
<dependency><groupId>net.coobird</groupId><artifactId>thumbnailator</artifactId><version>0.4.8</version></dependency>
方法
1.读入源图片
能够批量处理,多个文件或者文件夹:
Thumbnails.of(BufferedImage... images)
从BufferedImage
读入源;
Thumbnails.of(File... files)
从文件或者文件夹读入源;
Thumbnails.of(InputStream... inputStreams)
从流读入源;
Thumbnails.of(String... files)
Thumbnails.of(URL... urls)
2.设置大小,按比例或者拉伸
.size(int width, int height)
按比例,使原图撑满size大小;
.width(int width)
设置宽,高按比例;
.height(int height)
设置高,宽按比例;
.forceSize(int width, int height)
设置宽高,不按比例,会按照设置的宽高拉伸;
.scale(double scale)
按比例缩放,0~1缩小,1原比例,>1放大;
.scale(double scaleWidth, double scaleHeight)
长宽各自设置比例,会拉伸;
.scalingMode(ScalingMode config)
缩放模式(ScalingMode枚举BICUBIC、BILINEAR、PROGRESSIVE_BILINEAR);
.keepAspectRatio(boolean keep)
设置是否按比例,false不按比例;
注:size、width/height、scale、forceSize不能并用;size至关于width+height;forceSize关于设置长款+keepAspectRatio=false,因此forceSize不能跟其余设置长款属性、keepAspectRatio并用;
3.剪裁
.sourceRegion(int x, int y, int width, int height)
剪裁原图,坐标x,y起始,剪裁出宽度width高度height的图像,x向右为正,y向下为正,width(向右)和height(向下)必须大于0;
.sourceRegion(Position position, int width, int height)
剪裁原图,区域位置position可用Positions枚举的9个位置或者实现Position接口的实现类;
.sourceRegion(Position position, Size size)
.sourceRegion(Rectangle region)
.sourceRegion(Region sourceRegion)
.crop(Position position)
剪裁生成的缩略图,按照size设定剪裁;
4.旋转
.rotate(double angle)
旋转角度,顺时针为正;
5.水印
.watermark(BufferedImage image)
中心位置50%透明度设置水印;
.watermark(BufferedImage image, float opacity)
中心位置,opacity的不透明度设置水印(0.0<=opacity<=1.0);
.watermark(Position position, BufferedImage image, float opacity)
在position位置,opacity不透明度设置水印;
.watermark(Watermark w)
6.质量
.outputQuality(double quality)
质量0.0<=quality<=1.0;
.outputQuality(float quality)
7.输出格式
.outputFormat(String format)
设置输出格式(可用ImageIO.getWriterFormatNames()
得到支持的格式),[JPG, jpg, bmp, BMP, gif, GIF, WBMP, png, PNG, wbmp, jpeg, JPEG];
.outputFormatType(String formatType)
.useOriginalFormat()
使用原图格式;
8.输出图片
.asBufferedImage()
返回BufferedImage
对象;
.asBufferedImages()
返回多个BufferedImage
对象;
.asFiles(Rename rename)
返回文件列表,并按照重命名规则生成文件(Rename抽象类属性:Rename.NO_CHANGE 名称不变,Rename.PREFIX_DOT_THUMBNAIL 名称前缀“thumbnail.”,Rename.PREFIX_HYPHEN_THUMBNAIL 名称前缀“thumbnail-”,Rename.SUFFIX_DOT_THUMBNAIL 名称后缀“.thumbnail”,Rename.SUFFIX_HYPHEN_THUMBNAIL 名称后缀“-thumbnail”);
.asFiles(File destinationDir, Rename rename)
返回文件列表,并按照指定的重命名规则生成到指定目录里(文件夹要存在);
.asFiles(Iterable<File> iterable)
.toFile(File outFile)
无返回,写入文件里(若是没有后缀名会自动添加,下同);
.toFile(String outFilepath)
.toFiles(File destinationDir, Rename rename)
无返回,按照重命名规则生成到文件夹里;
.toFiles(Iterable<File> iterable)
.toFiles(Rename rename)
.toOutputStream(OutputStream os)
无返回,写入outputStream里;
.toOutputStreams(Iterable<? extends OutputStream> iterable)
.allowOverwrite(boolean allowOverwrite)
设置是否覆盖已存在的文件(只对toFile、toFiles、asFiles有效);
示例:
Thumbnails.of(image).size(200, 300).toFile(filePathAndName);//指定大小进行缩放Thumbnails.of(image).scale(0.25f).toFile(filePathAndName);//指定比例进行缩放Thumbnails.of(image).size(120, 120).keepAspectRatio(false).toFile(filePathAndName);//不按照比例指定大小进行缩放.rotate(90)//旋转 rotate(角度),正数:顺时针 负数:逆时针.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("images/watermark.png")), 0.5f) // watermark(位置,水印图,透明度).sourceRegion() // 裁剪.outputFormat("png") //转化图像格式Thumbnails.of(image).scale(0.25f).toOutputStream(os); //输出到OutputStreamThumbnails.of(image).scale(0.25f).asBufferedImage(); //输出到BufferedImage
阿里云OSS文件上传
简介
阿里云对象存储服务,简称 OSS,是一种面向海量数据规模的分布式存储服务。
注册开通略
配置OSS
AccessKey
创建Bucket
学习使用API
/document_detail/31948.html?spm=5176.208357.1107607.18.1e88390fheeEwP
导包
<dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.10.2</version></dependency>//如果使用的是Java 9及以上的版本,则需要添加jaxb相关依赖。添加jaxb相关依赖示例代码如下:<dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version></dependency><dependency><groupId>javax.activation</groupId><artifactId>activation</artifactId><version>1.1.1</version></dependency><!-- no more than 2.3.3--><dependency><groupId>org.glassfish.jaxb</groupId><artifactId>jaxb-runtime</artifactId><version>2.3.3</version></dependency>
初始化配置
application.properties
#阿里云 OSS#不同的服务器,地址不同 ==前面后面都不能加空格!!!!!!!!!!!!!!!!!1aliyun.oss.endpoint=oss-cn-aliyun.oss.accessKeyId=LTAI5t7hmUCakcQsHTSedsfEaliyun.oss.accessKeySecret=PwAZRnMx4p5GKFFF2ksdsaffdsiG#bucket可以在控制台创建,也可以使用java代码创建aliyun.oss.bucketName=greatbrookaliyun.oss.url=https://greatbrook.oss-cn- //文件存储地址
以用户上传头像为例
头像链接headerUrl保存在user表中,用户在网页选择并上传头像时
1.后端接收headerImage,并判断接收文件是否为jpg或png文件,不是则返回"文件格式不正确"。
2.使用Thumbnails工具对传入的图片进行处理,压缩图片尺寸,并输出BufferedImage对象。
3.根据配置创建文件上传客户端,使用OSSClientBuilder()。
4.上传处理过后的图片inputStream,更改文件名。关闭客户端。
5.将返回的用户头像路径写入user表。
用户表
用户表 user
user_mapper.xml
<update id="updateHeader">update User set header_url = #{headerUrl} where id = #{id}</update>
UserMapper
@Mapperpublic interface UserMapper {User selectById(int id);User selectByName(String username);User selectByEmail(String email);int insertUser(User user);int updateStatus(int id,int status);int updateHeader(int id, String headerUrl);int updatePassword(int id, String password);}
UserService
@Servicepublic class UserService{//更新头像 引入redis缓存user所以要先更新再清除缓存 不然会引起mysql和redis的冲突public int updateHeader(int userId, String headerUrl) {//return userMapper.updateHeader(userId, headerUrl); mysql实现方式int rows = userMapper.updateHeader(userId, headerUrl);clearCache(userId);return rows;}}
UserController
private static final Logger logger = LoggerFactory.getLogger(UserController.class);//导入相关路径@Value("${community.path.upload}")private String uploadPath;@Value("${community.path.domain}")private String domain;@Value("${server.servlet.context-path}")private String contextPath;@Value("${aliyun.oss.endpoint}")private String endpoint;@Value("${aliyun.oss.accessKeyId}")private String accessKeyId;@Value("${aliyun.oss.accessKeySecret}")private String accessKeySecret;@Value("${aliyun.oss.bucketName}")private String bucketName;@Value("${aliyun.oss.url}")private String url;//文件存储目录private String filedir = "header/";@Autowiredprivate UserService userService;@Autowiredprivate HostHolder hostHolder;//上传头像@LoginRequired@RequestMapping(path = "/upload",method = RequestMethod.POST)public String uploadHeader(MultipartFile headerImage, Model model){if (headerImage.isEmpty()){model.addAttribute("error","您还没有选择图片!");return "/site/setting";} //如果图片为空返回errorString fileName = headerImage.getOriginalFilename();String suffix = fileName.substring(fileName.lastIndexOf(".") + 1 );//只允许上传.jpg和.png文件 方法很原始 不安全可以采用头文件判断 if (StringUtils.isBlank(suffix)||!("jpg".equals(suffix)||"png".equals(suffix)||"jpeg".equalsIgnoreCase(suffix))){model.addAttribute("error","文件格式不正确");return "/site/setting";}try {//生成随机文件名fileName = CommunityUtil.generateUUID() + "." + suffix;//Thumbnails处理图片BufferedImage bufferedImage = Thumbnails.of(headerImage.getInputStream()).size(400, 400).asBufferedImage();ByteArrayOutputStream os = new ByteArrayOutputStream();//ImageIO.write(image, "JPEG", out);ImageIO.write(bufferedImage, suffix, os); //图片写入到 ImageOutputStream 和之前格式一致InputStream inputStream = new ByteArrayInputStream(os.toByteArray());//文件上传//设置文件路径和名称String fileUrl = filedir + fileName;//上传文件//阿里云文件上传客户端 创建OSSClient实例。OSS client = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);//调用oss方法实现上传//参数1:Bucket名称//参数2:上传到oss的文件路径和文件名//参数3:上传文件输入流client.putObject(bucketName, fileUrl, inputStream);// 关闭OSSClientclient.shutdown();//更新当前用户头像的路径(web访问 Http://loacalhost:8080/community/user/header/xxx.png)User user = hostHolder.getUser();//String headerUrl = domain + contextPath +"/user/header/" +fileName;String headerUrl = url + "/" + fileUrl;userService.updateHeader(user.getId(),headerUrl);return "redirect:/index";} catch (IOException e) {model.addAttribute("error",e.getMessage());return "/site/setting";}}
测试:
原图片2.07MB
上传成功并获取返回链接写入user表
查看OSS中图片确实上传成功 且图片是压缩过后的21.97kb
而且Thumbnails的一系列处理也杜绝了shell等文件通过修改后缀名为jpg和png等格式绕过检测上传到服务器的问题。
以上就是对图片文件处理并上传到阿里云OSS的简单介绍,如果有疑问或者纠错可以通过邮件与我联系。
引用:
/a/24fb08cae151401f973f0f60.html
/qq_41950447/article/details/115962254
/topics/392077729?list=lz
/document_detail/3.html?spm=5176.208357.1107607.21.331b390f9Z4W5C