24-bit bmp格式图片颜色数据的获取和bmp文件的写入

问题描述

初学,我先简单说下我的思路吧!首先获得图片信息,然后根据位图信息头中相应的字节得到源图的宽和高,然后将宽和高转换成整型(int)。随后是获得图片的颜色信息。后来的是第二个类,这个类的作用是将得到的图片写入另一个bmp文件。我先把颜色的信息放到一个叫pointArray的数组,就是这个地方我不知道有没有问题,然后用java.awt.color中的getRed(),getBlue()...等方法获得像素中的颜色分量,最后可能是颜色存储的地方有问题,思绪混乱了,希望能得到帮助如下是源代码://ReadBmp24.javaimportjava.io.FileInputStream;importjava.io.IOException;publicclassReadBmp24{/***位图宽*/publicstaticintwidth;/***位图高*/publicstaticintheight;/***像素三分量数据*/publicstaticint[][]red1,green1,blue1;publicvoidinit(){try{FileInputStreamfis=newFileInputStream("D:\MyEclipse-8.6\test.bmp");java.io.BufferedInputStreambis=newjava.io.BufferedInputStream(fis);intbflen=14;//BitmapFileHeadbytebf[]=newbyte[bflen];fis.read(bf,0,bflen);intbilen=40;//BitmapInfoHeadbytebi[]=newbyte[bilen];fis.read(bi,0,bilen);//获取图片数据intnwidth=(((int)bi[7]&0xff)<<24)//源图宽度|(((int)bi[6]&0xff)<<16)|(((int)bi[5]&0xff)<<8)|(int)bi[4]&0xff;System.out.println("宽:"+nwidth);intnheight=(((int)bi[11]&0xff)<<24)//源图高度|(((int)bi[10]&0xff)<<16)|(((int)bi[9]&0xff)<<8)|(int)bi[8]&0xff;System.out.println("高:"+nheight);width=ChangeInt(bi,7);height=ChangeInt(bi,11);getInfo(bis);}catch(Exceptione){System.out.println(e);}}/***实现可将四个字节翻译int数据的方法**@parambi*存储字节的字节数组*@paramstart*起始字节*@return返回翻译后的int数据*/publicintChangeInt(byte[]array2,intstart){//因为char,byte,short这些数据类型经过运算符后会自动转为成int数据类,//所以array2[start]&0xff的实际意思就是通过&0xff将字符数据转化为正int数据,然后在进行位运算。inti=(int)((array2[start]&0xff)<<24)|((array2[start-1]&0xff)<<16)|((array2[start-2]&0xff)<<8)|(array2[start-3]&0xff);returni;}publicvoidgetInfo(java.io.BufferedInputStreambis){red1=newint[height][width];green1=newint[height][width];blue1=newint[height][width];intskip_width=0;intm=width*3%4;if(m!=0){skip_width=4-m;}for(inti=height-1;i>=0;i--){for(intj=0;j<width;j++){try{blue1[i][j]=bis.read();green1[i][j]=bis.read();red1[i][j]=bis.read();if(j==0){bis.skip(skip_width);}}catch(IOExceptione){e.printStackTrace();}}}}}//WriteBmp24importjava.awt.Color;publicclassWriteBmp24extendsReadBmp24{/***图形数据数组*/privatestaticColor[][]pointArray;/***图形的宽*/staticintwidth;/***图形的高*/staticintheight;/***将数据传入内存*/publicWriteBmp24(Color[][]pointArray){this.pointArray=pointArray;this.width=pointArray.length;this.height=pointArray[0].length;this.write();}publicvoidwrite(){try{//创建输出流文件对象java.io.FileOutputStreamfos=newjava.io.FileOutputStream("D:\MyEclipse-8.6\success.bmp");//创建原始数据输出流对象java.io.DataOutputStreamdos=newjava.io.DataOutputStream(fos);//给文件头的变量赋值intbfType=0x424d;//位图文件类型(0—1字节)intbfSize=54+width*height*3;//bmp文件的大小(2—5字节)intbfReserved1=0;//位图文件保留字,必须为0(6-7字节)intbfReserved2=0;//位图文件保留字,必须为0(8-9字节)intbfOffBits=54;//文件头开始到位图实际数据之间的字节的偏移量(10-13字节)//输入数据的时候要注意输入的数据在内存中要占几个字节,//然后再选择相应的写入方法,而不是它自己本身的数据类型//输入文件头数据dos.writeShort(bfType);//输入位图文件类型'BM'dos.write(changeByte(bfSize),0,4);//输入位图文件大小dos.write(changeByte(bfReserved1),0,2);//输入位图文件保留字dos.write(changeByte(bfReserved2),0,2);//输入位图文件保留字dos.write(changeByte(bfOffBits),0,4);//输入位图文件偏移量//给信息头的变量赋值intbiSize=40;//信息头所需的字节数(14-17字节)intbiWidth=width;//位图的宽(18-21字节)intbiHeight=height;//位图的高(22-25字节)intbiPlanes=1;//目标设备的级别,必须是1(26-27字节)intbiBitcount=24;//每个像素所需的位数(28-29字节),必须是1位(双色)、4位(16色)、8位(256色)或者24位(真彩色)之一。intbiCompression=0;//位图压缩类型,必须是0(不压缩)(30-33字节)、1(BI_RLEB压缩类型)或2(BI_RLE4压缩类型)之一。intbiSizeImage=width*height;//实际位图图像的大小,即整个实际绘制的图像大小(34-37字节)intbiXPelsPerMeter=0;//位图水平分辨率,每米像素数(38-41字节)这个数是系统默认值intbiYPelsPerMeter=0;//位图垂直分辨率,每米像素数(42-45字节)这个数是系统默认值intbiClrUsed=0;//位图实际使用的颜色表中的颜色数(46-49字节),如果为0的话,说明全部使用了intbiClrImportant=0;//位图显示过程中重要的颜色数(50-53字节),如果为0的话,说明全部重要//因为java是大端存储,那么也就是说同样会大端输出。//但计算机是按小端读取,如果我们不改变多字节数据的顺序的话,那么机器就不能正常读取。//所以首先调用方法将int数据转变为多个byte数据,并且按小端存储的顺序。//输入信息头数据dos.write(changeByte(biSize),0,4);//输入信息头数据的总字节数dos.write(changeByte(biWidth),0,4);//输入位图的宽dos.write(changeByte(biHeight),0,4);//输入位图的高dos.write(changeByte(biPlanes),0,2);//输入位图的目标设备级别dos.write(changeByte(biBitcount),0,2);//输入每个像素占据的字节数dos.write(changeByte(biCompression),0,4);//输入位图的压缩类型dos.write(changeByte(biSizeImage),0,4);//输入位图的实际大小dos.write(changeByte(biXPelsPerMeter),0,4);//输入位图的水平分辨率dos.write(changeByte(biYPelsPerMeter),0,4);//输入位图的垂直分辨率dos.write(changeByte(biClrUsed),0,4);//输入位图使用的总颜色数dos.write(changeByte(biClrImportant),0,4);//输入位图使用过程中重要的颜色数//因为是24位图,所以没有颜色表//通过遍历输入位图数据//这里遍历的时候注意,在计算机内存中位图数据是从左到右,从下到上来保存的,//也就是说实际图像的第一行的点在内存是最后一行for(inti=height-1;i>=0;i--){for(intj=0;j<width;j++){//这里还需要注意的是,每个像素是有三个RGB颜色分量组成的,//而数据在windows操作系统下是小端存储,对多字节数据有用。intred=pointArray[i][j].getRed();//得到位图点的红色分量intgreen=pointArray[i][j].getGreen();//得到位图点的绿色分量intblue=pointArray[i][j].getBlue();//得到位图点的蓝色分量byte[]red2=changeByte(red);byte[]green2=changeByte(green);byte[]blue2=changeByte(blue);dos.write(blue2,0,1);dos.write(green2,0,1);dos.write(red2,0,1);}}//关闭数据的传输dos.flush();dos.close();fos.close();System.out.println("success!!!"+height+width);}catch(Exceptione){e.printStackTrace();}}/***将一个int数据转为按小端顺序排列的字节数组*@paramdataint数据*@return按小端顺序排列的字节数组*/publicbyte[]changeByte(intdata){byteb4=(byte)((data)>>24);byteb3=(byte)(((data)<<8)>>24);byteb2=(byte)(((data)<<16)>>24);byteb1=(byte)(((data)<<24)>>24);byte[]bytes={b1,b2,b3,b4};returnbytes;}publicstaticvoidmain(String[]args){ReadBmp24rb=newReadBmp24();rb.init();Color[][]pointArray=newColor[height][width];{for(inti=height-1;i>=0;i--){for(intj=0;j<width;j++){pointArray[i][j]=newColor(ReadBmp24.red1[i][j],ReadBmp24.green1[i][j],ReadBmp24.blue1[i][j]);}}}WriteBmp24wb=newWriteBmp24(pointArray);wb.write();}}

解决方案

解决方案二:
真头痛,搞不清楚是颜色存储的问题还是什么其他的东西

时间: 2024-12-22 07:16:40

24-bit bmp格式图片颜色数据的获取和bmp文件的写入的相关文章

【数字图像处理】一.MFC详解显示BMP格式图片

本文主要是讲述<数字图像处理>系列栏目中的第一篇文章.主要详细介绍了BMP图片格式,同时使用C++和MFC显示BMP格式,主要结合自己的<数字图像处理>课程和以前的项目叙述讲解. 一.BMP图片格式定义 BMP文件格式是Windows操作系统推荐和支持的标准图像文件格式,是一种将内存或显示器的图像数据不经过压缩而直接按位存盘的文件格式,故称位图(bitmap),其扩展名为BMP.BMP图像通常有4个部分组成:位图文件头.位图信息头.颜色表.位图数据.如下图所示: 第一部分为位图文件

C语言实现对bmp格式图片打码_C 语言

相信大家看到上面的标题一定觉的是上面高大上的技术,其实很简单.前提准备:一张bmp格式的图片,如果没有的话,可以用Windows的画图软件来才裁剪.设置像素大小为(1024,768):程序原理:将图片读入数组,然后给数组的指定位置存入随机数,最后再写入文件,这样图片就相应的位置就被置为乱码了. 源代码: <span style="font-size:14px;">#include<stdio.h> #include<stdlib.h> #includ

Android中把bitmap存成BMP格式图片的方法

最近的项目,做图片的另存为功能,需要把图片存成jpg,png,bmp.对于jpg和png来说相对简单,android提供了bitmap.compress()方法可以马上解决.但是对于BMP这种格式,没有很好的支持.我花了几天时间在网上找了很久,都没有找到有用的答案,同样也发了疑问,没有合适的解答. package com.test.bitmap; import java.io.FileNotFoundException; import java.io.FileOutputStream; impo

php将bmp格式图片转换成jpg格式程序

 代码如下 复制代码 function imagebmp($img,$file="",$rle=0) { $colorcount=imagecolorstotal($img); $transparent=imagecolortransparent($img); $istransparent=$transparent!=-1; if($istransparent) $colorcount--; if($colorcount==0) {$colorcount=0; $bitcount=24

C# 视频采集卡获取视频,如何将视频帧保存BMP格式图片?

问题描述 本人初学,向各位达人学习.如果能附上例子,本人不甚感激! 解决方案 解决方案二:你要先说明一下,你用的什么技术获取的视频,使用技术不同,获得截图的方法也不同.解决方案三:仔细看看采集卡的API,应该有获取一帧图像的方法,如果没有那只能使用截屏了,就是获取视频显示窗口的句柄用操作系统的API截取窗口图像.解决方案四:你好,视频采集是用directshow.

python获取图片颜色信息的方法_python

本文实例讲述了python获取图片颜色信息的方法.分享给大家供大家参考.具体分析如下: python的pil模块可以从图片获得图片每个像素点的颜色信息,下面的代码演示了如何获取图片所有点的颜色信息和每种颜色的数量. from PIL import Image image = Image.open("jb51.gif") image.getcolors() 返回结果如下 复制代码 代码如下: ..., (44, (72, 64, 55, 255)), (32, (231, 208, 14

关于图片存储格式的整理(BMP格式介绍)_相关技巧

BMP BMP(全称Bitmap)是Window操作系统中的标准图像文件格式 可以分成两类:设备相关位图(DDB)和设备无关位图(DIB),使用非常广. 它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大.BMP文件的图像深度可选lbit.4bit.8bit及24bit.BMP文件存储数据时,图像的扫描方式是按从左到右.从下到上的顺序.由于BMP文件格式是Windows环境中交换与图有关的数据的一种标准,因此在Windows环境中运行的图形图像软件都

bmp格式是否可以构建16位无压缩灰阶图片?

问题描述 bmp格式是否可以构建16位无压缩灰阶图片? bmp格式是否可以构建16位无压缩灰阶图片? 也就是说2个字节表示一个像素的灰度值,其范围为0~65535. 查阅资料发现bmp无压缩时,需采用BIRGB,但系统随后会默认分解2字节的像素值, 从而按RGB555格式构成彩色图,即使添加一个灰阶颜色板也不行. 这是生物方面图像需求,不太清楚是否可以构成16位灰阶bmp文件. 解决方案 标准的 BMP 16 位时肯定是有处理的,数据有一定的丢失,只有 24 位时是真实还原的. 这也不叫压缩,因

torch7中如何加载bmp格式的图片?

问题描述 torch7中如何加载bmp格式的图片? 因为需要用到特定的数据集,数据集里都是bmp格式的图片.torch中通过image.load()不能加载bmp格式的图片,但是由于数据集太大,不方便做批量格式转换,请问有其他的可选方案吗? 解决方案 转载博客地址:http://www.cnblogs.com/landmark/ 到现在为止我们只创建了一个窗口,其他什么都没干,这次我们将在窗口里显示图片,这是视频子系统最常用的功能,显示图片.SDL视频子系统只能加载bmp格式的位图.调用函数是S