网站首页 > 精选教程 正文
以下教你实现图片马赛克,黑白画,珠纹化,油画效果等处理技术原理及实现。看完自己也可以简单的玩一玩。
1. 需要用到的包
java.awt
// 用于创建用户界面和绘制图形图像的所有类
javax.swing
// 提供一组“轻量级”(全部是 Java 语言)组件,尽量让这些组件在所有平台上的工作方式都相同。
2. 主程序
我们需要定义一个主程序的类,叫做 class DrawFrame, 并且在主程序中调用“显示界面 ”方法initUI(),在这个方法中,我们将配置画图工具需要显示的组件,例如窗体,面板,按钮等。
public class DrawFrame {
// 主函数
public static void main(String[] args) {
DrawFrame frame = new DrawFrame();
frame.initUI();
}
//显示界面
public void initUI() {
}
}
2.1 配置initUI()方法
我们先创建组件:窗体(就是类似弹出的对话框),并且设置窗体的一些属
//窗体对象
javax.swing.JFrame jf = new javax.swing.JFrame();
// 设置窗体的大小
jf.setSize(800, 800);
// 设置窗体的名字
jf.setTitle("画图工具");
//设置窗体居中显示
jf.setLocationRelativeTo(null);
//设置退出进程的方法,这里3代表:我们点击窗口上的叉叉时,就退出当前线程(即程序执行结束,表示正在运行的红色方框消失)
jf.setDefaultCloseOperation(3);
//设置窗体可见
jf.setVisible(true);
如下就是窗体:
然后,我们需要在窗体上获取画笔(画笔可以生成颜色,画出各类形状),一定要在窗体显示可见后。
//画笔:图形画在哪个组件上,画笔就从该组件上获取
//从窗体上获取画笔对象(一定要在窗体显示可见之后)
Graphics g = jf.getGraphics();
在此之后,我们需要给窗体添加鼠标监听器方法,鼠标监听器方法需要输入的参数时一个鼠标监听器对象,那么我们可以创建一个DrawListener类,其implements了鼠标监听器类的API,我们需要重写方法。如下图
//事件处理类
public class DrawListener implements MouseListener{
public void mouseClicked(MouseEvent e) {
// Clicked可以理解成点击和释放后仍在同一位置
}
public void mousePressed(MouseEvent e) {
// 点击鼠标
}
public void mouseReleased(MouseEvent e) {
// 释放鼠标
}
public void mouseEntered(MouseEvent e) {
// 鼠标进入窗体
}
public void mouseExited(MouseEvent e) {
// 鼠标退出窗体
}
}
3 马赛克效果
我们需要的马赛克效果是,当鼠标按下时,出现马赛克的图片。
3.1马赛克效果的原理
每一张图片其实是由像素(Pixel)组成的,例如500*600像素的图片,是横向500个像素的长度,纵向600个像素的长度。那我们删除部分像素点,再填充以临近未删除的像素点,就形成了马赛克效果。
3.2 图片导入并得到像素点
原图片
当我们导入图片之后,我们需要用一个数组保存每个像素点的数值
public int[][] getImgPixel(String pathName){
//图片文件
File file = new File(pathName);
BufferedImage buffImg = null;
try {
buffImg = ImageIO.read(file);
} catch (IOException e) {
e.printStackTrace();
}
//获取buffImg大小
int w = buffImg.getWidth();
int h = buffImg.getHeight();
System.out.print(w);
System.out.print(h);
//保存图片像素点的二维数组
int[][] pixelArray = new int[h][w];
//把图片的每个像素点保存到数组中
for(int i=0;i<h;i++){
for(int j=0;j<w;j++){
//读取图片的像素点的颜色
int pixel = buffImg.getRGB(j, i);
//保存到二维数组中
pixelArray[i][j] = pixel;
}
}
return pixelArray;
}
3.3 马赛克处理
通过两个for循环,间隔15个像素点的取法,然后又用gr.fillRect()取临近的像素点填充扔掉的像素点。
public void drawPixel(String pathName){
int[][] pixelArray = getImgPixel(pathName);
for(int i=0;i<pixelArray.length;i+=15){
for(int j=0;j<pixelArray[i].length;j+=15){
Color color = new Color(pixelArray[i][j]);
gr.setColor(color);
gr.fillRect(j+300, i+300, 15,15);
}
}
}
最后,我们将这马赛克方法drawPixel(),加入到“鼠标按下”就可以实现
public void mousePressed(MouseEvent e) {
System.out.println("按下");
//实现六种图像效果
drawPixel("\1.jpg");
}
3.4最终效果
其他几种图片效果的展示,原理及代码
4 灰度效果(左上)
原理:
我们只需要取每个像素点,三原色RGB的平均值作为该像素点的RGB。
// 灰度效果
public void drawGray(String pathName){
int[][] pixelArray = getImgPixel(pathName);
for(int i=0;i<pixelArray.length;i++){
for(int j=0;j<pixelArray[i].length;j++){
Color color = new Color(pixelArray[i][j]);
int r=color.getRed();
int g=color.getGreen();
int b=color.getBlue();
int sum=(r+g+b)/3;
Color nc=new Color(sum,sum,sum);
gr.setColor(nc);
gr.fillOval(j, i, 1,1);
}
}
}
5 无背景效果(右上)
原理:
我们只输出RGB中Blue的值大于50的像素点
// 无背景
public void drawNoBackground(String pathName){
int[][] pixelArray = getImgPixel(pathName);
for(int i=0;i<pixelArray.length;i++){
for(int j=0;j<pixelArray[i].length;j++){
Color color = new Color(pixelArray[i][j]);
int r=color.getRed();
int g=color.getGreen();
int b=color.getBlue();
if(b>50){
Color nc1 = new Color(r,g,b);
gr.setColor(nc1);
gr.fillOval(j+600, i, 1,1);
}
}
}
}
6 珠纹化效果(左下)
原理:
类似于马赛克效果,每隔10个像素点取一个,然后用椭圆填充8个。
//珠纹化实现
public void drawBible(String pathName){
int[][] pixelArray = getImgPixel(pathName);
for(int i=0;i<pixelArray.length;i+=10){
for(int j=0;j<pixelArray[i].length;j+=10){
Color color = new Color(pixelArray[i][j]);
gr.setColor(color);
gr.fillOval(j, i+300, 8,8);
}
}
}
7 黑白画效果(中下)
原理:
我们将RGB中Blue的值小于100时,我们设置画笔颜色为黑,否则为白。每隔两个像素取一个,用椭圆填充周围四个。
// 黑白版画效果
public void drawBlackWhite(String pathName){
int[][] pixelArray = getImgPixel(pathName);
for(int i=0;i<pixelArray.length;i+=2){
for(int j=0;j<pixelArray[i].length;j+=2){
Color color = new Color(pixelArray[i][j]);
int b=color.getBlue();
if(b<100){
gr.setColor(Color.BLACK);
}else{
gr.setColor(Color.WHITE);
}
gr.fillOval(j+300, i+300,4,4);
}
}
}
8 油画效果(右下)
原理:
每隔五个像素点取一个,然后用随机大小的椭圆填充每个像素点周围的区域。
// 油画效果
public void drawOilPaint(String pathName){
int[][] pixelArray = getImgPixel(pathName);
for(int i=0;i<pixelArray.length;i+=5){
for(int j=0;j<pixelArray[i].length;j+=5){
Color color = new Color(pixelArray[i][j]);
gr.setColor(color);
//填充随机大小的色块
Random ran=new Random();
int r=ran.nextInt(20)+5;
gr.fillOval(j+600, i+300,r,r);
}
}
}
9 完整代码展示
DrawFrame.java
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.JButton;
//登录界面类
//1.javax.swing (可视化组件类) 2.java.awt (元素组件类)
public class DrawFrame {
//主函数
public static void main(String[] args){
DrawFrame lo = new DrawFrame();
lo.initUI();
}
//显示界面的方法
public void initUI(){
//窗体对象
javax.swing.JFrame jf = new javax.swing.JFrame();
jf.setSize(800, 800);
jf.setTitle("画图工具");
//设置居中显示
jf.setLocationRelativeTo(null);
//设置退出进程的方法
jf.setDefaultCloseOperation(3);
//设置窗体可见
jf.setVisible(true);
//画笔:图形画在哪个组件上,画笔就从该组件上获取
//从窗体上获取画笔对象(一定要在窗体显示可见之后)
Graphics g = jf.getGraphics();
DrawListener drawListener = new DrawListener();
//给窗体添加鼠标监听器方法
jf.addMouseListener(drawListener);
drawListener.setGr(g);
}
}
DrawListener.java
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
//事件处理类
public class DrawListener implements MouseListener{
private Graphics gr;
public void setGr(Graphics g){
gr = g;
}
public void mouseClicked(MouseEvent e) {
System.out.println("点击");
}
public void mousePressed(MouseEvent e) {
System.out.println("按下");
//实现六种图像效果
drawMosaic("1.jpg");
drawGray("1.jpg");
drawNoBackground("1.jpg");
drawBible("1.jpg");
drawBlackWhite("1.jpg");
drawOilPaint("1.jpg");
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
System.out.println("进入");
}
public void mouseExited(MouseEvent e) {
System.out.println("退出");
}
// 灰度图
public void drawGray(String pathName){
int[][] pixelArray = getImgPixel(pathName);
for(int i=0;i<pixelArray.length;i++){
for(int j=0;j<pixelArray[i].length;j++){
Color color = new Color(pixelArray[i][j]);
int r=color.getRed();
int g=color.getGreen();
int b=color.getBlue();
int sum=(r+g+b)/3;
Color nc=new Color(sum,sum,sum);
gr.setColor(nc);
gr.fillOval(j, i, 1,1);
}
}
}
// 马赛克效果
public void drawMosaic(String pathName){
int[][] pixelArray = getImgPixel(pathName);
for(int i=0;i<pixelArray.length;i+=15){
for(int j=0;j<pixelArray[i].length;j+=15){
Color color = new Color(pixelArray[i][j]);
gr.setColor(color);
gr.fillRect(j+300, i, 15,15);
}
}
}
// 无背景
public void drawNoBackground(String pathName){
int[][] pixelArray = getImgPixel(pathName);
for(int i=0;i<pixelArray.length;i++){
for(int j=0;j<pixelArray[i].length;j++){
Color color = new Color(pixelArray[i][j]);
int r=color.getRed();
int g=color.getGreen();
int b=color.getBlue();
if(b>50){
Color nc1 = new Color(r,g,b);
gr.setColor(nc1);
gr.fillOval(j+600, i, 1,1);
}
}
}
}
//珠纹化实现
public void drawBible(String pathName){
int[][] pixelArray = getImgPixel(pathName);
for(int i=0;i<pixelArray.length;i+=10){
for(int j=0;j<pixelArray[i].length;j+=10){
Color color = new Color(pixelArray[i][j]);
gr.setColor(color);
gr.fillOval(j, i+300, 8,8);
}
}
}
// 黑白版画效果
public void drawBlackWhite(String pathName){
int[][] pixelArray = getImgPixel(pathName);
for(int i=0;i<pixelArray.length;i+=2){
for(int j=0;j<pixelArray[i].length;j+=2){
Color color = new Color(pixelArray[i][j]);
int b=color.getBlue();
if(b<100){
gr.setColor(Color.BLACK);
}else{
gr.setColor(Color.WHITE);
}
gr.fillOval(j+300, i+300,4,4);
}
}
}
// 油画效果
public void drawOilPaint(String pathName){
int[][] pixelArray = getImgPixel(pathName);
for(int i=0;i<pixelArray.length;i+=5){
for(int j=0;j<pixelArray[i].length;j+=5){
Color color = new Color(pixelArray[i][j]);
gr.setColor(color);
//填充随机大小的色块
Random ran=new Random();
int r=ran.nextInt(20)+5;
gr.fillOval(j+600, i+300,r,r);
}
}
}
/**
* I/O
* 读取图片像素点的颜色值,保存到对应的二维数组中
* @param pathName
*/
public int[][] getImgPixel(String pathName){
//图片文件
File file = new File(pathName);
BufferedImage buffImg = null;
try {
buffImg = ImageIO.read(file);
} catch (IOException e) {
e.printStackTrace();
}
//获取buffImg大小
int w = buffImg.getWidth();
int h = buffImg.getHeight();
System.out.print(w);
System.out.print(h);
//保存图片像素点的二维数组
int[][] pixelArray = new int[h][w];
//把图片的每个像素点保存到数组中
for(int i=0;i<h;i++){
for(int j=0;j<w;j++){
//读取图片的像素点的颜色
int pixel = buffImg.getRGB(j, i);
//保存到二维数组中
pixelArray[i][j] = pixel;
}
}
return pixelArray;
}
}
- 上一篇: Java 图像处理(一)
- 下一篇: java读取照片信息
猜你喜欢
- 2024-11-25 干货|一文搞定 uiautomator2 自动化测试工具使用
- 2024-11-25 Java去除PDF文件中的图片
- 2024-11-25 2021 年 Node.js 开发人员学习路线图
- 2024-11-25 Java之base64转化成图片文件
- 2024-11-25 wangEditor 实现ctrl+v粘贴图片并上传、word粘贴带图片
- 2024-11-25 姐姐带我玩转java设计模式(内附照片)- 代理模式
- 2024-11-25 base64转化为图片
- 2024-11-25 Java 给Excel图表设置背景颜色和背景图片
- 2024-11-25 一个支持将html转为PDF、图片,且支持PDF加水印的项目
- 2024-11-25 使用SpringBoot Schedule实现定时任务动态添加、修改、删除等操作
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)