读书人

玩CF的时分官网用鼠标滑动控制图片切换

发布时间: 2012-12-19 14:13:14 作者: rapoo

玩CF的时候官网用鼠标滑动控制图片切换的东西

???????玩CF的时分官网用鼠标滑动控制图片切换的东西

?

????????以前玩CF的时候,官方网站有个网页鼠标进入左右移动两张图片可以进行切换,看起来很好看。

???? 数字图象处理课上需要将BMP图像进行处理,还要用C++,于是借此机会专门了解了BMP,了解下图片不同于文本的2进制文件,了解下C++。

????? 之后是一个一个字节一个字节的测试了BMP图片的信息,做了一个可以切换图片的东西完了一下。

???? 关于BMP自己的测试理解是:前54字节是位图信息即文件的一些信息,之后如果图像深度是少于24位的有调色板也称颜色查询器,之后是存放索引的一个数组,对于24位的是没有调色板这一项,直接用3个字节保存每个像素的B、G、R,的数组。有个文档很专业分享下。

?

测试代码是:

/** * 14个字节大小的:位图文件头 */System.out.println("格式是:  " + (char) dis.readByte());System.out.println("格式是(共2字节):  " + (char) dis.readByte());// 此处可以借助windows 的计算器实现逆序的转换System.out.println("文件大小4字节---第一个:  " + dis.readByte());System.out.println("文件大小4字节---第二个 : " + dis.readByte());System.out.println("文件大小4字节---第三个 : " + dis.readByte());System.out.println("文件大小4字节---第四个:  " + dis.readByte());System.out.println("位图文件头 --文件大小逆序后转换成了:      525430");System.out.println("位图文件头 --文件保留大小: " + dis.readInt());System.out.println("文件偏移4字节---第一个:  " + dis.readByte());System.out.println("文件偏移4字节---第二个 : " + dis.readByte());System.out.println("文件偏移4字节---第三个 : " + dis.readByte());System.out.println("文件偏移4字节---第四个:  " + dis.readByte());System.out.println("位图文件头 --文件偏移逆序后转换成了:      118字节");// 16色调色板是64字节+文件头14+位图信息头40=118/** * 40字节的位图信息头 */System.out.println("位图信息头之大小4字节---第一个:  " + dis.readByte());System.out.println("位图信息头之大小4字节---第二个 : " + dis.readByte());System.out.println("位图信息头之大小4字节---第三个 : " + dis.readByte());System.out.println("位图信息头之大小4字节---第四个:  " + dis.readByte());System.out.println("位图信息头--大小逆序后转换成了:            40字节");System.out.println("位图信息头之位图宽度4字节---第一个:  " + dis.readByte());System.out.println("位图信息头之位图宽度4字节---第二个:  " + dis.readByte());System.out.println("位图信息头之位图宽度4字节---第三个:  " + dis.readByte());System.out.println("位图信息头之位图宽度4字节---第四个:  " + dis.readByte());System.out.println("位图信息头--宽度逆序后转换成了:            1366字节");System.out.println("位图信息头之位图高度4字节---第一个:  " + dis.readByte());System.out.println("位图信息头之位图高度4字节---第二个:  " + dis.readByte());System.out.println("位图信息头之位图高度4字节---第三个:  " + dis.readByte());System.out.println("位图信息头之位图高度4字节---第四个:  " + dis.readByte());System.out.println("位图信息头--高度逆序后转换成了:            768字节");System.out.println("位图信息头--位面数2字节   --- 第一个:" + dis.readByte());System.out.println("位图信息头--位面数2字 节 --- 第二个:" + dis.readByte());System.out.println("位图信息头--位面数逆序后转换成了数值是:           1");System.out.println("位图信息头--图像深度2字节:---第一个:" + dis.readByte());System.out.println("位图信息头--图像深度2字节:---第二个:" + dis.readByte());System.out.println("位图信息头--图像深度逆序后准换成的值是:           4");System.out.println("位图信息头--压缩编码4字节:---第一个" + dis.readByte());System.out.println("位图信息头--压缩编码4字节:---第二个" + dis.readByte());System.out.println("位图信息头--压缩编码4字节:---第三个" + dis.readByte());System.out.println("位图信息头--压缩编码4字节:---第四个" + dis.readByte());System.out.println("4个全是0  表示是:-------无压缩");System.out.println("位图信息头之位图数据大小4字节---第一个:  " + dis.readByte());System.out.println("位图信息头之位图数据大小4字节---第二个:  " + dis.readByte());System.out.println("位图信息头之位图数据大小4字节---第三个:  " + dis.readByte());System.out.println("位图信息头之位图数据大小4字节---第四个:  " + dis.readByte());System.out.println("位图信息头之位图数据 逆序转换数值是 525312+位图文件头+位图信息头+彩色表=总的大小");System.out.println("位图信息头之水平分辨率4字节---第一个:  " + dis.readByte());System.out.println("位图信息头之水平分辨率4字节---第二个:  " + dis.readByte());System.out.println("位图信息头之水平分辨率4字节---第三个:  " + dis.readByte());System.out.println("位图信息头之水平分辨率4字节---第四个:  " + dis.readByte());System.out.println("位图信息头之水平分辨率转换成最后的数值是:  4个0 ");System.out.println("位图信息头之垂直分辨率4字节---第一个:  " + dis.readByte());System.out.println("位图信息头之垂直分辨率4字节---第二个:  " + dis.readByte());System.out.println("位图信息头之垂直分辨率4字节---第三个:  " + dis.readByte());System.out.println("位图信息头之垂直分辨率4字节---第四个:  " + dis.readByte());System.out.println("位图信息头之垂直分辨率转换成最后的数值是:4个0   ");System.out.println("位图信息头之位图使用的颜色数4字节---第一个:  " + dis.readByte());System.out.println("位图信息头之位图使用的颜色数4字节---第二个:  " + dis.readByte());System.out.println("位图信息头之位图使用的颜色数4字节---第三个:  " + dis.readByte());System.out.println("位图信息头之位图使用的颜色数4字节---第四个:  " + dis.readByte());System.out.println("位图信息头之位图使用的颜色数  4个0");System.out.println("位图信息头之位图使用的重要颜色数4字节---第一个:  " + dis.readByte());System.out.println("位图信息头之位图使用的重要颜色数4字节---第二个:  " + dis.readByte());System.out.println("位图信息头之位图使用的重要颜色数4字节---第三个:  " + dis.readByte());System.out.println("位图信息头之位图使用的重要颜色数4字节---第四个:  " + dis.readByte());System.out.println("位图信息头之位图使用的重要颜色数4个0  表示彼此都很重要");

