Java利用文件读写对位图文件进行重绘

这篇博客主要介绍用Java读一个位图文件,并把它打印出来。

一、灵魂画手绘制位图文件

在这里插入图片描述
在这里插入图片描述

二、使用UltraEdit对文件进行分析

在这里插入图片描述
在这里关于位图文件的数据不详细分析,有问题的可以参考博客:
https://blog.csdn.net/aidem_brown/article/details/80500637
我们只需要注意文件中,关于这个图片的宽和高的信息是在第二行,如图:
在这里插入图片描述
之后,关于位图的颜色信息是在第四行第七个开始往后
在这里插入图片描述
最后还有一个要注意的地方,在每一行的结尾位置,行的宽度*3%4如果不为0,需要补00,使其整除
在这里插入图片描述

三、代码

代码分几个部分:

1、消除高、宽前面的内容

// 消去第一行
			for (int i = 0; i < 4; i++) {
				int c = dis.readInt();
				System.out.println(c);
			}
			// 去除第二行前两个
			dis.read();
			dis.read();

2、获取宽、高

// 算出宽度,参考 readInt()源代码中的方法
			int ch1 = dis.read();
			int ch2 = dis.read();
			int ch3 = dis.read();
			int ch4 = dis.read();
			int width = ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
			System.out.println(width);
			// 算高
			ch1 = dis.read();
			ch2 = dis.read();
			ch3 = dis.read();
			ch4 = dis.read();
			int height = ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
			System.out.println(height);

3、出去高后面到颜色之前的没用的内容

// 消去下面的无用字节
			for (int i = 0; i < 7; i++) {
				dis.readInt();
			}

4、创建画布,用于重画图片

//创建画布
			JFrame jf = new JFrame();
			jf.setSize(width, height);
			jf.setLocationRelativeTo(null);
			jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			jf.setVisible(true);
			Graphics Gr =jf.getGraphics();

5、二重循环,涂色

for (int j = height; j > 0; j--) {
				for (int i = 0; i < width; i++) {
					int b = dis.read();
					int g = dis.read();
					int r = dis.read();
					Gr.setColor(new Color(r,g,b));
					Gr.drawLine(i+1,j+1,i+1,j+1);
				}
				int n = (width * 3) % 4;
				if (n != 0) {
					for (int i = 0; i < 4 - n; i++) {
						dis.read();
					}
				}
			}

完整代码:

package 读位图;

import java.awt.Color;
import java.awt.Graphics;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;

import javax.swing.JFrame;

public class BMP {
	public void readMap(String filename) {
		try {
			FileInputStream fis = new FileInputStream(filename);
			java.io.BufferedInputStream bis = new BufferedInputStream(fis);
			DataInputStream dis = new DataInputStream(bis);
			// 消去第一行
			for (int i = 0; i < 4; i++) {
				int c = dis.readInt();
				System.out.println(c);
			}
			// 去除第二行前两个
			dis.read();
			dis.read();
			// 算出宽度,参考 readInt()源代码中的方法
			int ch1 = dis.read();
			int ch2 = dis.read();
			int ch3 = dis.read();
			int ch4 = dis.read();
			int width = ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
			System.out.println(width);
			// 算高
			ch1 = dis.read();
			ch2 = dis.read();
			ch3 = dis.read();
			ch4 = dis.read();
			int height = ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
			System.out.println(height);
			// 消去下面的无用字节
			for (int i = 0; i < 7; i++) {
				dis.readInt();
			}
			//创建画布
			JFrame jf = new JFrame();
			jf.setSize(width, height);
			jf.setLocationRelativeTo(null);
			jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			jf.setVisible(true);
			
			Graphics Gr =jf.getGraphics();
						
			for (int j = height; j > 0; j--) {
				for (int i = 0; i < width; i++) {
					int b = dis.read();
					int g = dis.read();
					int r = dis.read();
					Gr.setColor(new Color(r,g,b));
					Gr.drawLine(i+1,j+1,i+1,j+1);
				}
				int n = (width * 3) % 4;
				if (n != 0) {
					for (int i = 0; i < 4 - n; i++) {
						dis.read();
					}
				}
			}
			
			dis.close();
			bis.close();
			fis.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		BMP bmp = new BMP();
		bmp.readMap("C:\\Users\\董润泽\\Desktop\\1.bmp");
	}
}

输出效果

在这里插入图片描述

(点个赞再走呗O(∩_∩)O)

发布了45 篇原创文章 · 获赞 14 · 访问量 2474

猜你喜欢

转载自blog.csdn.net/qq_44357371/article/details/103220943