java 图片压缩100k_java实现图片压缩

简介

我们在项目中经常会遇到图片上传的需求,如商品图片,但图片太大的话,在客户端加载太慢影响用户体验,所有一般会将图片进行压缩。

实现

原图

添加依赖

net.coobird

thumbnailator

0.4.8

按质量压缩

import java.io.File;

import java.io.FileOutputStream;

import net.coobird.thumbnailator.Thumbnails;

public class Client {

public static void main(String[] args) throws Exception {

Thumbnails.of(new File("D:/showqrcode.jpg"))

.scale(1f) //图片大小(长宽)压缩比例 从0-1,1表示原图

.outputQuality(0.5f) //图片质量压缩比例 从0-1,越接近1质量越好

.toOutputStream(new FileOutputStream("D:/showqrcode_50.jpg"));

}

}

压缩后图片

图片大小从665KB压缩到了77KB。

按比例缩放

import java.io.File;

import java.io.FileOutputStream;

import net.coobird.thumbnailator.Thumbnails;

public class Client2 {

public static void main(String[] args) throws Exception {

Thumbnails.of(new File("D:/showqrcode.jpg"))

.scale(0.5f) //图片大小(长宽)压缩 从0按照

.outputQuality(0.5f) //图片质量压缩比例 从0-1,越接近1质量越好

.toOutputStream(new FileOutputStream("D:/showqrcode_50%.jpg"));

}

}

按大小和比例缩放

import java.io.File;

import java.io.FileOutputStream;

import net.coobird.thumbnailator.Thumbnails;

public class Client21 {

public static void main(String[] args) throws Exception {

Thumbnails.of(new File("D:/showqrcode.jpg"))

.size(500, 300) // 图片比例不变

.toOutputStream(new FileOutputStream("D:/showqrcode_500_300.jpg"));

}

}

按大小缩放

import java.io.File;

import java.io.FileOutputStream;

import net.coobird.thumbnailator.Thumbnails;

public class Client22 {

public static void main(String[] args) throws Exception {

Thumbnails.of(new File("D:/showqrcode.jpg"))

.forceSize(500, 300) //不保持图片比例

.toOutputStream(new FileOutputStream("D:/showqrcode_500_300.jpg"));

}

}

旋转

import java.io.File;

import java.io.FileOutputStream;

import net.coobird.thumbnailator.Thumbnails;

public class Client3 {

public static void main(String[] args) throws Exception {

Thumbnails.of(new File("D:/showqrcode.jpg"))

.forceSize(500, 300)

.rotate(90f) //向右旋转

.toOutputStream(new FileOutputStream("D:/showqrcode+90.jpg"));

}

}

加水印

水印图片

import java.io.File;

import java.io.IOException;

import javax.imageio.ImageIO;

import net.coobird.thumbnailator.Thumbnails;

import net.coobird.thumbnailator.geometry.Positions;

public class Client4 {

public static void main(String[] args) throws IOException {

Thumbnails.of("D:/showqrcode.jpg")

.size(1280, 1024)

.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("D:/watermark.jpg")),

0.5f) //位置,水印来源,透明度

.outputQuality(0.8f)

.toFile("D:/showqrcode_watermark_bottom_right.jpg");

}

}

裁剪

import java.io.IOException;

import net.coobird.thumbnailator.Thumbnails;

import net.coobird.thumbnailator.geometry.Positions;

public class Client5 {

public static void main(String[] args) throws IOException {

Thumbnails.of("D:/showqrcode.jpg")

.sourceRegion(Positions.CENTER, 800, 600) //位置,宽,高

.size(800, 600)

.keepAspectRatio(false)

.toFile("D:/showqrcode_region_center.jpg");

}

}

拼接

import java.awt.Graphics;

import java.awt.image.BufferedImage;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

import java.util.Objects;

import javax.imageio.ImageIO;

