技术标签: java Java基础 thumbnails 图片操作
最近工作上用到图片旋转,所以来偏图片旋转的文章。其中碰到不少坑。
以下实现了旋转90度的倍数。方便我们了解旋转是怎么做的 ,如果要旋转任意角度,可以用Java自带的thumbnails(文章后面介绍)
import org.springframework.util.Base64Utils;
import net.coobird.thumbnailator.Thumbnails;
/**
* 旋转图片
* @param old_img
* @param degess 旋转度数 负数为逆时针 //如果宽高比大于1 不旋转
* @return
* @throws IOException
*/
public static BufferedImage rotateImage(BufferedImage bi, String times ) {
int width = bi.getWidth();
int height = bi.getHeight();
BufferedImage biFlip = null;
try {
int count = Integer.valueOf(times);
if(count>=4){
count = count % 4;
}
if(count==0) return bi;
if(count==1){
biFlip = new BufferedImage(height,width, bi.getType());
for(int i=0; i<width; i++){
for(int j=0; j<height; j++){
biFlip.setRGB(height-1-j, i, bi.getRGB(i, j));//顺时针旋转
//旋转公式 R*(x,y) = (-y,x)
}
}
}else if(count==2){
//旋转180度
biFlip = new BufferedImage(width,height, bi.getType());
for(int i=0; i<width; i++){
for(int j=0; j<height; j++){
biFlip.setRGB(width-1-i, height-1-j, bi.getRGB(i, j));//顺时针旋转180
}
}
}else {
//逆时针旋转90 == 旋转270度
biFlip = new BufferedImage(height,width, bi.getType());
for(int i=0; i<width; i++){
for(int j=0; j<height; j++){
biFlip.setRGB(j, width-1-i, bi.getRGB(i, j));
}
}
}
} catch(Exception e){
e.printStackTrace();
return bi;
}finally {
}
return biFlip;
}
图片转base64
public static String encodeToString(BufferedImage image) {
String imageString = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ImageIO.write(image, "jpg", bos);
byte[] imageBytes = bos.toByteArray();
imageString = Base64Utils.encodeToString(imageBytes);
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
return imageString;
}
base64转图片
public static BufferedImage baseToBufferedImage(String base64Sign){
ByteArrayOutputStream os = new ByteArrayOutputStream();
BufferedImage img = null;
byte[] buffer=null;
BufferedImage bufferImg =null ;
try {
buffer = Base64Utils.decodeFromString(base64Sign);
ByteArrayInputStream input = new ByteArrayInputStream(buffer);
bufferImg = ImageIO.read(input);
} catch (Exception e) {
e.printStackTrace();
return null;
}
return bufferImg;
}
**
**
1 Thumbnails.of(images)
<!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
可以是BufferedImage File InputStream URL 等途径
**
**
a 压缩图片(拉伸图片)
压缩图片(选择操作的大小) size()是按照原图一width为准等比例压缩。forceSize()是强制压缩,可能导致图片变形。
也可以用scale指定比例,第二个方法可以指定长款分别压缩多少倍,等于图片拉伸操作。
b 旋转图片
Thumbnails.of(“”).scale(1).rotate(10);
旋转度数按顺时针旋转,如果要逆时针,可以传入负数。必须先指定大小既scale或用size指定。
3**
**
可以作为输出的方式也挺多的 。
总结 :
不管哪种方式实现,还是要注意几个问题
1 是图片旋转后编码的时候用BASE64Decoder编码解码,而BASE64Decoder编码时默认每隔76个字符加一个换行,导致旋转后编码变的很大,并且有换行的编码在转图片的时候就有问题,用spring自带的工具org.springframework.util.Base64Utils编解码;。
2是对于空白图片,在转成BufferedImage时Java把透明背景设置成了黑色背景,可以在操作之前把图片设置成白色背景。
图片剪裁
/**
* 图片中心400*400的区域
*/
Thumbnails.of("images/test.jpg").sourceRegion(Positions.CENTER, 400, 400).size(200, 200).keepAspectRatio(false)
.toFile("C:/image_region_center.jpg");
/**
* 图片右下400*400的区域
*/
Thumbnails.of("images/test.jpg").sourceRegion(Positions.BOTTOM_RIGHT, 400, 400).size(200, 200).keepAspectRatio(false)
.toFile("C:/image_region_bootom_right.jpg");
/**
* 指定坐标
*/
Thumbnails.of("images/test.jpg").sourceRegion(600, 500, 400, 400).size(200, 200).keepAspectRatio(false).toFile("C:/image_region_coord.jpg");
/**
* watermark(位置,水印图,透明度)
*/
Thumbnails.of("images/test.jpg").size(1280, 1024).watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("images/watermark.png")), 0.5f)
.outputQuality(0.8f).toFile("C:/image_watermark_bottom_right.jpg");
Thumbnails.of("images/test.jpg").size(1280, 1024).watermark(Positions.CENTER, ImageIO.read(new File("images/watermark.png")), 0.5f)
.outputQuality(0.8f).toFile("C:/image_watermark_center.jpg");
文章浏览阅读1.5k次,点赞2次,收藏15次。ORACLE 的 EMP&DEPT表 建表语句-- 创建表与数据CREATE TABLE EMP(EMPNO NUMBER(4) NOT NULL,ENAME VARCHAR2(10),JOB VARCHAR2(9),MGR NUMBER(4),HIREDATE DATE,SAL NUMBER(7, 2),COMM NUMBER(7, 2),DEPTNO NUMBER(..._oracle emp建表语句
文章浏览阅读9.5k次。第一种方案修改ajax中type方式并设置header,同时对put重新构建数据字典在对views中的方法进行类对象封装时,发现django并不支持像post和get一样将数据封装。 由于网页端无法设置method方法,在用postman和ajax开启pycharm对接口进行debug测试时发现:提交数据后并没有进入代码逻辑。 查阅资料得知,django支持put和delete方法..._django如何简单快速实现put、delete方法
文章浏览阅读2.9w次,点赞17次,收藏45次。先吐槽: 搞了一上午!!! 我太难了!!! 最近服务器不够用, 就差动手算深度学习梯度了!!! 向本科朋友借了几台机子跑, 这要是没上过大学, 研究生还不能毕业了呢!!!目录1. 简单任务介绍2. 本机的配置3. 跳板机的配置4.内网服务器的配置5. 怎么样不需要密码访问嘤嘤嘤~~1. 简单的任务介绍:我现在用的电脑叫做A, 然后借了一台服务器叫做C..._vscode 连接堡垒机
文章浏览阅读1.1k次。例如100行数据填入word,每页固定展示5行,需要20页_python docx设置每页行数
文章浏览阅读7k次。目录前言OpenEmu简介OpenEmu实际体验最后前言 这次的文章和以往不太一样, 不谈技术, 来谈谈情怀. 记得那是我小学二三年级的时候吧, 我妈给我买了一个Game Boy, 价格记不清了, 反正不贵, 而且是黑白的那种, 应该就是初代Game Boy吧. 然后还配了一张口袋妖怪青的卡. 在那个魔域啊, 传奇啊, 或者什么类似网游盛..._openemu苹果电脑
文章浏览阅读108次。声明:该博文以socket中,关闭输出流为例进行说明。为了方便讲解,我们把DataOutputstream dout = new DataOutputStream(new BufferedOutputStream(mySocket.getOutputStream()));中的dout做为Socket输出流的代言。同样的,din是输入流的代言。可以造成dout被关闭的操作有:1、调用dout.clo..._error:java.net.socketexception: socket output is shutdown
文章浏览阅读2.1w次,点赞9次,收藏50次。Android11及以上 文件读写权限申请_android 11 write_external_storage
文章浏览阅读330次,点赞8次,收藏6次。托管班店铺的装修风格,一定要结合学生喜欢的设计风格,颜色搭配一定要看起来舒适,让学生一进来就有学习的范围,不由自主就想学习的动力,所以装修的风格,是要符合学生学习的环境氛围,让学生一进来想呆着不想走,所以设计方面,一定一定多参考同行的装修风格。想要运营好一家托管班,那么需要有一个正规化的管理流程,那么就要为校区制定各种规章制度,按照规章制度来走,避免后期因为没有任何提示,导致出现一系列的问题,所以要出针对教师,学生,家长的不同规章制度。保护孩子的安全,预防托管机构火灾事故的发生,是托管班一项重要指标。
文章浏览阅读2.2k次,点赞7次,收藏40次。外观模式实例问题描述结构图编程实现需要交互的类Facade类客户端问题描述某软件公司为新开发的智能手机控制与管理软件提供一键备份功能,通过该功能可以将原本存储在手机中的通讯录、短信、照片、音乐等资料一次性拷贝到移动存储介质中(例如:SD卡)中。在实现过程中需要与多个已有的类进行交互,如通讯录管理类、短信管理类。结构图编程实现需要交互的类public class ContactsManager { private String contacts; public Contacts_某软件公司为新开发的智能手机控制与管理软件提供了一键备份功能,通过该功能可以
文章浏览阅读1k次。本文转自:http://www.99inf.net/SoftwareDev/VC/22322.htmWindows给我们或是说给它自己定义了许多丰富的通用控件,如:Edit、ComboBox 、ListBox……等,这些控件功能丰富,能为我们开发工作带来极大方面,试想:我们单单是自己实现一个EDIT控件是多么的艰难!但是,在实际开发中还是有些情况这些标准控件也无能为力,比如:在我们的应用中要求_vs怎么用mfc画出迷宫
文章浏览阅读6.4k次,点赞5次,收藏42次。【矩阵学习】Jacobian矩阵和Hessian矩阵Jacobian 矩阵Jacobian 行列式功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchar..._海森矩阵判断是否为驻点
文章浏览阅读487次。计算机网络这门课是在大二上的时候是作为主修课,当然上这门课的时候有点划水了。后来接触到校招这方面,下定决心恶补计算机网络这方面的知识,就买了一本《计算机网络:自顶向下的方法》研习。如果不想读谢希仁那版书(毕竟晦涩难懂),又想比较系统的了解计算机网络这方面知识,这本书真的非常推荐。划重点:简单回顾一下HTTP及其报文。1、什么是HTTP协议?HTTP 超文本传输协议 (HTTP-Hypertext transfer protocol),是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用_协议报文和数据报文的区别