一款简易美颜相机的功能我们可以简单分为两大块:1.图像处理 2.功能区
(2)int数字构成颜色:Color color = new Color(842179),其值在int范围内即可。Int最大到21亿
因为高位补1会超过255.
获取RGB三原色的分量值:
1.取出所有的像素值,把像素值转为Color对象,通过调用Color对象的getRed,getGreen,getBlue方法获取
2.通过将像素值右移相应的位数,再进行与操作
1Byte(字节) = 8bit(位)
位运算:
在Java中int是有4个字节,RGB是三个字节的长度(0-255是一个字节),通过左移运算 把三个Byte合成了一个int,1Byte(字节) = 8bit(位)。R红色<<移动了16位,G绿色<<移动了8位,B蓝色不移动,通过位移操作总共移动了24位。
源代码:
- Java程序真正是运行在我们的虚拟机上面的,程序>jvm(虚拟机)>os>总线>屏幕。
- 利用缓冲区可以加快像素点的绘制速度,思路:把所有处理好的像素点先存入缓冲区,然后在屏幕上一次性显示出来。缓冲区它也是个容器。
- 图像消失问题是因为组件重绘问题。
- 除了接口,类里面也可以定义常量,常量可以直接通过类名来调用。
图像重绘问题:
- 所有的swing包下的每一个组件都有一个paint方法,paint方法的作用:绘制组件本身。
- swing包下的每一个组件都要通过调用paint函数把组件的效果显示在我们的屏幕上。
- 当改变窗体的状态(隐藏,改变大小)都会导致窗体上所有的swing组件重新/自动调用paint方法。
- 解决办法:让组件在重绘的过程中,把我们的图像显示效果也一起画一遍。
- 解决图像重绘问题:1.重写组件的paint方法,添加paint方法绘制组件的功能
- 2.保存图像数据
- g.drawImage(img, x, x, width, height, observer)
- img:画哪张图片 x,y画在哪个位置,图片的左上角 最后一个暂时用不到,给null
package com.gch.filterarithmetic;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
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;
/**
滤镜算法
*/
public class PixelUI {
/**
图像处理界面
*/
public void showUI(){
JFrame win = new JFrame("PC版美颜相机");
win.setSize(1000,650);
win.setLocationRelativeTo(null);
win.setDefaultCloseOperation(3);
// 设置边框/边界布局:BorderLayout 用这种边框布局,一个方向只能加一个组件
win.setLayout(new BorderLayout());
// 面板对象/桌布:JPanel 面板对象的默认颜色和窗体同色
// 功能区:eastPanel
JPanel eastPanel = new JPanel();
// 设置功能区面板对象的背景色
eastPanel.setBackground(Color.yellow);
// 设置功能区面板对象的大小
eastPanel.setPreferredSize(new Dimension(120,0));
// 把功能区面板对象添加到窗体上 并且设置功能区的位置
win.add(eastPanel,BorderLayout.EAST);
// 创建事件处理类对象
ButtonMouse mouse = new ButtonMouse();
// 功能区按钮的添加
// 定义字符串数组保存功能区按钮的名称
String[] functionButton = {"原图","马赛克","灰度","黑白","去色","单色","底片/反向","怀旧","褐色","连环画","冰冻",
"熔铸","浮雕","放大镜","左转","右转","撤回"};
for(int i = 0;i < functionButton.length;i++){
// 定义按钮添加
JButton btn = new JButton(functionButton[i]);
// 把按钮添加到功能区面板
eastPanel.add(btn);
// 给按钮添加动作监听器:绑定事件处理类
btn.addActionListener(mouse);
}
// 自定义面板类:MyPanel
// 图像显示区/内容显示区:drawPanel
MyPanel drawPanel = new MyPanel();
// 设置图像显示区的背景色
drawPanel.setBackground(Color.LIGHT_GRAY);
// 把图像显示区添加到窗体上并设置图像显示区的位置
win.add(drawPanel, BorderLayout.CENTER);
// 设置窗体显示可见
win.setVisible(true);
// 画笔更新,画笔的获取要在内容显示区,直接传内容显示区对象/面板对象
mouse.setG(drawPanel);
}
}
package com.gch.filterarithmetic;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
/**
自定义面板类:图像显示区/内容显示区
*/
public class MyPanel extends JPanel {
// 定义缓冲区,保存传递过来的当前图像的缓冲对象
private BufferedImage buff;
/**
定义set方法,初始化属性
*/
public void setBuff(BufferedImage buff) {
this.buff = buff;
}
/**
重写绘制组件的paint方法
*/
@Override
public void paint(Graphics g){
// 1.保留绘制组件本身的功能:调用父类的方法
super.paint(g); // super:表示当前类的父类对象
// 2.绘制当前的图像功能,把画好的缓冲区buff传递过来
g.drawImage(buff, 0 , 0 , null);
}
}
package com.gch.filterarithmetic;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
/**
事件处理类:给按钮添加动作监听器
*/
public class ButtonMouse implements ActionListener {
// 定义保存当前图像的缓冲区
private BufferedImage buff;
/**
定义get方法,获取属性
*/
public BufferedImage getBuff() {
return buff;
}
// 定义缓冲区数组,保存图层的数组
private BufferedImage[] buffArr = new BufferedImage[100];
// 定义操作数组的下标
private int index = 0;
// 保存当前的有效图层
private int count = 0;
// 标记位
public int flag = 1;
// 定义图像显示区/内容显示区对象
private MyPanel drawPanel;
// 定义画笔对象,保存传递过来的画笔对象
private Graphics g;
/**
定义set方法,初始化属性
*/
public void setG(MyPanel drawPanel) {
this.drawPanel = drawPanel;
}
/**
事件处理方法:动作监听器方法
*/
@Override
public void actionPerformed(ActionEvent e) {
//每次画之前重新获取画笔,可以让画笔的获取实时更新
g = drawPanel.getGraphics();
// 指定图片路径
String path = "C:\\Users\\A.G.H\\Pictures\\Camera Roll\\t0118a001acf2c4dc77.jpg";
// 把指定路径的图片转换为int型的二维数组,获取指定图片路径的像素点的像素值
int[][] pixelArr = getImagePixel(path);
// 获取按钮上的内容
String buttonName = e.getActionCommand();
// 根据不同的按钮选择来实现不同的滤镜算法
switch (buttonName){
case "原图":
masterPixel(pixelArr);
break;
case "马赛克":
mosaicPixel(pixelArr);
break;
case "灰度":
grayPixel(pixelArr);
break;
case "黑白":
blackWhitePixel(pixelArr);
break;
case "去色":
desaturatePixel(pixelArr);
break;
case "单色":
singleColorPixel(pixelArr);
break;
case "底片/反向":
artworkPixel(pixelArr);
break;
case "怀旧":
retroPixel(pixelArr);
break;
case "褐色":
brownPixel(pixelArr);
break;
case "连环画":
comicsPixel(pixelArr);
break;
case "冰冻":
freezePixel(pixelArr);
break;
case "熔铸":
castingPixel(pixelArr);
break;
case "浮雕":
reliefPixel(pixelArr);
break;
case "放大镜":
enlargePixel(pixelArr);
break;
case "左转":
leftPixel(pixelArr);
break;
case "右转":
rightPixel(pixelArr);
break;
}
if("撤回".equals(buttonName)) {
//取出最后一个图层
//把当前图层更新为撤回的图层
buff = buffArr[--count];
index = count;
System.out.println("buff=" +buff + "count="+count);
}else {
//保存当前图层
buffArr[index] = buff; //每按一次按钮就保存一次
count = index; //记录有效图层
index++;
System.out.println("index="+index);
}
//更新缓冲区对象后再把当前缓冲区传递给自定义类MyPanel
drawPanel.setBuff(buff); //每更新一次就传一次
//刷新面板
drawPanel.repaint();
}
/**将图片转换为int型的二维数组,获取图片像素的宽高,获取每个像素点的像素值
* 获取指定路径图片的像素点的像素值
* @param path:指定图片路径
* @return:返回保存指定路径图片像素点的像素值的二维数组
*/
public int[][] getImagePixel(String path){
// 创建文件对象
File file = new File(path);
// BufferedImage:图像缓冲区,图片数据的封装类
BufferedImage bufferedImage = null;
// 用输入流读取指定文件的数据
try {
bufferedImage = ImageIO.read(file);
} catch (IOException e) {
throw new RuntimeException(e);
}
// 获取图片像素的宽高
int w = bufferedImage.getWidth(); // 宽:对应二维数组的列
int h = bufferedImage.getHeight(); // 高:对应二维数组的行
// 保存到二维数组
int[][] pixelArr = new int[h][w];
// 遍历二维数组的每一个元素,通过双层循环遍历整个图片的像素点
for(int i = 0;i < h;i++){
for(int j = 0;j < w;j++){
// 通过图像缓冲区bufferedImage对象的getRGB()方法获取每个像素点的像素值
int pixel = bufferedImage.getRGB(j, i);
// 把每个像素点的像素值保存到二维数组中
pixelArr[i][j] = pixel;
}
}
// 返回保存指定图片像素点的像素值的二维数组
return pixelArr;
}
/**
* 原图效果
* @param pixelArr:保存图片像素点的像素值的二维数组
*/
public void masterPixel(int[][]pixelArr) {
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
//把像素点存到缓冲区里 缓冲区它也是个容器
//2.获取缓冲区的画笔对象 buffG缓冲画笔 把像素点画到缓冲区里面
Graphics buffG = buff.getGraphics();
for(int i=0;i<pixelArr.length;i++) {
for(int j=0;j<pixelArr[i].length;j++) {
//取出所有的像素值
int pixel =pixelArr[i][j];
//把像素值转为Color对象
Color color = new Color(pixel);
//把所有的像素点画在缓冲区里面
//把画笔设置成当前颜色
buffG.setColor(color);
//绘制出当前颜色的像素点
buffG.fillRect(j, i, 1, 1);
}
}
//把图片显示在窗体上 缓冲区是个组件,如果你不把它显示出来,根本就看不见,缓冲区它是个图片 缓冲区/缓存图片
g.drawImage(buff, 0, 0,null); //drawImage方法它重载了好多次
}
/**
马赛克效果:在固定范围内放大像素点
*/
public void mosaicPixel(int[][]pixelArr) {
//创建缓冲区的对象 BufferedImage buff = new BufferedImage(width, height, imageType) 常量,可以直接通过类名来调用
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
//2.获取缓冲区的画笔对象 buffG缓冲画笔 把像素点画到缓冲区里面
Graphics buffG = buff.getGraphics();
for(int i=0;i<pixelArr.length;i+=10) { //放大了几倍,就跳过几个像素
for(int j=0;j<pixelArr[i].length;j+=10) {
//取出图片的所有像素值
int pixel = pixelArr[i][j];
//把像素值转为Color对象
Color color = new Color(pixel);
//把画笔对象设置成当前颜色
buffG.setColor(color);
//绘制出当前颜色的像素点 因为每一个像素点的位置是不一样的
buffG.fillRect(j, i, 10, 10); //放大了10倍数
}
}
g.drawImage(buff, 0, 0, null);
}
/**
灰度效果
*/
public void grayPixel(int[][]pixelArr) {
//创建缓冲区对象
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
//2.获取缓冲区的画笔对象 buffG缓冲画笔 把像素点画到缓冲区里面
Graphics buffG = buff.getGraphics();
for(int i=0;i<pixelArr.length;i++) {
for(int j=0;j<pixelArr[i].length;j++) {
//取出所有的像素值
int pixel = pixelArr[i][j];
//把像素值转为Color对象
Color color = new Color(pixel);
//取RGB平均值,则画成灰度图
int red = color.getRed();
int green = color.getGreen();
int blue = color.getBlue();
int ave = (red+green+blue)/3;
//把平均值作为三原色的基础值
Color nc = new Color(ave,ave,ave);
buffG.setColor(nc);
buffG.fillRect(j, i, 1, 1);
}
}
g.drawImage(buff, 0, 0, null);
}
//2.通过将像素值右移得到RGB三原色的分量值
public void drawPixel4(int[][]pixelArr) {
//创建缓冲区对象
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
//2.获取缓冲区的画笔对象 buffG缓冲画笔 把像素点画到缓冲区里面
Graphics buffG = buff.getGraphics();
for(int i=0;i<pixelArr.length;i++) {
for(int j=0;j<pixelArr[0].length;j++) {
//取出所有的像素值
int pixel = pixelArr[i][j];
//通过右移取出pixel像素中的三原色
int red = (pixel>>16)&0xFF; //位运算:只有1&1=1
int green = (pixel>>8)&0xFF;
int blue = (pixel>>0)&0xFF;
//取RGB平均值
int ave = (red+green+blue)/3;
//把平均值作为三原色的初始值
Color nc = new Color(ave,ave,ave);
buffG.setColor(nc);
buffG.fillRect(j, i, 1, 1);
}
}
g.drawImage(buff, 0, 0, null);
}
//3.取三种颜色的最大值来实现灰度滤镜
public void drawPixel5(int[][]pixelArr) {
//创建缓冲区对象
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
//2.获取缓冲区的画笔对象 buffG缓冲画笔 把像素点画到缓冲区里面
Graphics buffG = buff.getGraphics();
for(int i=0;i<pixelArr.length;i++) {
for(int j=0;j<pixelArr[i].length;j++) {
//取出所有的像素值
int pixel = pixelArr[i][j];
//通过将像素值右移得到RGB三原色分量值
int red = (pixel>>16)&0xFF;
int green =(pixel>>8)&0xFF;
int blue =(pixel>>0)&0xFF;
int tempmax = Math.max(red, green); //int tempmax = (red>green)?red:green;
int max =Math.max(tempmax, blue); //int max = (tempmax>blue)?tempmax:blue;
//把三种颜色最大值作为三原色的初始值
Color nc = new Color(max,max,max);
//把画笔设置成当前颜色
buffG.setColor(nc);
buffG.fillRect(j, i, 1, 1);
}
}
g.drawImage(buff, 0, 0, null);
}
//4.取三种颜色的最小值来实现灰度滤镜
public void drawPixel6(int[][]pixelArr) {
//创建缓冲区对象
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
//2.获取缓冲区的画笔对象 buffG缓冲画笔 把像素点画到缓冲区里面
Graphics buffG = buff.getGraphics();
for(int i=0;i<pixelArr.length;i++) {
for(int j=0;j<pixelArr[0].length;j++) {
//取出所有的像素值
int pixel = pixelArr[i][j];
//通过将像素值右移得到RGB三原色分量值
int red = (pixel>>16)&0xFF;
int green =(pixel>>8)&0xFF;
int blue =(pixel>>0)&0xFF;
int tempmin = Math.min(red, green); //int tempmin = (red<green)?red:green;
int min = Math.min(tempmin, blue); //int min =(tempmin<blue)?tempmin:blue;
//把三原色的最小值作为RGB三原色的初始值
Color color = new Color(min,min,min);
buffG.setColor(color);
buffG.fillRect(j, i, 1, 1);
}
}
g.drawImage(buff,0, 0, null);
}
/**
黑白滤镜
*/
public void blackWhitePixel(int[][]pixelArr) {
//创建缓冲区对象
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
//2.获取缓冲区的画笔对象 buffG缓冲画笔 把像素点画到缓冲区里面
Graphics buffG = buff.getGraphics();
for(int i=0;i<pixelArr.length;i++) {
for(int j=0;j<pixelArr[i].length;j++) {
int pixel = pixelArr[i][j];
//通过将像素值右移得到RGB三原色的分量值
int red = (pixel>>16)&0xFF;
int green =(pixel>>8)&0xFF;
int blue = (pixel>>0)&0xFF;
//计算RGB三原色平均值
int ave = (red+green+blue)/3;
if(ave>=100) {
ave = 255;
}else {
ave = 0;
}
//将ave设为RGB三原色初始值
Color color = new Color(ave,ave,ave);
buffG.setColor(color);
buffG.fillRect(j, i, 1, 1);
}
}
g.drawImage(buff, 0, 0, null);
}
/**
去色滤镜
*/
public void desaturatePixel(int[][]pixelArr) {
//创建缓冲区对象
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
//2.获取缓冲区的画笔对象 buffG缓冲画笔 把像素点画到缓冲区里面
Graphics buffG = buff.getGraphics();
for(int i=0;i<pixelArr.length;i++) {
for(int j=0;j<pixelArr[i].length;j++) {
//取出所有的像素值
int pixel = pixelArr[i][j];
//把像素值右移得到RGB三原色分量值
int red = (pixel>>16)&0xFF;
int green =(pixel>>8)&0xFF;
int blue = (pixel>>0)&0xFF;
//取RGB三原色的最大值
int tempmax = Math.max(red, green);
int max = Math.max(tempmax, blue);
//取RGB三原色的最小值
int tempmin =Math.min(red, green);
int min =Math.min(tempmin, blue);
//取RGB三原色最大值和最小值的平均值
int ave = (max+min)/2;
//把平均值设为RGB三原色的初始值
Color color = new Color(ave,ave,ave);
buffG.setColor(color);
buffG.fillRect(j, i, 1, 1);
}
}
g.drawImage(buff, 0, 0, null);
}
/**
单色滤镜
*/
public void singleColorPixel(int[][]pixelArr) {
//创建缓冲区对象
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
//2.获取缓冲区的画笔对象 buffG缓冲画笔 把像素点画到缓冲区里面
Graphics buffG = buff.getGraphics();
for(int i=0;i<pixelArr.length;i++) {
for(int j=0;j<pixelArr[i].length;j++) {
//取出所有的像素点
int pixel = pixelArr[i][j];
//把像素点转为Color对象
Color color = new Color(pixel);
//获取RGB三原色分量值
int red = color.getRed();
int green = color.getGreen();
int blue = color.getBlue();
//只保留一个颜色
Color nc = new Color(red,0,0);
buffG.setColor(nc);
buffG.fillRect(j, i, 1, 1);
}
}
g.drawImage(buff,0,0, null);
}
/**
底片/反向滤镜
*/
public void artworkPixel(int [][]pixelArr) {
//创建缓冲区对象
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
//2.获取缓冲区的画笔对象 buffG缓冲画笔 把像素点画到缓冲区里面
Graphics buffG = buff.getGraphics();
for(int i=0;i<pixelArr.length;i++) {
for(int j=0;j<pixelArr[i].length;j++) {
//取出所有的像素值
int pixel = pixelArr[i][j];
//把像素值右移得到RGB三原色的分量值
int red = 255 -(pixel>>16)&0xFF;
int green = 255-(pixel>>8)&0xFF;
int blue = 255 -(pixel>>0)&0xFF;
//把分量值设为RGB三原色初始值
Color color = new Color(red,green,blue);
buffG.setColor(color);
buffG.fillRect(j, i, 1, 1);
}
}
g.drawImage(buff, 0, 0, null);
}
/**
怀旧滤镜
*/
public void retroPixel(int[][]pixelArr) {
//创建缓冲区对象
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
//2.获取缓冲区的画笔对象 buffG缓冲画笔 把像素点画到缓冲区里面
Graphics buffG = buff.getGraphics();
for(int i=0;i<pixelArr.length;i++) {
for(int j=0;j<pixelArr[i].length;j++) {
//取出所有的像素值
int pixel =pixelArr[i][j];
//把像素值右移得到RGB三原色分量值
int red = (pixel>>16)&0xFF;
/// System.out.println("red="+red);
int green = (pixel>>8)&0xFF;
// System.out.println("green="+green);
int blue =(pixel>>0)&0xFF;
// System.out.println("blue="+blue);
int R = (int)(0.393*red+0.769*green+0.189*blue);
if(R>255) {
R=255;
}
// System.out.println("R="+R);
int G = (int)(0.349*red+0.686*green+0.168*blue);
if(G>255) {
G=255;
}
//System.out.println("G="+G);
int B = (int)(0.272*red+0.534*green+0.131*blue);
if(B>255) {
B=255;
}
//System.out.println("B="+B);
//把新的RGB值设为RGB三原色
Color color = new Color(R,G,B);
buffG.setColor(color);
buffG.fillRect(j, i, 1, 1);
}
}
g.drawImage(buff, 0, 0, null);
}
/**
褐色滤镜
*/
public void brownPixel(int pixelArr[][]) {
//创建缓冲区对象
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
//2.获取缓冲区的画笔对象 buffG缓冲画笔 把像素点画到缓冲区里面
Graphics buffG = buff.getGraphics();
for(int i=0;i<pixelArr.length;i++) {
for(int j=0;j<pixelArr[0].length;j++) {
int pixel = pixelArr[i][j];
int red = (pixel>>16)&0xFF;
int green = (pixel>>8)&0xFF;
int blue = (pixel>>0)&0xFF;
//褐色滤镜算法
red = (int)(red*0.393+green*0.769+blue*0.189);
if(red>255) {
red=255;
}
green = (int)(red*0.349+green*0.686+blue*0.168);
if(green>255) {
green=255;
}
blue = (int)(red*0.272+green*0.534+blue*0.131);
if(blue>255) {
blue = 255;
}
//把新的RGB值设为三原色初始值
Color color = new Color(red,green,blue);
buffG.setColor(color);
buffG.fillRect(j, i, 1, 1);
}
}
g.drawImage(buff, 0, 0, null);
}
/**
连环画滤镜
*/
public void comicsPixel(int[][]pixelArr) {
//创建缓冲区对象
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
//2.获取缓冲区的画笔对象 buffG缓冲画笔 把像素点画到缓冲区里面
Graphics buffG = buff.getGraphics();
for(int i=0;i<pixelArr.length;i++) {
for(int j=0;j<pixelArr[i].length;j++) {
//取出所有的像素点
int pixel = pixelArr[i][j];
int R = (pixel>>16)&0xFF;
int G = (pixel>>8)&0xFF;
int B = (pixel>>0)&0xFF;
R = Math.abs(G-B+G+R)*R/256;
if(R>255) {
R=255;
}
G = Math.abs(B-G+B+R)*R/256;
if(G>255) {
G=255;
}
B = Math.abs(B-G+B+R)*G/256;
if(B>255) {
B=255;
}
Color color = new Color(R,G,B);
buffG.setColor(color);
buffG.fillRect(j, i, 1, 1);
}
}
g.drawImage(buff, 0, 0, null);
}
/**
冰冻滤镜
*/
public void freezePixel(int pixelArr[][]) {
//创建缓冲区对象
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
//2.获取缓冲区的画笔对象 buffG缓冲画笔 把像素点画到缓冲区里面
Graphics buffG = buff.getGraphics();
for(int i=0;i<pixelArr.length;i++) {
for(int j=0;j<pixelArr[i].length;j++) {
int pixel = pixelArr[i][j];
int R = (pixel>>16)&0xFF;
int G = (pixel>>8)&0xFF;
int B = (pixel>>0)&0xFF;
R = (R-G-B)*3/2;
if(R<0) {
R=0;
}else if(R>255) {
R=255;
}
//System.out.println("R="+R);
G = (G-R-B)*3/2;
if(G<0) {
G=0;
}else if(G>255) {
G=255;
}
// System.out.println("G="+G);
B = (B-G-R)*3/2;
if(B<0) {
B=0;
}else if(B>255) {
B=255;
}
// System.out.println("B="+B);
Color color = new Color(R,G,B);
buffG.setColor(color);
buffG.fillRect(j, i, 1, 1);
}
}
g.drawImage(buff, 0, 0, null);
}
/**
熔铸滤镜
*/
public void castingPixel(int[][]pixelArr) {
//创建缓冲区对象
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
//2.获取缓冲区的画笔对象 buffG缓冲画笔 把像素点画到缓冲区里面
Graphics buffG = buff.getGraphics();
for(int i=0;i<pixelArr.length;i++) {
for(int j=0;j<pixelArr[0].length;j++) {
int pixel = pixelArr[i][j];
int R = (pixel>>16)&0xFF;
int G = (pixel>>8)&0xFF;
int B = (pixel>>0)&0xFF;
R = R*128/(G+B+1);
if(R<0) {
R=0;
}else if(R>255){
R =255;
}
G = G*128/(R+B+1);
if(G<0) {
G=0;
}else if(G>255) {
G=255;
}
B = B*128/(G+R+1);
if(B<0) {
B=0;
}else if(B>255) {
B=255;
}
//
Color color = new Color(R,G,B);
buffG.setColor(color);
buffG.fillRect(j, i,1,1);
}
}
g.drawImage(buff, 0, 0, null);
}
/**
浮雕效果
*/
public void reliefPixel(int[][]pixelArr) {
//创建缓冲区对象
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
//2.获取缓冲区的画笔对象 buffG缓冲画笔 把像素点画到缓冲区里面
Graphics buffG = buff.getGraphics();
for(int i =0;i<pixelArr.length-1;i++) {
for(int j=0;j<pixelArr[0].length-1;j++) {
int pixel0 = pixelArr[i][j];
Color color0 = new Color(pixel0);
int R0 = color0.getRed();
int G0 = color0.getGreen();
int B0 = color0.getBlue();
int pixel1 = pixelArr[i+1][j+1];
Color color1 = new Color(pixel1);
int R1 = color1.getRed();
int G1 = color1.getGreen();
int B1 = color1.getBlue();
int NR = R0-R1+128;
if(NR<0) {
NR = 0;
}else if(NR>255){
NR = 255;
}
int NG = G0-G1+128;
if(NG<0) {
NG = 0;
}else if(NG>255) {
NG = 255;
}
int NB = B0-B1+128;
if(NB<0) {
NB = 0;
}else if(NB>255) {
NB = 255;
}
Color nc = new Color(NR,NG,NB);
buffG.setColor(nc);
buffG.fillRect(j, i, 1, 1);
}
}
g.drawImage(buff, 0, 0, null);
}
/**
放大镜
*/
public void enlargePixel(int[][]pixelArr) {
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
Graphics buffG = buff.getGraphics();
for(int i=0;i<pixelArr.length;i++) { //放大了几倍,就跳过几个像素
for(int j=0;j<pixelArr[i].length;j++) {
//取出图片的所有像素值
int pixel = pixelArr[i][j];
//把像素值转为Color对象
Color color = new Color(pixel);
//把画笔对象设置成当前颜色
buffG.setColor(color);
//绘制出当前颜色的像素点 因为每一个像素点的位置是不一样的
buffG.fillRect(j, i, 1, 1); //放大了10倍数
}
} //同比例缩放
g.drawImage(buff, 0, 0,pixelArr[0].length+220, pixelArr.length+220, null);
}
/**
左转90°
*/
public int[][] leftPixel(int[][]pixelArr) {
//新建数组
int [][] newArr = {};
//第一次旋转 现在的行是原来列数的最大索引-原来的列 现在的列是原来的行
if(flag%4 == 1) {
//创建缓冲区对象
buff = new BufferedImage(pixelArr.length, pixelArr[0].length, BufferedImage.TYPE_INT_RGB);
//新建数组的大小
newArr = new int[pixelArr[0].length][pixelArr.length];
for(int i = 0;i < pixelArr.length;i++ ) {
for(int j = 0;j < pixelArr[0].length;j++) {
newArr[pixelArr[0].length-1-j][i] = pixelArr[i][j];
}
}
flag++;
}
//第二次旋转 现在的行是原来的行 现在的列是原来列的最大索引-列
else if(flag%4 == 2) {
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
newArr = new int[pixelArr.length][pixelArr[0].length];
for(int i = 0;i < pixelArr.length;i++) {
for(int j = 0;j < pixelArr[0].length;j++) {
newArr[i][pixelArr[0].length-1-j] = pixelArr[i][j];
}
}
flag++;
}
//第三次旋转 现在的行是原来的列 现在的列是原来的行
else if(flag%4 == 3) {
buff = new BufferedImage(pixelArr.length, pixelArr[0].length, BufferedImage.TYPE_INT_RGB);
newArr = new int[pixelArr[0].length][pixelArr.length];
for(int i = 0;i < pixelArr.length;i++) {
for(int j = 0;j < pixelArr[0].length;j++) {
newArr[j][i] = pixelArr[i][j];
}
}
flag++;
}
//第四次旋转
else if(flag%4 == 0) {
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
newArr = pixelArr;
flag++;
}
//获取缓冲区的画笔对象
Graphics buffG = buff.getGraphics();
for(int i = 0;i < newArr.length;i++) {
for(int j = 0;j < newArr[0].length;j++) {
//取出所有的像素值
int pixel = newArr[i][j];
//把像素值转为Color对象
Color color = new Color(pixel);
//把缓冲画笔设置成当前颜色
buffG.setColor(color);
//绘制出当前颜色的像素点
buffG.fillRect(j, i, 1, 1);
}
}
g.drawImage(buff,100,100,null);
return newArr;
}
/**
右转90°
*/
public int[][] rightPixel(int[][]pixelArr){
//新建数组
int [][] newArr = {} ;
//第一次旋转 现在的行是原来的列 现在的列是原来行数的最大索引-原来的行
if(flag%4 == 1) {
//创建缓冲区对象
buff = new BufferedImage(pixelArr.length, pixelArr[0].length, BufferedImage.TYPE_INT_RGB);
//新建数组的大小
newArr = new int[pixelArr[0].length][pixelArr.length];
for(int i = 0;i < pixelArr.length;i++ ) {
for(int j = 0;j < pixelArr[0].length;j++) {
newArr[j][pixelArr.length-1-i] = pixelArr[i][j];
}
}
flag++;
}
//第二次旋转 现在的行是原来行的最大索引-行 现在的列是原来列的最大索引-列
else if(flag%4 == 2) {
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
newArr = new int[pixelArr.length][pixelArr[0].length];
for(int i = 0;i < pixelArr.length;i++) {
for(int j = 0;j < pixelArr[0].length;j++) {
newArr[pixelArr.length-1-i][pixelArr[0].length-1-j] = pixelArr[i][j];
}
}
flag++;
}
//第三次旋转 现在的行是原来列的最大索引-列 现在的列是原来的行
else if(flag%4 == 3) {
buff = new BufferedImage(pixelArr.length, pixelArr[0].length, BufferedImage.TYPE_INT_RGB);
newArr = new int[pixelArr[0].length][pixelArr.length];
for(int i = 0;i < pixelArr.length;i++) {
for(int j = 0;j < pixelArr[0].length;j++) {
newArr[pixelArr[0].length-1-j][i] = pixelArr[i][j];
}
}
flag++;
}
//第四次旋转
else if(flag%4 == 0) {
buff = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
newArr = pixelArr;
flag++;
}
//获取缓冲区的画笔对象
Graphics buffG = buff.getGraphics();
//遍历并画出像素点
for(int i = 0;i < newArr.length;i++) {
for(int j = 0;j < newArr[0].length;j++) {
//取出所有的像素值
int pixel = newArr[i][j];
//把像素值转为Color对象
Color color = new Color(pixel);
//把缓冲画笔设置成当前颜色
buffG.setColor(color);
//绘制出当前颜色的像素点
buffG.fillRect(j, i, 1, 1);
}
}
g.drawImage(buff, 100, 100, null);
return newArr;
}
}
package com.gch.filterarithmetic;
public class Manage {
/**
主函数
*/
public static void main(String[] args) {
PixelUI ui = new PixelUI();
ui.showUI();
}
}