?

?

?

上面是24位前54个字节的信息测试,有一点是:文件大小是4个字节表示的,假如是int 1,图像中存放数据是00000001 00000000 00000000 000000000 以字节为单位逆序排放。

?

下面是深度为24位的BMP图片切换代码:

?

package com.wlh.BMPPhoto;import java.awt.Color;import java.awt.Graphics;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.event.MouseWheelEvent;import java.io.*;import javax.swing.*;public class BMPPhoto_1_24 extends JFrame {int width = 1366;int height = 768;// 定义rgb数组int[][] R=new int[height][width];int[][] G=new int[height][width];int[][] B=new int[height][width];int[][] R1=new int[height][width];int[][] G1=new int[height][width];int[][] B1=new int[height][width];int count = 0;int count1=0;//表示是否读取文件完毕  可用于paint的时候的判断boolean state=false;private Graphics gra;    int myTest_X=1366; // 构造函数public BMPPhoto_1_24() {this.setTitle("BMP测试");this.setSize(1366, 760);this.setVisible(true);this.setAlwaysOnTop(true);this.setDefaultCloseOperation(3);gra = this.getGraphics();}public static void main(String args[]) {BMPPhoto_1_24 bmp = new BMPPhoto_1_24();try {bmp.readBMP();} catch (IOException e) {e.printStackTrace();}}// 读取BMP图像的方法public void readBMP() throws IOException {InputStream in = new FileInputStream("F:\\1.bmp");DataInputStream dis = new DataInputStream(in);InputStream in_1 = new FileInputStream("F:\\22.bmp");DataInputStream dis_1 = new DataInputStream(in_1);/** * 14个字节大小的:位图文件头 */System.out.println("格式是:  " + (char) dis.readByte());System.out.println("格式是(共2字节):  " + (char) dis.readByte());// 此处可以借助windows 的计算器实现逆序的转换System.out.println("文件大小4字节---第一个:  " + dis.readByte());System.out.println("文件大小4字节---第二个 : " + dis.readByte());System.out.println("文件大小4字节---第三个 : " + dis.readByte());System.out.println("文件大小4字节---第四个:  " + dis.readByte());System.out.println("位图文件头 --文件大小逆序后转换成了:      525430");System.out.println("位图文件头 --文件保留大小: " + dis.readInt());System.out.println("文件偏移4字节---第一个:  " + dis.readByte());System.out.println("文件偏移4字节---第二个 : " + dis.readByte());System.out.println("文件偏移4字节---第三个 : " + dis.readByte());System.out.println("文件偏移4字节---第四个:  " + dis.readByte());System.out.println("位图文件头 --文件偏移逆序后转换成了:      118字节");// 16色调色板是64字节+文件头14+位图信息头40=118/** * 40字节的位图信息头 */System.out.println("位图信息头之大小4字节---第一个:  " + dis.readByte());System.out.println("位图信息头之大小4字节---第二个 : " + dis.readByte());System.out.println("位图信息头之大小4字节---第三个 : " + dis.readByte());System.out.println("位图信息头之大小4字节---第四个:  " + dis.readByte());System.out.println("位图信息头--大小逆序后转换成了:            40字节");System.out.println("位图信息头之位图宽度4字节---第一个:  " + dis.readByte());System.out.println("位图信息头之位图宽度4字节---第二个:  " + dis.readByte());System.out.println("位图信息头之位图宽度4字节---第三个:  " + dis.readByte());System.out.println("位图信息头之位图宽度4字节---第四个:  " + dis.readByte());System.out.println("位图信息头--宽度逆序后转换成了:            1366字节");System.out.println("位图信息头之位图高度4字节---第一个:  " + dis.readByte());System.out.println("位图信息头之位图高度4字节---第二个:  " + dis.readByte());System.out.println("位图信息头之位图高度4字节---第三个:  " + dis.readByte());System.out.println("位图信息头之位图高度4字节---第四个:  " + dis.readByte());System.out.println("位图信息头--高度逆序后转换成了:            768字节");System.out.println("位图信息头--位面数2字节   --- 第一个:" + dis.readByte());System.out.println("位图信息头--位面数2字 节 --- 第二个:" + dis.readByte());System.out.println("位图信息头--位面数逆序后转换成了数值是:           1");System.out.println("位图信息头--图像深度2字节:---第一个:" + dis.readByte());System.out.println("位图信息头--图像深度2字节:---第二个:" + dis.readByte());System.out.println("位图信息头--图像深度逆序后准换成的值是:           4");System.out.println("位图信息头--压缩编码4字节:---第一个" + dis.readByte());System.out.println("位图信息头--压缩编码4字节:---第二个" + dis.readByte());System.out.println("位图信息头--压缩编码4字节:---第三个" + dis.readByte());System.out.println("位图信息头--压缩编码4字节:---第四个" + dis.readByte());System.out.println("4个全是0  表示是:-------无压缩");System.out.println("位图信息头之位图数据大小4字节---第一个:  " + dis.readByte());System.out.println("位图信息头之位图数据大小4字节---第二个:  " + dis.readByte());System.out.println("位图信息头之位图数据大小4字节---第三个:  " + dis.readByte());System.out.println("位图信息头之位图数据大小4字节---第四个:  " + dis.readByte());System.out.println("位图信息头之位图数据 逆序转换数值是 525312+位图文件头+位图信息头+彩色表=总的大小");System.out.println("位图信息头之水平分辨率4字节---第一个:  " + dis.readByte());System.out.println("位图信息头之水平分辨率4字节---第二个:  " + dis.readByte());System.out.println("位图信息头之水平分辨率4字节---第三个:  " + dis.readByte());System.out.println("位图信息头之水平分辨率4字节---第四个:  " + dis.readByte());System.out.println("位图信息头之水平分辨率转换成最后的数值是:  4个0 ");System.out.println("位图信息头之垂直分辨率4字节---第一个:  " + dis.readByte());System.out.println("位图信息头之垂直分辨率4字节---第二个:  " + dis.readByte());System.out.println("位图信息头之垂直分辨率4字节---第三个:  " + dis.readByte());System.out.println("位图信息头之垂直分辨率4字节---第四个:  " + dis.readByte());System.out.println("位图信息头之垂直分辨率转换成最后的数值是:4个0   ");System.out.println("位图信息头之位图使用的颜色数4字节---第一个:  " + dis.readByte());System.out.println("位图信息头之位图使用的颜色数4字节---第二个:  " + dis.readByte());System.out.println("位图信息头之位图使用的颜色数4字节---第三个:  " + dis.readByte());System.out.println("位图信息头之位图使用的颜色数4字节---第四个:  " + dis.readByte());System.out.println("位图信息头之位图使用的颜色数  4个0");System.out.println("位图信息头之位图使用的重要颜色数4字节---第一个:  " + dis.readByte());System.out.println("位图信息头之位图使用的重要颜色数4字节---第二个:  " + dis.readByte());System.out.println("位图信息头之位图使用的重要颜色数4字节---第三个:  " + dis.readByte());System.out.println("位图信息头之位图使用的重要颜色数4字节---第四个:  " + dis.readByte());System.out.println("位图信息头之位图使用的重要颜色数4个0  表示彼此都很重要");/** * 下面开始读取调色板 width=1366 的深度是24的bmp 需要行对齐 每行补上2个字节 */// 初始化颜色索引数组int b;int g;int r;for (int i = height - 1; i >= 0; i--) {for (int j = 0; j < width; j++) {count++;// 当达到1366 的整数倍的时候 跳过两个字节 ======专门为1366 分辨率设置的算法if (count % 1366 == 0) {dis.readByte();dis.readByte();}//读取RGBb = dis.readByte();g = dis.readByte();r = dis.readByte();if(b<0){b = 256 + b;}if(g<0){g= 256 + g;}if(r<0){r=256+r;}B[i][j]=b;G[i][j]=g;R[i][j]=r; //画到JFrame上this.gra.setColor(new Color(r, g, b));this.gra.drawLine(j, i, j, i);}}dis_1.skip(54);for (int i = height - 1; i >= 0; i--) {for (int j = 0; j < width; j++) {count1++;// 当达到1366 的整数倍的时候 跳过两个字节 ======专门为1366 分辨率设置的算法if (count1 % 1366 == 0) {dis_1.readByte();dis_1.readByte();}//读取RGBb = dis_1.readByte();g = dis_1.readByte();r = dis_1.readByte();if(b<0){b = 256 + b;}if(g<0){g= 256 + g;}if(r<0){r=256+r;}B1[i][j]=b;G1[i][j]=g;R1[i][j]=r; }}state=true;System.out.println("第二章初始化完毕......");this.addMouseMotionListener(new MouseAdapter(){public void mouseMoved(MouseEvent e){if(state){    int x=e.getX();    System.out.println("测试的X:="+x);    if(x<myTest_X){    for(int i=0;i<height;i++){    for(int j=x;j<myTest_X;j++){    gra.setColor(new Color(R1[i][j], G1[i][j], B1[i][j]));    gra.drawLine(j, i, j, i);    }    }    }else{    for(int i=0;i<height;i++){    for(int j=myTest_X;j<x;j++){    gra.setColor(new Color(R[i][j], G[i][j], B[i][j]));    gra.drawLine(j, i, j, i);    }    }    }        myTest_X=x;}}});}public void paint(Graphics g){if(state){for(int i=0;i<height;i++){for(int j=0;j<width;j++){gra.setColor(new Color(R[i][j], G[i][j], B[i][j]));gra.drawLine(j, i, j, i);}}}}}

?

???? 下面是深度为8位的,和24位不同的是需要先读取出文件的调色板信息,根据数组里的索引查看BGR:

package com.wlh.BMPPhoto;import javax.swing.*;import java.awt.*;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.io.*;public class BMPPhoto_1_256 extends JFrame {/** * 读取深度为8位的BMP指定图像 */// 定义256色的调色板BMPColor[] colorSelector_1 = new BMPColor[256];BMPColor[] colorSelector_2 = new BMPColor[256];// 定义一个存放索引数据的信息数组// 图片1int weith_1 = 1048;// 存放索引的数组的长度 不一定等于图片的宽度int height_1 = 468;// 存放索引的数组的高度=图片的高度int[][] data_1 = new int[height_1][weith_1];// 图片2int weith_2 = weith_1;int height_2 = height_1;int[][] data_2 = new int[height_2][weith_2];//定义一个状态是为了在paint在两张图片数据初始化完成后才能进行重绘boolean state = false;//画笔private Graphics G;//用来保存上次鼠标监听的位置private int myText_X=weith_1;public static void main(String[] args) {BMPPhoto_1_256 bmp = new BMPPhoto_1_256();}public BMPPhoto_1_256() {this.setTitle("BMP 之深度为8位测试");this.setAlwaysOnTop(true);this.setSize(1050, 470);this.setDefaultCloseOperation(3);this.setVisible(true);try {// 创建两个文件流对象InputStream in_1 = new FileInputStream("F:\\b1.bmp");DataInputStream dis_1 = new DataInputStream(in_1);/** * 读取第一个文件 */// 先跳过位图信息部分 直接读取调色板信息dis_1.skipBytes(54);for (int i = 0; i < 256; i++) {/** * 先初始化对象 */colorSelector_1[i] = new BMPColor();int b = dis_1.readByte();int g = dis_1.readByte();int r = dis_1.readByte();dis_1.readByte();if (g < 0) {//至于此处 DataInputStream的方法readByte 返回的是-128——127的值 要进行转换g += 256;colorSelector_1[i].g = g;} else {colorSelector_1[i].g = g;}if (r < 0) {r += 256;colorSelector_1[i].r = r;} else {colorSelector_1[i].r = r;}if (b < 0) {b += 256;colorSelector_1[i].b = b;} else {colorSelector_1[i].b = b;}}// 数组的索引初始化for (int i = data_1.length - 1; i > 0; i--) {// 468 行for (int j = 0; j < data_1[i].length; j++) {// 1048列byte index = dis_1.readByte();if (index < 0) {//此处转换同样是上面的道理返回的有可能是负数data_1[i][j] = index + 256;} else {data_1[i][j] = index;}}}state = true;// 将图片画在JFrame上 G = this.getGraphics();BMPColor bmpCol = new BMPColor();for (int i = 0; i < data_1.length; i++) {for (int j = 0; j < data_1[i].length; j++) {// 取出调色板对应的索引的颜色类对象bmpCol = colorSelector_1[data_1[i][j]];G.setColor(new Color(bmpCol.getR(), bmpCol.getG(), bmpCol.getB()));G.drawLine(j, i, j, i);}}/** * 初始化第二个图片 */InputStream in_2 = new FileInputStream("F:\\b2.bmp");DataInputStream dis_2 = new DataInputStream(in_2);dis_2.skipBytes(54);for (int i = 0; i < 256; i++) {/** * 先初始化对象 */colorSelector_2[i] = new BMPColor();int b = dis_2.readByte();int g = dis_2.readByte();int r = dis_2.readByte();dis_2.readByte();if (g < 0) {g += 256;colorSelector_2[i].g = g;} else {colorSelector_2[i].g = g;}if (r < 0) {r += 256;colorSelector_2[i].r = r;} else {colorSelector_2[i].r = r;}if (b < 0) {b += 256;colorSelector_2[i].b = b;} else {colorSelector_2[i].b = b;}}// 数组的索引初始化for (int i = data_2.length - 1; i > 0; i--) {// 468 行for (int j = 0; j < data_2[i].length; j++) {// 1048列byte index = dis_2.readByte();if (index < 0) {data_2[i][j] = index + 256;} else {data_2[i][j] = index;}}}System.out.println("第二章图片初始化完成........");} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}this.addMouseMotionListener(new MouseAdapter(){ public void mouseMoved(MouseEvent e) { System.out.println("@@@@@@@@@@@@@@"); if(state){ int x=e.getX(); System.out.println("Enter:   X="+myText_X); //通过x进行X方向的定位 //右边 BMPColor bmpColor; if(x<myText_X){ for(int i=0;i<data_2.length;i++){ for(int j=x;j<myText_X;j++){ bmpColor=colorSelector_2[data_2[i][j]]; G.setColor(new Color(bmpColor.r, bmpColor.g, bmpColor.b)); G.drawLine(j, i, j, i); } } }else{ //左边 for(int i=0;i<data_1.length;i++){ for(int j=myText_X;j<x;j++){ bmpColor=colorSelector_1[data_1[i][j]]; G.setColor(new Color(bmpColor.r, bmpColor.g, bmpColor.b)); G.drawLine(j, i, j, i); } }  }  myText_X=e.getX(); }   }});}class BMPColor {int b = 0;int g = 0;int r = 0;int a = 0;public int getB() {return b;}public int getG() {return g;}public int getR() {return r;}public int getA() {return a;}public void set_B(int b) {if (b < 0) {b += 256;}this.b = b;}public void set_G(int g) {if (g < 0) {g += 256;}this.g = g;}public void set_R(int r) {if (r < 0) {r += 256;}this.r = r;}public void set_A(int a) {if (a < 0) {a += 256;}this.a = a;}}public void paint(Graphics g) {if (state) {BMPColor bmpCol = new BMPColor();for (int i = 0; i < data_1.length; i++) {for (int j = 0; j < data_1[i].length; j++) {// 取出调色板对应的索引的颜色类对象bmpCol = colorSelector_1[data_1[i][j]];g.setColor(new Color(bmpCol.getR(), bmpCol.getG(),bmpCol.getB()));g.drawLine(j, i, j, i);}}}}}

?

?

?

?

?

读书人网 >编程

热点推荐