public class Client6 {

public static void main(String[] args) throws Exception {

byte[] bytes = joinImages(false, new File("D:/showqrcode.jpg"), new File("D:/showqrcode.jpg"));

if (Objects.nonNull(bytes)) {

new ByteArrayInputStream(bytes).transferTo(new FileOutputStream("D:/showqrcode_join.jpg"));

}

}

/**

* 将多张图片拼接成一张

*

* @param horizontal 是否为水平拼接

* @param files 文件列表

* @return 拼接后的文件字节数组

*/

private static byte[] joinImages(boolean horizontal, File... files) throws IOException {

if (Objects.isNull(files) || files.length == 0) {

return null;

}

List imageList = new ArrayList<>();

for (File file : files) {

BufferedImage image = ImageIO.read(file);

imageList.add(image);

}

int height = imageList.get(0).getHeight();

int width = imageList.get(0).getWidth();

if (horizontal) {

width = imageList.stream().mapToInt(BufferedImage::getWidth).sum();

} else {

height = imageList.stream().mapToInt(BufferedImage::getHeight).sum();

}

//创建拼接后的图片画布,参数分别为宽,高,类型,这里我们使用RGB3元色类型

BufferedImage resultImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

Graphics graphics = resultImage.getGraphics();

int previousWidth = 0;

int previousHeight = 0;

for (BufferedImage image : imageList) {

//向画布上画图片

graphics.drawImage(image, previousWidth, previousHeight, null);

if (horizontal) {

previousWidth += image.getWidth();

} else {

previousHeight += image.getHeight();

}

}

ByteArrayOutputStream output = new ByteArrayOutputStream();

ImageIO.write(resultImage, "jpg", output);

return output.toByteArray();

}

}

更多用法请参考官方文档

总结

图片经过以上处理之后都会去除EXIF信息,关于EXIF详情,请查看java获取图片的GPS信息

参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/420246.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端学习(1352)模板语法

demo27.js const template require(art-template); //绝对路径 模板中显示的数据 const path require(path); const views path.join(__dirname, 01.art); const html template(views, {name: 张三,age: 20,content: <h1>我是歌谣</h1> }); console.log(html)…

marker 头像 高德地图_高德地图头像怎么更换 高德地图更换头像图文教程

相信绝大部分人都知道微信头像以及QQ头像怎么更换&#xff0c;而设置头像也是很多人喜欢做的一件事情。而对于经常使用高德地图的用户来说&#xff0c;头像该怎么设置呢&#xff1f;对于这群用户&#xff0c;下面百事网小编为大家带来详细的高德地图更换头像图文教程&#xff0…

UVA10763:Foreign ExchangeUVA10340: All in All(水题)

10763:水题不解释直接贴代码。 #include <iostream> #include <string.h> #include <stdio.h> #include <algorithm> #include <math.h> #include <queue> #define eps 1e-9 typedef long long ll; using namespace std; int n; int d[500…

项目经验BigDecimal

BigDeciaml1. BigDecimal1. BigDecimal 我们知道&#xff0c;关于金钱相关的计算&#xff0c;都用BigDeciaml数据类型, 来表示金额。所有关于金额的项目中不能缺少它的使用。 而我今天说说用这个类型&#xff0c;踩到的坑。 金额比较问题 带精度不适用equals比较。使用compar…

前端学习(1353)模板语法条件判断

const template require(art-template); //绝对路径 模板中显示的数据 const path require(path); const views path.join(__dirname, 02.art); const html template(views, {name: 张三,age: 20,/* content: <h1>我是歌谣</h1> */ }); console.log(html); 0…

MySql 缓存查询原理与缓存监控 和 索引监控

MySql缓存查询原理与缓存监控 And 索引监控 by:授客 QQ&#xff1a;1033553122 查询缓存 1.查询缓存操作原理 mysql执行查询语句之前&#xff0c;把查询语句同查询缓存中的语句进行比较&#xff0c;且是按字节比较&#xff0c;仅完全一致才被认为相同。如下&#xff0c;这两…

python pandas 数据分析 DataFrame

二维组转表 import pandas as pdarr [[google, 100], [amazon, 99], [github, 233], [microsoft, 88]]df pd.DataFrame(dataarr, columns[Site, Age]) # 二元组转成表&#xff0c; 列为 Site 和 Age. print(df)col df[Age]# 获取Age列 print(col)# 获取Age > 100的所有行…

前端学习(1354):集合关联

const mongoose require(mongoose); mongoose.connect(mongodb://localhost/playground, { useUnifiedTopology: true }).then(() > console.log(数据库连接成功)).catch(err > console.log(err, 数据库连接失败)) const userSchema new mongoose.Schema({name: {type:…

ati jti jwt 和_一文搞懂JWT

Django REST framework JWT一、JWT简介二、JWT 组成headersignature三.使用手动生成jwt前端保存jwt一、JWT简介JWT(Json Web Token) 是一个开放标准(RFC 7519)&#xff0c;它定义了一种用于简洁&#xff0c;自包含的用于通信双方之间以 JSON 对象的形式安全传递信息的方法。JWT…

[禅悟人生]心平气和, 慢慢修行

有一个人问投子大同禅师&#xff1a;“一个没有眼晴的人&#xff0c;走路时应该怎样选择方向呢&#xff1f;” 禅师回答说&#xff1a;“他可以朝着四面八方行走&#xff0c;周围都会留下他的脚印。” 那人又问&#xff1a;“既然他都没有眼睛&#xff0c;那么他的脚印怎么会遍…

前端学习(1355)模板语法循环

const template require(art-template); //绝对路径 模板中显示的数据 const path require(path); const views path.join(__dirname, 03.art); const html template(views, {users: [{name: geyao,age: 20,sex: 男}, {name: xiao,age: 20,sex: 男}, {name: hau,age: 20,se…

c++检测ip是否匹配子网掩码_网络工程师从入门到精通通俗易懂系列 | ARP和IP这篇文章讲的相当详细了,这么基础的知识往往也是最容易遗忘的!...

网络层负责将报文从源送到目的包括TCP建立连接&#xff0c;也需要依靠网络层&#xff0c;来将这个连接请求&#xff0c;传递到对方。为设备提供逻辑地址&#xff0c;也就是IP地址主流是IPV4地址IPV4地址&#xff0c;为32位二进制数&#xff0c;长度4个字节&#xff0c;1字节等于…

复合索引字段的排序对搜素的影响

索引是对数据库大数据的查询优化的一种有效的手段&#xff0c;索引又可分为唯一索引和复合索引 单一索引是指索引列为一列的情况&#xff0c;即新建索引的语句只实施在一列上面。 用户可以在多个列上建立索引&#xff0c;这种索引叫做复合索引(组合索引)。复合索引的创建方法与…

mysql图片jsp_mysql jsp 图片

?转个帖子给你&#xff0c;我也是用的这个&#xff0c;已经成功实现了的。我在程序代码里贴了向Mysql数据库写入image代码的程序&#xff0c;可是好多人都是Java的初学者&#xff0c;对于这段代码&#xff0c;他们无法将它转换成jsp&#xff0c;所以我在这在写一下用jsp怎样向…

递归和迭代的差别

递归的基本概念:程序调用自身的编程技巧称为递归,是函数自己调用自己. 一个函数在其定义中直接或间接调用自身的一种方法,它通常把一个大型的复杂的问题转化为一个与原问题类似的规模较小的问题来解决,能够极大的降低代码量.递归的能力在于用有限的语句来定义对象的无限集合. 使…

前端学习(1357) :模板配置

const template require(art-template); //绝对路径 模板中显示的数据 const path require(path); const views path.join(__dirname, 07.art); const dateFormat require(dateFormat) template.defaults.imports.dateFormat dateFormat; const html template(views, {ti…

使用Office Word 2010/2013 发布文章到博客园

使用Office Word 2010/2013 发布文章到博客园 ☆&#xff1a;参考http://www.cnblogs.com/liuxianan/archive/2013/04/13/3018732.html&#xff1b; 软件准备&#xff1a;Office Word2010/2013 初次使用&#xff0c;必要的配置&#xff1a; Office Word2010&#xff1a;代开wor…

前端学习(1355) 子模板

const template require(art-template); //绝对路径 模板中显示的数据 const path require(path); const views path.join(__dirname, 04.art); const html template(views, {msg: 我是首页,name: geyao,age: 20 }); console.log(html); 04.art {{include./index.art}} {…

mysql 正无穷字符_mysql 字符串函数收集比较全

ASCII(str)返回字符串str的 最左面字符的ASCII代码值。如果str是空字符串&#xff0c; 返回0。如果str是NULL&#xff0c;返回NULL。 mysql> select ASCII(2);-> 50mysql> select ASCII(2);-> 50mysql> select ASCII(dx);-> 100也可参见ORD()函数。ORD(str)如…

前端学习(1358) :渲染模板默认

const template require(art-template); //绝对路径 模板中显示的数据 const path require(path);const dateFormat require(dateFormat) template.defaults.imports.dateFormat dateFormat; template.defaults.root path.join(__dirname); template.defaults.extname .a…