绘制图片,简单图片处理,清除画板
一、创建窗体
创建PixelUI类,用来创建窗体。
package beauty_camera02;
import javax.swing.*;
import java.awt.*;
public class PixelUI extends JFrame implements Data {
JFrame jf = new JFrame();
public void initUI(){
jf.setTitle("Beauty camera");
jf.setSize(FW,FH);
jf.setLayout(new FlowLayout());
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
// 按钮
Graphics g = jf.getGraphics();
PixelMouse pixelMouse = new PixelMouse(g);
jf.addMouseListener(pixelMouse);
String[] options = {"SrcImage","Mosaic","Grey","NegativePlate","Relief","ClockWise","Clear"};
for (int i = 0; i < options.length; i++) {
JButton btn = new JButton(options[i]);
jf.add(btn);
btn.addActionListener(pixelMouse);
}
}
public static void main(String[] args) {
PixelUI pixelUI = new PixelUI();
pixelUI.initUI();
}
}
二、创建方法类
1、创建PixelMouse类
接入MouseListener, ActionListener, Data接口。
package beauty_camera02;
import javax.imageio.ImageIO;
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.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class PixelMouse implements MouseListener, ActionListener, Data {
private Graphics g;
private double currentAngle;
public PixelMouse(Graphics g){
this.g = g;
}
@Override
public void actionPerformed(ActionEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}
2、获取图片文件像素点
public int[][] getImagePixel(String path){
//创建图片文件
File file = new File(path);
//读取图片文件数据
BufferedImage bufferedImage = null;
try {
bufferedImage = ImageIO.read(file);
} catch (IOException e) {
throw new RuntimeException(e);
}
int w = bufferedImage.getWidth();
int h = bufferedImage.getHeight();
int[][] piexlArr = new int[h][w];
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
int pixel = bufferedImage.getRGB(j,i);
piexlArr[i][j] = pixel;
}
}
return piexlArr;
}
3、绘制图像及简单处理
(1)原图
public void drawPixel(int[][] pixelArr){
//创建一个新的BufferedImage对象,用于储存图像数据
BufferedImage bufferedImage = new BufferedImage(pixelArr[0].length,pixelArr.length,BufferedImage.TYPE_INT_ARGB);
for (int i = 0; i < pixelArr.length; i++) {
for (int j = 0; j < pixelArr[0].length; j++) {
int pixel = pixelArr[i][j];
//透明度
int alpha = pixel >> 24 & 0xFF;
int red = pixel >> 16 & 0xFF;
int green = pixel >> 8 & 0xFF;
int blue = pixel >> 0 & 0xFF;
// 通过位操作组合alpha、red、green和blue分量到32位整数中
int a = (alpha << 24) | (red << 16) | (green << 8) | blue;
// 将计算出的ARGB颜色值设置到BufferedImage对象中对应的像素位置
bufferedImage.setRGB(j, i, a);
}
}
//Graphics转化为Graphics2D对象
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(bufferedImage,PX,PY,null);
}
(2)马赛克
public void drawMosaic(int[][] pixelArr){
int mosaicSize = 10;
if (pixelArr != null && g != null){
for (int i = 0; i < pixelArr.length; i+=mosaicSize){
for (int j = 0; j < pixelArr[0].length; j+=mosaicSize){
int redSum = 0, greenSum = 0, blueSum = 0;
int count = 0;
for (int k = i; k < i + mosaicSize && k < pixelArr.length; k++){
for (int l = j; l < j + mosaicSize && l < pixelArr[0].length; l++){
int pixel = pixelArr[k][l];
redSum += (pixel >> 16) & 0xFF;
greenSum += (pixel >> 8) & 0xFF;
blueSum += (pixel) & 0xFF;
count++;
}
}
int red =redSum / count;
int green =greenSum / count;
int blue =blueSum / count;
Color color = new Color(red,green,blue);
g.setColor(color);
int Width = Math.min(mosaicSize, pixelArr[0].length - j);
int Height = Math.min(mosaicSize, pixelArr.length - i);
g.fillRect(j+PX,i+PY,Width,Height);
}
}
}
}
(3)灰度
public void drawGrayLevel(int[][] pixelArr) {
BufferedImage bufferedImage = new BufferedImage(pixelArr[0].length,pixelArr.length,BufferedImage.TYPE_INT_ARGB);
for (int i = 0; i < pixelArr.length; i++) {
for (int j = 0; j < pixelArr[0].length; j++) {
int pixel = pixelArr[i][j];
int gray = (int) ((pixel >> 16 & 0xFF) * 0.299 + (pixel >> 8 & 0xFF) * 0.587 + (pixel & 0xFF) * 0.114);
// pixelArr[i][j] = (gray << 16) | (gray << 8) | gray;
int alpha = pixel >> 24 & 0xFF;
int a = (alpha << 24) | (gray << 16) | (gray << 8) | gray;
bufferedImage.setRGB(j, i, a);
}
}
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(bufferedImage,PX,PY,null);
}
(4)底片
public void drawNegativePlate(int[][] pixelArr){
BufferedImage bufferedImage = new BufferedImage(pixelArr[0].length,pixelArr.length,BufferedImage.TYPE_INT_ARGB);
for (int i = 0; i < pixelArr.length; i++) {
for (int j = 0; j < pixelArr[0].length; j++) {
int pixel = pixelArr[i][j];
int alpha = (pixel >> 24) & 0xFF;
int red = (pixel >> 16) & 0xFF;
int green = (pixel >> 8) & 0xFF;
int blue = pixel & 0xFF;
int negativeRed = 255 - red;
int negativeGreen = 255 - green;
int negativeBlue = 255 - blue;
int a =(alpha << 24) | (negativeRed << 16) | (negativeGreen << 8) | negativeBlue;
bufferedImage.setRGB(j,i,a);
}
}
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(bufferedImage,PX,PY,null);
}
(5)浮雕
public void drawRelief(int[][] pixelArr) {
BufferedImage bufferedImage = new BufferedImage(pixelArr[0].length,pixelArr.length,BufferedImage.TYPE_INT_ARGB);
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 & 0xFF;
// 增加每个颜色通道的值,以创建浮雕效果
red += 30;
green += 30;
blue += 30;
// 限制颜色值在0到255之间
red = Math.min(255, Math.max(0, red));
green = Math.min(255, Math.max(0, green));
blue = Math.min(255, Math.max(0, blue));
// 组合新的像素值
int alpha = pixel >> 24 & 0xFF;
int a = (alpha << 24) | (red << 16) | (green << 8) | blue;
// // 更新像素数组
// pixelArr[i][j] = a;
bufferedImage.setRGB(j,i,a);
}
}
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(bufferedImage,PX,PY,null);
}
(6)旋转
public void clockWise(int[][] pixelArr,double angle){
int W = pixelArr[0].length;
int H = pixelArr.length;
BufferedImage bufferedImage = new BufferedImage(W,H,BufferedImage.TYPE_INT_ARGB);
for (int i = 0; i < pixelArr.length; i++) {
for (int j = 0; j < pixelArr[0].length; j++) {
int pixel = pixelArr[i][j];
//透明度
int alpha = pixel >> 24 & 0xFF;
int red = pixel >> 16 & 0xFF;
int green = pixel >> 8 & 0xFF;
int blue = pixel >> 0 & 0xFF;
// 通过位操作组合alpha、red、green和blue分量到32位整数中
int a = (alpha << 24) | (red << 16) | (green << 8) | blue;
// 将计算出的ARGB颜色值设置到BufferedImage对象中对应的像素位置
bufferedImage.setRGB(j, i, a);
}
}
//Graphics转化为Graphics2D对象
Graphics2D g2d = (Graphics2D) g;
// 保存当前变换矩阵
AffineTransform originalTransform = g2d.getTransform();
//将绘制中心移到图片中心
int x = bufferedImage.getWidth()/2;
int y = bufferedImage.getHeight()/2;
g2d.translate(x+PX,y+PX);
//应用旋转变换
g2d.rotate(Math.toRadians(angle));
//绘制旋转后的图片
g2d.drawImage(bufferedImage,-x,-y,null);
//回复原始变换矩阵
g2d.setTransform(originalTransform);
}
(7)清除画布
public void clear(){
Graphics2D g2d = (Graphics2D) g;
g2d.clearRect(0,100,FW,FH);
//旋转度数清零
currentAngle = 0;
}
4、按钮监听器添加
@Override
public void actionPerformed(ActionEvent e) {
int[][] pixelArr = getImagePixel(path);
String ac =e.getActionCommand();
if (ac.equals("SrcImage")){
drawPixel(pixelArr);
}else if (ac.equals("Mosaic")){
drawMosaic(pixelArr);
}else if (ac.equals("Grey")){
drawGrayLevel(pixelArr);
}else if (ac.equals("NegativePlate")){
drawNegativePlate(pixelArr);
}else if (ac.equals("Relief")) {
drawRelief(pixelArr);
}else if (ac.equals("ClockWise")){
currentAngle = getCurrentAngle();
double newAngle = currentAngle+45;
setCurrentAngle(newAngle);
System.out.println(newAngle);
clockWise(pixelArr,newAngle);
}if (ac.equals("Clear")){
clear();
}
}
// 获取当前的角度
public double getCurrentAngle(){
System.out.println(currentAngle);
return currentAngle;
}
//设置新的角度
public void setCurrentAngle(double newAngle){
currentAngle = newAngle;
}