📄 mypanel.java
字号:
/**
* MyPanel.java
*
* 该类显示两个图片:滤波前和滤波后的图片
* 用函数WFilter来对图片进行滤波处理
* 由于JAVA的Image类不直接支持bmp位图,所以要自己编写代码来显示位图
*
* Copyright 2004 by 海南大学信息学院
* @author 温小斌
* @version 1.0
*/
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.io.*;
import javax.swing.*;
import java.awt.color.*;
public class MyPanel extends JPanel
{
BufferedImage image;
FileInputStream fs;
int bflen=14; // 14 字节 BitmapFileHeader
byte bf[]=new byte[bflen];
int bilen=40; // 40 字节 BitmapInfoHeader
byte bi[]=new byte[bilen];
int nsize;
int nbisize;
int nwidth;
int nheight;
int nplanes;//位面数总为1
int nbitcount;//比特数/象素
int ncompression;//压缩数据
int nsizeimage;
int nxpm;
int nypm;
int nclrused;//使用的颜色索引
int nclrimp;//重要颜色索引
int nNumColors = 0;
int npalette[];
byte bpalette[];//调色板范围
int npad8;
int ndata8[];
byte bdata[];
protected void paintComponent(Graphics g) //重画,刷新
{
super.paintComponent(g);
if (image != null)
g.drawImage(image, 0, 0, null);
}
public void loadImage(String name, boolean filter, float a, float q, float c, float r) //参数name表示文件名,filter表示是否滤波
{
// 调用图像,在这之前需要先调用自定义的loadBitmap函数,这是因为JAVA不直接支持bmp位图
Image loadedImage
= loadBitmap(name, filter, a, q, c, r);
MediaTracker tracker = new MediaTracker(this);
tracker.addImage(loadedImage, 0);
try { tracker.waitForID(0); }
catch (InterruptedException e) {}
//调入图像缓冲
image = new BufferedImage(loadedImage.getWidth(null), loadedImage.getHeight(null), BufferedImage.TYPE_INT_BGR);
Graphics2D g2 = image.createGraphics();
g2.drawImage(loadedImage, 0, 0, null);
repaint(); //调用paintComponent刷新窗口
}
public Image loadBitmap(String name, boolean filter, float a, float q, float c, float r)
{
Image bitmap;
try{
fs=new FileInputStream(name);
fs.read(bf,0,bflen);
fs.read(bi,0,bilen);
//解释数据
nsize = (((int)bf[5]&0xff)<<24) | (((int)bf[4]&0xff)<<16) | (((int)bf[3]&0xff)<<8) | (int)bf[2]&0xff;
nbisize = (((int)bi[3]&0xff)<<24) | (((int)bi[2]&0xff)<<16) | (((int)bi[1]&0xff)<<8) | (int)bi[0]&0xff;
nwidth = (((int)bi[7]&0xff)<<24) | (((int)bi[6]&0xff)<<16) | (((int)bi[5]&0xff)<<8) | (int)bi[4]&0xff;
nheight = (((int)bi[11]&0xff)<<24) | (((int)bi[10]&0xff)<<16) | (((int)bi[9]&0xff)<<8) | (int)bi[8]&0xff;
nplanes = (((int)bi[13]&0xff)<<8) | (int)bi[12]&0xff;
nbitcount = (((int)bi[15]&0xff)<<8) | (int)bi[14]&0xff;
ncompression = (((int)bi[19])<<24) | (((int)bi[18])<<16) | (((int)bi[17])<<8) | (int)bi[16];
nsizeimage = (((int)bi[23]&0xff)<<24) | (((int)bi[22]&0xff)<<16) | (((int)bi[21]&0xff)<<8) | (int)bi[20]&0xff;
nxpm = (((int)bi[27]&0xff)<<24) | (((int)bi[26]&0xff)<<16) | (((int)bi[25]&0xff)<<8) | (int)bi[24]&0xff;
nypm = (((int)bi[31]&0xff)<<24) | (((int)bi[30]&0xff)<<16) | (((int)bi[29]&0xff)<<8) | (int)bi[28]&0xff;
nclrused = (((int)bi[35]&0xff)<<24) | (((int)bi[34]&0xff)<<16) | (((int)bi[33]&0xff)<<8) | (int)bi[32]&0xff;
nclrimp = (((int)bi[39]&0xff)<<24) | (((int)bi[38]&0xff)<<16) | (((int)bi[37]&0xff)<<8) | (int)bi[36]&0xff;
if (nbitcount == 8) //如果是256色位图
{
if (nclrused > 0)//clrused 为0表示使用所有调色板项
nNumColors = nclrused;
else
nNumColors = (1&0xff)<<nbitcount;
// 读取调色板颜色。
npalette = new int [nNumColors];
bpalette = new byte [nNumColors*4];
fs.read (bpalette, 0, nNumColors*4);
int nindex8 = 0;
for (int n = 0; n < nNumColors; n++)
{
npalette[n] = (255&0xff)<<24 | (((int)bpalette[nindex8+2]&0xff)<<16) | (((int)bpalette[nindex8+1]&0xff)<<8) | (int)bpalette[nindex8]&0xff;
nindex8 += 4;
}
// 读取图像数据(实际上是调色板的索引)
// 扫描行仍被补足到 4 个字节。
npad8 = (nsizeimage / nheight) - nwidth;
ndata8 = new int [nwidth*nheight];
bdata = new byte [(nwidth+npad8)*nheight];
fs.read (bdata, 0, (nwidth+npad8)*nheight);
nindex8 = 0;
for (int j8 = 0; j8 < nheight; j8++)
{
for (int i8 = 0; i8 < nwidth; i8++)
{
if(filter) //如果需要滤波,调用滤波函数WFilter
{
ndata8 [nwidth*(nheight-j8-1)+i8] = npalette [(WFilter(nindex8, a, q, c, r)&0xff)];
nindex8++;
}
else //如果不需要滤波
{
ndata8 [nwidth*(nheight-j8-1)+i8] = npalette [((int)bdata[nindex8]&0xff)];
nindex8++;
}
}
nindex8 += npad8;
}
bitmap = createImage(new MemoryImageSource(nwidth, nheight, ndata8, 0, nwidth)); //产生Image的对象bitmap
}
else
{
return (Image)null;
}
fs.close();
return bitmap;
}
catch(Exception e){
System.err.println(e);
return (Image)null;
}
}
//维纳滤波函数
public int WFilter(int n, float a, float q, float c, float r)
{
// x 为滤波器的输入信号
float p;
float p1, p2, p3, p4, p5;
float g;
float f;
//滤波器的冲激响应
int j;
int s[]; //滤波器的输出信号
p1 = (a*a-1)*r;
p2 = c*c*q;
p3 = (a*a-1)*(a*a-1)*r*r;
p4 = 2*c*c*r*q*(1+a*a);
p5 = c*c*c*c*q*q;
p = (float)((p1+p2+Math.sqrt(p3+p4+p5))/(2*a));
g = (c*p)/(r+c*c*p);
f = a*(1-c*g);
/*
for(int i=0; i<=n; i++)
{
s += g*(float)Math.pow(f, n)*bdata[n-i];
}
*/
if(j=0)
{
s[j]=g*bdata[0];
return Math.round(s);
}
else
{
for(int i=1;i<=n;i++)
{j=i;
s[j]=f*s[j-1]+g*bdata[i]
/*s=g*f*bdata[n];*/
return Math.round(s);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -