初次提交

This commit is contained in:
2022-09-19 18:05:01 +08:00
commit 57051fc44b
5401 changed files with 325410 additions and 0 deletions

View File

@@ -0,0 +1,147 @@
package com.bn;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.*;
import java.awt.color.*;
import java.io.*;
import javax.imageio.ImageIO;
public class NormalMapUtil extends JFrame
{
//创建显示源图像的标签,并将其放置到滚动窗格中
JLabel jls=new JLabel();
JScrollPane jspz=new JScrollPane(jls);
//创建显示目标图像的标签,并将其放置到滚动窗格中
JLabel jlt=new JLabel();
JScrollPane jspy=new JScrollPane(jlt);
//创建分割窗格,并设置各子窗格中显示的控件
JSplitPane jsp=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,jspz,jspy);
//创建文件选择器
JFileChooser jfc;
//定义一个图标引用
ImageIcon ii;
public NormalMapUtil()
{
String path=new File("a").getAbsolutePath();
path=path.substring(0,path.length()-2);
jfc=new JFileChooser(path);
//加载选择的图片到图标对象中
ii=this.chooserFile();
//将图片设置到源标签中
jls.setIcon(ii);
//设置两个标签的水平、垂直对齐方式
jls.setVerticalAlignment(JLabel.CENTER);
jls.setHorizontalAlignment(JLabel.CENTER);
jlt.setVerticalAlignment(JLabel.CENTER);
jlt.setHorizontalAlignment(JLabel.CENTER);
//设置分隔条的宽度以及初始位置
jsp.setDividerLocation(500);
jsp.setDividerSize(4);
//将分割窗格添加到窗体中
this.add(jsp);
//设置窗体的标题、大小位置以及可见性
this.setTitle("高度域灰度图转换成法向量纹理图工具");
this.setBounds(0,0,1000,500);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Image iTemp=process();
//将处理后的图片设置到目标标签中
jlt.setIcon(new ImageIcon(iTemp));
try
{
FileOutputStream os = new FileOutputStream("resultnt.jpg");
System.out.println(((RenderedImage)iTemp).getColorModel());
ImageIO.write((RenderedImage)iTemp, "JPEG", os);
os.flush();
os.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
//加载选中图片的方法
public ImageIcon chooserFile()
{
//弹出文件选择器
int i=jfc.showOpenDialog(this);
//获取选择文件的路径
String dir=(jfc.getSelectedFile()!=null)?(jfc.getSelectedFile().getPath()):null;
if(dir!=null&&!dir.equals(""))
{
//按指定的路径加载图片到图标对象中并返回
return new ImageIcon(dir);
}
return null;
}
//从源高度图生成凹凸贴图的方法
public Image process(){
int width=ii.getImage().getWidth(null);//获取待处理图像的宽度与高度
int height=ii.getImage().getHeight(null);
//创建两个BufferedImage对象分别用来放置待处理图像与处理后的图像
BufferedImage sourceBuf=new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
BufferedImage targetBuf=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//将待处理图像绘制加载到源BufferedImage对像中
Graphics graph=sourceBuf.getGraphics();
graph.drawImage(ii.getImage(),0,0,Color.white,null);
for(int i=0;i<height;i++){//对待处理图中像素的行循环
for(int j=0;j<width;j++){//对待处理图中像素的列循环
int color=sourceBuf.getRGB(j,i);//获取指定位置处的像素
//拆分出RGB三个色彩通道的值
int r=(color >> 16) & 0xff;int g=(color >> 8) & 0xff;int b=(color) & 0xff;
float c=(r+g+b)/3.0f/255.0f;//求出折算后此像素的高度
if(i==0||j==width-1){//若为最左侧一列或最上面一行的像素不用计算
targetBuf.setRGB(j,i,0xFF8080FF);
continue;
}
//取出正上方像素的值并折算成高度
int colorUp=sourceBuf.getRGB(j,i-1);
int rUp=(colorUp >> 16) & 0xff;
int gUp=(colorUp >> 8) & 0xff;
int bUp=(colorUp) & 0xff;
float cUp=(rUp+gUp+bUp)/3.0f/255.0f;
//取出正右侧像素的值并折算成高度
int colorRight=sourceBuf.getRGB(j+1,i);
int rRight=(colorRight >> 16) & 0xff;
int gRight=(colorRight >> 8) & 0xff;
int bRight=(colorRight) & 0xff;
float cRight=(rRight+gRight+bRight)/3.0f/255.0f;
//计算出两个差分向量
float[] vec1={1,0,cUp-c};
float[] vec2={0,1,cRight-c};
//将差分向量叉积得到结果向量
float[] vResult=VectorUtil.getCrossProduct(vec1[0],vec1[1],vec1[2]*4,vec2[0],vec2[1],vec2[2]*4);
vResult=VectorUtil.vectorNormal(vResult);
//将结果向量各分量值折算到0-255的范围内
int cResultRed=(int)(vResult[0]*128)+128;
int cResultGreen=(int)(vResult[1]*128)+128;
int cResultBlue=(int)(vResult[2]*128)+128;
cResultRed=(cResultRed>255)?255:cResultRed;
cResultGreen=(cResultGreen>255)?255:cResultGreen;
cResultBlue=(cResultBlue>255)?255:cResultBlue;
//将结果向量送入像素
int cResult=0xFF000000;
cResult+=cResultRed<<16;
cResult+=cResultGreen<<8;
cResult+=cResultBlue;
targetBuf.setRGB(j,i,cResult);
}
}
return targetBuf;
}
public static void main(String[] args)
{
//创建Sample29_8窗体对象
new NormalMapUtil();
}
}

View File

@@ -0,0 +1,20 @@
package com.bn;
//向量计算方法的封装类
public class VectorUtil{
//求两个向量的叉积
public static float[] getCrossProduct(float x1,float y1,float z1,float x2,float y2,float z2){
//求出两个矢量叉积矢量在XYZ轴的分量ABC
float A=y1*z2-y2*z1;
float B=z1*x2-z2*x1;
float C=x1*y2-x2*y1;
return new float[]{A,B,C};
}
public static float[] vectorNormal(float[] vector){//向量规格化
float module=(float)Math.sqrt(vector[0]*vector[0]+vector[1]*vector[1]+vector[2]*vector[2]);//求向量的模
return new float[]{vector[0]/module,vector[1]/module,vector[2]/module};
}
public static float mould(float[] vec){//求向量的模
return (float)Math.sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1 @@
java -cp . com.bn.NormalMapUtil

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB