(文件数据的写入顺序要与读取顺序一致)
一.用自定义的队列保存图像与读取图像
由于在画图板上每画一种图形,就相当于在自定义的队列中装入此图形,那么在保存画图板图形时,就只需从自定义队列中获取每个图形的基本属性,如颜、点的坐标,图形的种类,然后将这些基本信息写入文件,存储到硬盘。不过先要写入图形的个数,方便打开时获得队列的长度。
打开保存的图形时,只需要定义一个自定义队列,在从保存的文件中读取图形的中种类,根据种类不同,分别读取图形的属性,颜色、坐标,创建具有这些属性的图形队形,装入到队列中去。然后再根据队列中的装入的图形,通过draw方法画出来。
保存:
①文件头信息:int(表示队列中图形的个数)
②:文件数据信息:1)直线:int(表type)+int(表color值)+int+int+int+int
2)矩形:int(表type)+int(表color值)+int+int+int+int
3)椭圆:int(表type)+int(表color值)+int+int+int+int
4)多边形;int(表type)+int(表color值)+int[]
/**
* 文件的保存
*
* @param shapes
* :要保存的图形队列
* @param path
* :保存的路径
* @return:是否保存成功
*/
public boolean savefile(QueueImp<Shape> shapes, String path) {
boolean isb = false;
try {
// 根据路径创建一个文件输出流对象
java.io.FileOutputStream fos = new java.io.FileOutputStream(path);
// 将文件流包装为基本类型数据流
java.io.DataOutputStream dos = new java.io.DataOutputStream(fos);
// 先写入队列中图形的个数
dos.writeInt(shapes.size());
// 读取队列
for (int i = 0; i < shapes.size(); i++) {
// 取出一个形状
Shape sh = shapes.get(i);
// 得到形状的类型
byte type = sh.type;
// 写入形状类型
dos.writeByte(type);
if (type == 0) { // 如果是直线
// 将形状强制转化为直线
Line line = (Line) sh;
// 得到直线的属性
int x1 = line.x1;
int y1 = line.y1;
int x2 = line.x2;
int y2 = line.y2;
int rgb = line.color.getRGB();
// 写入属性
dos.writeInt(rgb);
dos.writeInt(x1);
dos.writeInt(y1);
dos.writeInt(x2);
dos.writeInt(y2);
} else if (type == 1) { // 如果是矩形
// 将形状强制转化为矩形
Rect rect = (Rect) sh;
// 得到矩形的属性
int x1 = rect.x1;
int y1 = rect.y1;
int x2 = rect.x2;
int y2 = rect.y2;
int rgb = rect.color.getRGB();
// 写入属性
dos.writeInt(rgb);
dos.writeInt(x1);
dos.writeInt(y1);
dos.writeInt(x2);
dos.writeInt(y2);
} else if (type == 2) { // 如果是椭圆
// 将形状强制转化为椭圆
Oval oval = (Oval) sh;
// 得到椭圆的属性
int x1 = oval.x1;
int y1 = oval.y1;
int x2 = oval.x2;
int y2 = oval.y2;
int rgb = oval.color.getRGB();
// 写入属性
dos.writeInt(rgb);
dos.writeInt(x1);
dos.writeInt(y1);
dos.writeInt(x2);
dos.writeInt(y2);
} else if (type == 3) { // 如果是多边形
// 将形状强制转化为多边形
Polygon polygon = (Polygon) sh;
// 得到颜色
int rgb = polygon.color.getRGB();
// 写入颜色
dos.writeInt(rgb);
// 创建一个队列,用来得到多边形的属性
QueueImp<Integer> gp = polygon.point;
// 写入队列的长度
dos.writeInt(gp.size());
// 遍历队列,写入属性
for (int j = 0; j < gp.size(); j++) {
int p = gp.get(j);
dos.writeInt(p);
}
}
isb = true;
}
// 强制刷新
dos.flush();
// 关闭流
fos.close();
} catch (Exception ef) {
ef.printStackTrace();
}
return isb;
}
读取:按照写入文件的顺序,将数据包装成形状一个个读取出来,保存到队列中去
/**
* 读取文件
*
* @param path
* :所读取的文件的路径
* @return:图形数组
*/
public QueueImp<Shape> openfile(String path) {
// 创建一个用来保存图形的队列
QueueImp<Shape> shapes = new QueueImp<Shape>();
try {
// 根据路径创建输入流对象
java.io.FileInputStream fis = new java.io.FileInputStream(path);
// 将输入流包装成基本类型的数据流
java.io.DataInputStream dis = new java.io.DataInputStream(fis);
// 读取一个int,表示图形队列中图形的个数
int len = dis.readInt();
// 循环读取每一个图形信息
for (int i = 0; i < len; i++) {
// 读取图形类型
byte type = dis.readByte();
if (type == 0) { // 如果是直线
// 读取直线的属性
int rgb = dis.readInt();
int x1 = dis.readInt();
int y1 = dis.readInt();
int x2 = dis.readInt();
int y2 = dis.readInt();
Color color = new Color(rgb);
// 创建一个直线对象
Line line = new Line(x1, y1, x2, y2, color);
// 将直线装入队列
shapes.add(line);
} else if (type == 1) { // 如果是矩形
// 读取矩形的属性
int rgb = dis.readInt();
int x1 = dis.readInt();
int y1 = dis.readInt();
int x2 = dis.readInt();
int y2 = dis.readInt();
Color color = new Color(rgb);
// 创建一个矩形对象
Rect rect = new Rect(x1, y1, x2, y2, color);
// 将矩形装入队列
shapes.add(rect);
} else if (type == 2) { // 如果是椭圆
// 读取椭圆的属性
int rgb = dis.readInt();
int x1 = dis.readInt();
int y1 = dis.readInt();
int x2 = dis.readInt();
int y2 = dis.readInt();
Color color = new Color(rgb);
// 创建一个椭圆对象
Oval oval = new Oval(x1, y1, x2, y2, color);
// 将椭圆装入队列
shapes.add(oval);
} else if (type == 3) {
// 读取多边形的颜色
int rgb = dis.readInt();
// 读取队列的长度
int size = dis.readInt();
// 创建队列,得到数组的内容
QueueImp<Integer> qi = new QueueImp<Integer>();
// 遍历数组,写入多边形的属性
for (int j = 0; j < size; j++) {
int s = dis.readInt();
qi.add(s);
}
Color color = new Color(rgb);
// 创建一个多边形对象
Polygon polygon = new Polygon(qi, color);
// 将多边形装入队列
shapes.add(polygon);
}
}
} catch (Exception ef) {
ef.printStackTrace();
}
return shapes;
}
// 读取图像
QueueImp<Shape> getshapes = fu.openfile("D:\\jm.hu");
// 将getshapes中的图形装入到shapes中
for (int i = 0; i < getshapes.size(); i++) {
shapes.add(getshapes.get(i));
}
// 将队列中的形状取出来绘制
for (int i = 0; i < shapes.size(); i++) {
// 根据下标取出一个形状对象
Shape sh = shapes.get(i);
// 绘制
sh.draw(g);
}
由于每种格式的文件都有固定的格式,而文件的后缀只是方便系统快速的找到打开此类文件的程序,故文件的类型不是由文件的后缀名决定的,而是文件固定的写入格式。我们用队列保存的这个文件格式,故也只能由我们自己的画图板才能打开。
二.仿BMP格式保存读取(以相位点的形式保存读取)
画板的画布,是由一个个相位点组成的,如果在画布上画了图形,那么一定会有一些相位点的颜色发生了改变,那么只要保存每一个相位点的颜色值就可以了。定义一个二维数组来实现,读取时,在根据二维数组的信息,把每个相位点画出来。
抓取一张图片,而图片的大小由画布的大小决定,比如我们在JPanel上加的画布,则图片的大小就是JPanel的大小,再将图片每一个相位点的颜色值保存到数组中去。
/**
* 山寨BMP保存
*
* @author
*
*/
public class Save4Bit {
static int width;
static int height;
static int[][] colors;// 用来保存每一个像素点颜色的数组
static java.awt.Robot robot;
public static void savePic(JPanel panel) {
try {
robot = new java.awt.Robot();
} catch (Exception ef) {
ef.printStackTrace();
}
width = panel.getWidth();
height = panel.getHeight();
colors = new int[height][width];
// 得到panel左上角的点相对于屏幕的坐标
Point p = panel.getLocationOnScreen();
java.awt.Rectangle rect = new java.awt.Rectangle(p.x, p.y,
panel.getWidth(), panel.getHeight());
// 从屏幕上抓取一张图片
java.awt.image.BufferedImage img = robot.createScreenCapture(rect);
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
colors[i][j] = img.getRGB(j, i); //数组行列分别与画板的y坐标和x坐标对应
}
}
}
文件头:画面的大小 int(高)+int(宽)
文件数据:画面的每个点的颜色值 int
/* 图像的保存
* @author
*
*/
public class FileUtil {
/**
* 保存成文件
*
* @param path
* :保存路径
*/
public void saveFile(String path, int[][] color, JPanel jp) {
try {
// 创建一个文件输出流
java.io.FileOutputStream fos = new FileOutputStream(path);
// 将文件输出输出到缓冲流
java.io.BufferedOutputStream bos = new BufferedOutputStream(fos);
// 将缓冲流包装成Data的数据流
java.io.DataOutputStream dos = new java.io.DataOutputStream(bos);
// 首先保存画面的大小
dos.writeInt(jp.getHeight());
dos.writeInt(jp.getWidth());
// 遍历列队
for (int i = 0; i < jp.getHeight(); i++) {
for (int j = 0; j < jp.getWidth(); j++) {
dos.writeInt(color[i][j]);
}
}
dos.flush(); //强制刷新
fos.close();
} catch (Exception ef) {
ef.printStackTrace();
}
}
/**
* 打开文件
*
* @param path
* @return
*/
public int[][] openFile(String path) {
//创建一个二维数组,用来装入位点
int[][] color = null;
try {
// 创建文件输入流
java.io.FileInputStream fit = new FileInputStream(path);
// 将文件输入流输入缓冲流
java.io.BufferedInputStream bis = new BufferedInputStream(fit);
// 把缓冲流打包成Data输入流
java.io.DataInputStream dos = new DataInputStream(bis);
// 先读取大小
int width = dos.readInt();
int height = dos.readInt();
//创建一个二维数组,用来保存相位点的值
color=new int[height][width];
// 把文件中的数据加入队列中
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
color[i][j] = dos.readInt();
}
}
} catch (Exception ef) {
ef.printStackTrace();
}
return color;
}
重绘,从二维数组中读取颜色值,再画点
public void paint(Graphics g) {
// 调用父类的方法来绘制窗体
super.paint(g);
if (Save4Bit.colors != null) {
for (int i = 0; i < Save4Bit.colors.length; i++) {
for (int j = 0; j < Save4Bit.colors[i].length; j++) {
int rgb = Save4Bit.colors[i][j];
if (panel.getBackground().getRGB() != rgb) {
Color color = new Color(rgb);
g.setColor(color);
g.drawLine(i, j, i, j);
}
}
}
}
}
通过两种方法的保存与读取,不难看出第一种方法写入文件和读取出来的过程都比较繁琐,而好处则是保存的文件在所画的图形个数不多的情况下,占用空间较少;第二种方法是每个每个相位点的保存,不难看出,无论什么情况下,文件的大小都是跟画板的大小相关的,好处是保存与读取的过程简单,但在画了很多图形情况下,画布的重载速度会很慢。
- 大小: 45.7 KB
分享到:
相关推荐
用自制画板打开和保存BMP格式文件。画板代码如下
火山安卓高级画板实现画板开发源码
这是我初学qt编写的简易画板程序,程序结构和算法不算优秀,请多多指教
VC++课程设计,windows简单画板,可以画直线、矩形、椭圆、改颜色、线条;清除,保存打开功能。
易语言简易画板源码,简易画板,公用接口_寻找文件扩展,公用接口_复制目录,公用接口_数组到表格,公用接口_生成编号,公用接口_生成密码,公用接口_时间到文本,公用接口_数据到十六进制文本,公用接口_十六进制文本到数据,...
易语言取画板图片文件源码.zip
使用Android的自定义View写的Android画板程序,主要使用DrawPath()实现,需要的童鞋可以下来看看。
用VC开发工具编写的MFC简易画板,可以实现类似与windows自带画板的一些功能
提供源代码 直接可运行 提供了比较全面的画板功能
使用python做的一个简易画板,能够实现画点、画直线、画多边形、画椭圆等功能,其中包含了对Tkinter的操作以及对于GUI的操作,希望对python初学者能够有所帮助
一个简易画板的实现 有简单的画图,画图形,改颜色功能
一个普通的JAVA画图还能够创建文件用来积存程序,运用到几个有关的包,有关如何处理的方法
用qt做的简易画板,能够实现图形,颜色,线宽选择。用鼠标移动操作。
简单画板(源代码)有有橡皮筋功能,文本输入功能,文件输入保存功能,调色功能,取色功能等等 用MFC实现
用c#语言编写的简易画板程序,可以实现简易的绘画功能,可以绘制直线矩形…… 有参考一下别人的代码
本程序为简易画板程序,主要解决画板的一些基本问题,并保持绘画的流畅。希望对新人有所帮助
这是用C# GDI实现的简易画板Demo,对应博文http://blog.csdn.net/luols/article/details/7171668,有需要的朋友可以下载样例试用
matlab简易画板GUI程序 可选择点、线、矩形、椭圆进行画图 可以选择颜色、线条粗细 有橡皮擦、清除按钮 只有添加文本框的功能还没有实现~
c#简单画板程序 有c#代码编写的简单画板程序 代码类资源
java画板程序 源代码,自己写的作业,给大家共享一下了,^_^。代码共享,随意修改了。呵呵。支持文件的打开和保存操作,默认的文件格式为jdf,压缩包中firstDraw.jdf为我画的第一幅画,可以用来打开测试。。