java实现图片缩放、旋转和马赛克化
作者:Crazy光光 发布时间:2021-07-23 03:04:54
标签:java,缩放,旋转,马赛克
本文是作者结合网上的一些资料封装的java图片处理类,支持图片的缩放,旋转,马赛克化。
不多说,上代码:
package deal;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
/**
* 图像处理类.
*
* @author nagsh
*
*/
public class ImageDeal {
String openUrl; // 原始图片打开路径
String saveUrl; // 新图保存路径
String saveName; // 新图名称
String suffix; // 新图类型 只支持gif,jpg,png
public ImageDeal(String openUrl, String saveUrl, String saveName,
String suffix) {
this.openUrl = openUrl;
this.saveName = saveName;
this.saveUrl = saveUrl;
this.suffix = suffix;
}
/**
* 图片缩放.
*
* @param width
* 需要的宽度
* @param height
* 需要的高度
* @throws Exception
*/
public void zoom(int width, int height) throws Exception {
double sx = 0.0;
double sy = 0.0;
File file = new File(openUrl);
if (!file.isFile()) {
throw new Exception("ImageDeal>>>" + file + " 不是一个图片文件!");
}
BufferedImage bi = ImageIO.read(file); // 读取该图片
// 计算x轴y轴缩放比例--如需等比例缩放,在调用之前确保参数width和height是等比例变化的
sx = (double) width / bi.getWidth();
sy = (double) height / bi.getHeight();
AffineTransformOp op = new AffineTransformOp(
AffineTransform.getScaleInstance(sx, sy), null);
File sf = new File(saveUrl, saveName + "." + suffix);
Image zoomImage = op.filter(bi, null);
try {
ImageIO.write((BufferedImage) zoomImage, suffix, sf); // 保存图片
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 旋转
*
* @param degree
* 旋转角度
* @throws Exception
*/
public void spin(int degree) throws Exception {
int swidth = 0; // 旋转后的宽度
int sheight = 0; // 旋转后的高度
int x; // 原点横坐标
int y; // 原点纵坐标
File file = new File(openUrl);
if (!file.isFile()) {
throw new Exception("ImageDeal>>>" + file + " 不是一个图片文件!");
}
BufferedImage bi = ImageIO.read(file); // 读取该图片
// 处理角度--确定旋转弧度
degree = degree % 360;
if (degree < 0)
degree = 360 + degree;// 将角度转换到0-360度之间
double theta = Math.toRadians(degree);// 将角度转为弧度
// 确定旋转后的宽和高
if (degree == 180 || degree == 0 || degree == 360) {
swidth = bi.getWidth();
sheight = bi.getHeight();
} else if (degree == 90 || degree == 270) {
sheight = bi.getWidth();
swidth = bi.getHeight();
} else {
swidth = (int) (Math.sqrt(bi.getWidth() * bi.getWidth()
+ bi.getHeight() * bi.getHeight()));
sheight = (int) (Math.sqrt(bi.getWidth() * bi.getWidth()
+ bi.getHeight() * bi.getHeight()));
}
x = (swidth / 2) - (bi.getWidth() / 2);// 确定原点坐标
y = (sheight / 2) - (bi.getHeight() / 2);
BufferedImage spinImage = new BufferedImage(swidth, sheight,
bi.getType());
// 设置图片背景颜色
Graphics2D gs = (Graphics2D) spinImage.getGraphics();
gs.setColor(Color.white);
gs.fillRect(0, 0, swidth, sheight);// 以给定颜色绘制旋转后图片的背景
AffineTransform at = new AffineTransform();
at.rotate(theta, swidth / 2, sheight / 2);// 旋转图象
at.translate(x, y);
AffineTransformOp op = new AffineTransformOp(at,
AffineTransformOp.TYPE_BICUBIC);
spinImage = op.filter(bi, spinImage);
File sf = new File(saveUrl, saveName + "." + suffix);
ImageIO.write(spinImage, suffix, sf); // 保存图片
}
/**
* 马赛克化.
* @param size 马赛克尺寸,即每个矩形的长宽
* @return
* @throws Exception
*/
public boolean mosaic(int size) throws Exception {
File file = new File(openUrl);
if (!file.isFile()) {
throw new Exception("ImageDeal>>>" + file + " 不是一个图片文件!");
}
BufferedImage bi = ImageIO.read(file); // 读取该图片
BufferedImage spinImage = new BufferedImage(bi.getWidth(),
bi.getHeight(), bi.TYPE_INT_RGB);
if (bi.getWidth() < size || bi.getHeight() < size || size <= 0) { // 马赛克格尺寸太大或太小
return false;
}
int xcount = 0; // 方向绘制个数
int ycount = 0; // y方向绘制个数
if (bi.getWidth() % size == 0) {
xcount = bi.getWidth() / size;
} else {
xcount = bi.getWidth() / size + 1;
}
if (bi.getHeight() % size == 0) {
ycount = bi.getHeight() / size;
} else {
ycount = bi.getHeight() / size + 1;
}
int x = 0; //坐标
int y = 0;
// 绘制马赛克(绘制矩形并填充颜色)
Graphics gs = spinImage.getGraphics();
for (int i = 0; i < xcount; i++) {
for (int j = 0; j < ycount; j++) {
//马赛克矩形格大小
int mwidth = size;
int mheight = size;
if(i==xcount-1){ //横向最后一个比较特殊,可能不够一个size
mwidth = bi.getWidth()-x;
}
if(j == ycount-1){ //同理
mheight =bi.getHeight()-y;
}
// 矩形颜色取中心像素点RGB值
int centerX = x;
int centerY = y;
if (mwidth % 2 == 0) {
centerX += mwidth / 2;
} else {
centerX += (mwidth - 1) / 2;
}
if (mheight % 2 == 0) {
centerY += mheight / 2;
} else {
centerY += (mheight - 1) / 2;
}
Color color = new Color(bi.getRGB(centerX, centerY));
gs.setColor(color);
gs.fillRect(x, y, mwidth, mheight);
y = y + size;// 计算下一个矩形的y坐标
}
y = 0;// 还原y坐标
x = x + size;// 计算x坐标
}
gs.dispose();
File sf = new File(saveUrl, saveName + "." + suffix);
ImageIO.write(spinImage, suffix, sf); // 保存图片
return true;
}
public static void main(String[] args) throws Exception {
ImageDeal imageDeal = new ImageDeal("e://1.jpg", "e://", "2", "jpg");
// 测试缩放
/* imageDeal.zoom(200, 300); */
// 测试旋转
/* imageDeal.spin(90); */
//测试马赛克
/*imageDeal.mosaic(4);*/
}
}
来源:https://blog.csdn.net/u012116457/article/details/46445931
0
投稿
猜你喜欢
- 当我们需要制作动态炫酷科技感很强的UI时,美术一般会给我们提供一些序列图,这时候我们只需在程序里实现序列动画。一.动画机unity自带的帧动
- 需要自定义ListView。这里就交FloatDelListView吧。复写onTouchEvent方法。如下:@Override &nbs
- 最近公司因为短信接口被盗刷的比较严重,需要做一个类似于淘宝的滑动验证,用于特定环境,以增加一层保障。拿到需求首先想到的是自定义ViewGro
- 1.1 概述分布式系统:分布式系统指由很多台计算机组成的一个整体!这个整体一致对外,并且处理同一请求!系统对内透明,对外不透明!内部的每台计
- 有时候会碰到一些需要设置开始日期和结束日期的需求,比如有很多商品,每件商品都有开始出售日期和结束出售日期的字段。如何使用DatePicker
- 阅读目录:基础Socket编程多线程并发阻塞式同步IO基础在现今软件开发中,网络编程是非常重要的一部分,本文简要介绍下网络编程的概念和实践。
- 本文实例为大家分享了Android实现View滑动效果的具体代码,供大家参考,具体内容如下一、View的滑动简介View的滑动是Androi
- 项目中需要判断传入的日期是否在未来的一年以内,百度了一下网上没有找到好的方式,写了,方便自己和他人:int datecompareAfter
- 目录Emit异常处理流程 显示Exception对象的Message属性 返回目录 Emit异常处理流程来看这种C#异常处理代码:
- 1 修饰属性或者变量无论属性是基本类型还是引用类型,作用都是变量里面存放的“值”不可变经常和static关键字一起使用,作为常量1 基本类型
- 简介说明本文用实例介绍stream的使用。JDK8新增了Stream(流操作) 处理集合的数据,可执行查找、过滤和映射数据等操作。使用Str
- 本文实例为大家分享了C语言实现通讯录小项目的具体代码,供大家参考,具体内容如下编写程序实现通讯录的基本功能,可以做到增,删,查,改,打印通讯
- 概念装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。装饰者和被装饰对象有相同的超类型。你可以用一个或
- 1. 测试文档、期望达到的目标文档效果用于测试的Word文档如下所示,包含的空白段落影响文章整体布局及美观性:目标文档效果:2. 辅助工具2
- 本文实例讲述了C#使用linq查询大数据集的方法。分享给大家供大家参考。具体如下:using System;using System.Col
- 在android移动端的开发中,首页轮播图是一个特别常见的功能,所以今天就来将最近写的一个小demo记录一下。首先当然是新建一个项目代码如下
- android系统提供了Environment.getExternalStorageDirectory()接口获得存储器的路径,但是这个接口
- LiveData概述LiveData 是一种可观察的数据存储器类: 与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循
- springBoot所有依赖和配置文件都写好的情况下1、dao接口的实现方法package com.cy.pj.sys.dao;import
- 本文实例为大家分享了Android App获取屏幕旋转角度的具体代码,供大家参考,具体内容如下一、获取屏幕旋转角度的方法是:int rota