class="MsoNormal" style="line-height: 11pt; margin: 0cm 0cm 10pt;">这是一个BMP解码器的练习,实现8位,24位真彩的解码,放在这里做个记录。希望对各位有用:(分为四个文件,大家可以下载压缩文件,不需要Ctrl+A)
package text;
?
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
?
import javax.swing.JFrame;
?
public class BMPopener extends JFrame{
????? private Graphics g;
????? public MenuBar creatMenuBar(){
?????????? MenuBar mB = new MenuBar();
?????????? //定义一个菜单
????? ??? Menu mn1 = new Menu("文件");
????? ??? MenuItem mn1_I2 = new MenuItem("打开");
????? ??? ButtonListener bL = new ButtonListener();
????? ??? mn1_I2.addActionListener(bL);
????? ??? mn1.add(mn1_I2);
????? ??? mB.add(mn1);
?????????? return mB;
????? }
????? public void showUI(){
?????????? this.setTitle("BMP打开器");
?????????? this.setSize(1024,768);
?????????? FlowLayout fl = new FlowLayout();
?????????? this.setLayout(fl);
?????????? MenuBar mB = this.creatMenuBar();
?????????? this.setMenuBar(mB);
?????????? this.setResizable(false);
?????????? this.setDefaultCloseOperation(3);
?????????? this.getContentPane().setBackground(Color.WHITE);
?????????? this.setVisible(true);
?????????? g = this.getGraphics();
?????????? g.setFont(new Font("黑体",12,48));
?????????? g.setColor(Color.red);
?????????? g.drawString("欢迎使用", this.getHeight()/2-100,this.getWidth()/2);
????? }
????? public void paint(){
?????????? super.paint(g);
?????????? g.drawString("欢迎使用", this.getHeight()/2-100,this.getWidth()/2);
????? }
??? public static void main(String args[]){
??? BMPopener bOpPopener = new BMPopener();
??? bOpPopener.showUI();
??? }
}
?
package text;
?
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
?
import javax.swing.JFileChooser;
?
public class ButtonListener implements ActionListener{
?
????? JFileChooser fileChooser = new JFileChooser();
????? File file;
????? @Override
????? public void actionPerformed(ActionEvent e) {
?????????? // TODO Auto-generated method stub
?????????? fileChooser.showOpenDialog(null);
?????????? file= fileChooser.getSelectedFile();
?????????? String path = file.getAbsolutePath();
?????????? System.out.print(path);
?????????? JiemaBMP jBmp = new JiemaBMP(path);
?????????? jBmp.showJiema();
????? }
}
?
?
package text;
?
import java.awt.Color;
import java.awt.Graphics;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.IOException;
?
import javax.swing.JFrame;
?
public class JiemaBMP extends JFrame{
?
????? private String pathString;
????? private Graphics g;
????? private UserColor[][] userColors;
????? private int unith = 23;
????? private UserColor[] userTiaoseban;
????? public? JiemaBMP(String path) {
?????????? this.pathString =path;
????? }
????? public void showJiema() {
?????????? // TODO Auto-generated method stub
?????????? try{
???????????????? FileInputStream fis = new FileInputStream(pathString);
???????????????? DataInputStream dis = new DataInputStream(fis);
???????????????? if(dis.read()!= 'B'){
????????????????????? throw new IOException("Not a .BMP file");????
???????????????? }
???????????????? if(dis.read()!='M'){
????????????????????? throw new IOException("Not a .BMP file");
???????????????? }
???????????????? //得到总大小
???????????????? int fileSize = readInt(dis);
???????????????? System.out.println("文件大小:"+fileSize);
???????????????? System.out.println(readUsignedShort(dis));
???????????????? System.out.println(readUsignedShort(dis));
???????????????? //读取偏移量
???????????????? int bitmapOffset = readInt(dis);
???????????????? //读取当前结构体的大小
???????????????? System.out.println("bitmapOffset="+bitmapOffset);
???????????????? int bitmapInfoSize = readInt(dis);
???????????????? System.out.println("bitmapInfoSize"+bitmapInfoSize);
???????????????? //读取宽高
???????????????? int width = readInt(dis);
???????????????? int height = readInt(dis);
???????????????? System.out.println("width:"+width+"height:"+height);
???????????????? //读Plants总是1
???????????????? System.out.println(readUsignedShort(dis));
???????????????? //读位数
???????????????? int bitCount = readUsignedShort(dis);
???????????????? System.out.println("bitCount"+bitCount);
???????????????? //读取压缩方式
???????????????? int compressionType = readInt(dis);
???????????????? System.out.println("CompressionType:"+compressionType);
???????????????? //读取图片大小
?????????? ??? int imageSize = readInt(dis);
?????????? ??? //读分辨率
?????????? ??? readInt(dis);
?????????? ??? readInt(dis);
????? ????? ??? //读位图使用的颜色数
?????????? ??? int colorsUsed = readInt(dis);
?????????? ??? int colorsImportant = readInt(dis);
?????????? ??? System.out.println("[colorused]= "+colorsUsed);
?????????? ??? //? Read the pixels from the stream based on the compression type
?????????? ??? if(compressionType ==0){
?????????? ??? ????? if(bitCount == 24||bitCount == 4){
?????????? ??? ?????????? readRGB24(width, height, dis);
?????????? ??? ????? }
?????????? ??? ????? if(bitCount == 8||bitCount == 1){
?????????? ??? ?????????? readRGB8(width, height, dis);
?????????? ??? ????? }
//???????? ??? ????? if(bitCount == 4){
//???????? ??? ?????????? readRGB4(width, height, dis);
//???????? ??? ????? }
//???????? ??? ????? if(bitCount == 1){
//???????? ??? ?????????? readRGB1(width, height, dis);
//???????? ??? ????? }
?????????? ??? }
?????????? ???
?????????? }catch(Exception e){
????????????????
?????????? }
????? }
????? public void readRGB1(int width,int height,DataInputStream dis) throws IOException{
?????
????? }
????? public void readRGB4(int width,int height,DataInputStream dis) throws IOException{
??????????
????? }
????? public void readRGB8(int width,int height,DataInputStream dis)throws IOException{
?????????? this.setTitle(pathString);
?????????? //设置一个大小
?????????? this.setSize(width,height+unith);
?????????? this.setResizable(false);
?????????? this.setVisible(true);
?????????? g = this.getGraphics();
?????????? userTiaoseban = new UserColor[256];
?????????? userColors = new UserColor[width][height];
?????????? for(int i = 0;i<256;i++){
???????????????? int blue = dis.read();
???????????????? int green = dis.read();
???????????????? int red = dis.read();
???????????????? dis.read();
???????????????? userTiaoseban[i] = new UserColor(red, green, blue);
???????????????? System.out.println("加了="+i);
?????????? }
?????????? //System.out.println(userTiaoseban[217].red+userTiaoseban[217].green);
?????????? //按行读取如果H,W为正则到这来
?????????? for(int h = height-1;h>=0;h--){
???????????????? for(int w = 0;w<width;w++){
????? ??? //? Read in the red, green, and blue components
???????????????? int num = dis.read();
???????????????? ?
???????????????? ?? userColors[w][h] = userTiaoseban[num];
???????????????? ?? if((userColors[w][h].red!=255)||(userColors[w][h].green!=255)||(userColors[w][h].blue!= 255)){
????????????????????? ?? g.setColor(new Color(userColors[w][h].red,userColors[w][h].green,userColors[w][h].blue));
????????????????????? ?? g.fillOval(w, h+unith, 1, 1);
????????????????????? ??
???????????????? ?? }
???????????????? }
?????????? }
????? }
????? public void readRGB24(int width,int height,DataInputStream dis)throws IOException{
?????????? this.setTitle(pathString);
?????????? //设置一个大小
?????????? this.setSize(width,height+unith);
?????????? this.setResizable(false);
?????????? this.setVisible(true);
?????????? g = this.getGraphics();
?????????? userColors = new UserColor[width][height];
?????????? //System.out.println(userTiaoseban[217].red+userTiaoseban[217].green);
?????????? //按行读取如果H,W为正则到这来
?????????? for(int h = height-1;h>=0;h--){
???????????????? for(int w = 0;w<width;w++){
????? ??? //? Read in the red, green, and blue components
????????????????????? int blue = dis.read();
????????????????????? int green = dis.read();
????????????????????? int red = dis.read();
????????????????????? userColors[w][h] = new UserColor(red, green, blue);
????? ?????????? ?? if((userColors[w][h].red!=255)||(userColors[w][h].green!=255)||(userColors[w][h].blue!= 255)){
????????????????????? ?? g.setColor(new Color(userColors[w][h].red,userColors[w][h].green,userColors[w][h].blue));
????????????????????? ?? g.fillOval(w, h+unith, 1, 1);
????????????????????? ??
???????????????? ?? }
???????????????? }
????? ????? }
????? }
????? //构造一个整数的方法
????? public final int readInt(DataInputStream dis) throws IOException{
?????????? int ch1 = dis.read();
?????????? int ch2 = dis.read();
?????????? int ch3 = dis.read();
?????????? int ch4 = dis.read();
?????????? if((ch1|ch2|ch3|ch4)<0)
???????????????? throw new IOException();
?????????? return ((ch4<<24)+(ch3<<16)+(ch2<<8)+(ch1<<0));
????? }
??? //构造一个读2个字节整数的方法
????? public final int readUsignedShort(DataInputStream dis) throws IOException{
?????????? int ch1 = dis.read();
?????????? int ch2 = dis.read();
?????????? if((ch1|ch2)<0)
???????????????? throw new EOFException();
?????????? return(ch2<<8)+(ch1<<0);
????? }
????? public final int disHH(int num){
?????????? return (num&8)>>3;
????? }
????? public final int disHL(int num){
?????????? return (num&4)>>2;
????? }
????? public final int disLH(int num){
?????????? return (num&2)>>1;
????? }
????? public final int disLL(int num){
?????????? return (num&1);
????? }
??? /*
???? * 定义一个将高位输出的方法(针对RGB4)
???? */
????? public final int disH(int num){
?????????? return num>>4;
????? }
??? /*
???? * 定义一个将低位输出的方法(针对RGB4)
???? */
????? public final int disL(int num){
?????????? int num1 = 15;
?????????? return num&num1;
????? }
????? //重写重绘方法
????? public void paint(Graphics g){
?????????? super.paint(g);
?????????? for(int h = userColors[0].length-1;h>=0;h--){
???????????????? for(int w=0;w<userColors.length;w++){
????????????????????? if((userColors[w][h].red!=255)||(userColors[w][h].green!=255)||userColors[w][h].blue!=255){
??????????????????????????? g.setColor(new Color(userColors[w][h].red,userColors[w][h].green,userColors[w][h].blue));
??????????????????????????? g.fillOval(w, h+unith, 1, 1);
????????????????????? }
???????????????? }
?????????? }
????? }
}
?
package text;
?
publicclass UserColor {
?
?? publicintred;
?? publicintgreen;
?? publicintblue;
?? public UserColor(int red,int green,int blue){
???? this.red = red;
???? this.green = green;
???? this.blue = blue;
?? }
}
?