java 位图是什么(java高手来,位图问题~~)
各位老铁们好,相信很多人对java 位图是什么都不是特别的了解,因此呢,今天就来为大家分享下关于java 位图是什么以及java高手来,位图问题~~的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!
Java 技巧:用 Java 保存位图文件
如果您在 Microsoft Windows环境中工作那么创建位图文件的功能将为您提供许多方便例如在我的上一个项目中我必须将 Java与 Microsoft Access对接 Java程序允许用户在屏幕上绘图这幅图随后被打印到 Microsoft Access报表中由于 Java不支持 OLE我的唯一选择就是创建该图的一个位图文件并通知 Microsoft Access报表在何处能找到这个位图文件如果您写过向剪贴板发送图像的应用程序则这个技巧可能对您有用尤其是当您将这个信息传递给另一个应用程序时位图文件的格式位图文件格式支持位 RLE(行程长度编码)以及位和位编码因为我们只处理位格式所以下面我们查看一下该文件的结构位图文件分为三个部分我已将它们列在下面第部分位图文件的标头标头包含位图文件的类型大小信息和版面信息结构如下(摘自 C语言结构定义) typedef struct tagBITMAPFILEHEADER{牋燯INT bfType;牋燚WORD bfSize;牋燯INT bfReserved;牋燯INT bfReserved;牋燚WORD bfOffBits;}BITMAPFILEHEADER;下面是对这个清单中的代码元素的说明 bfType指定文件类型其值始终为 BM bfSize指定整个文件的大小(以字节为单位) bfReserved保留必须为 bfReserved保留必须为 bfOffBits指定从 BitmapFileHeader到图像首部的字节偏移量现在您已经明白位图标头的用途就是标识位图文件读取位图文件的每个程序都使用位图标头来进行文件验证第部分位图信息标头随后的标头称为信息标头其中包含图像本身的属性下面说明如何指定 Windows(或更高版本)设备独立位图(DIB)的大小和颜色格式: typedef struct tagBITMAPINFOHEADER{牋牋DWORD biSize;牋牋LONG biWidth;牋牋LONG biHeight;牋牋WORD biPlanes;牋牋WORD biBitCount;牋牋DWORD biCompression;牋牋DWORD biSizeImage;牋牋LONG biXPelsPerMeter;牋牋LONG biYPelsPerMeter;牋牋DWORD biClrUsed;牋牋DWORD biClrImportant;} BITMAPINFOHEADER;以上代码清单的每个元素说明如下 biSize指定 BITMAPINFOHEADER结构所需的字节数 biWidth指定位图的宽度(以象素为单位) biHeight指定位图的高度(以象素为单位) biPlanes指定目标设备的位面数这个成员变量的值必须为 biBitCount指定每个象素的位数其值必须为或 biCompression指定压缩位图的压缩类型在位格式中该变量被设置为 biSizeImage指定图像的大小(以字节为单位)如果位图的格式是 BI_RGB则将此成员变量设置为是有效的 biXPelsPerMeter为位图指定目标设备的水平分辨率(以象素/米为单位)应用程序可用该值从最符合当前设备特征的资源群组中选择一个位图 biYPelsPerMeter为位图指定目标设备的垂直分辨率(以象素/米为单位) biClrUsed指定位图实际所用的颜色表中的颜色索引数如果 biBitCount设为则 biClrUsed指定用来优化 Windows调色板性能的参考颜色表 biClrImportant指定对位图的显示有重要影响的颜色索引数如果此值为则所有颜色都很重要现在已定义了创建图像所需的全部信息第部分图像在位格式中图像中的每个象素都由存储为 BRG的三字节 RGB序列表示每个扫描行都被补足到位为了使这个过程稍复杂一点图像是自底而上存储的即第一个扫描行是图像中的最后一个扫描行下图显示了标头(BITMAPHEADER)和(BITMAPINFOHEADER)以及部分图像各个部分由垂线分隔 D B| E B EC EC| FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF*现在我们开始检视代码现在我们已经知道了位位图文件的结构下面就是您期待已久的内容用来将图像对象写入位图文件的代码 import java awt*;import java io*;import java awt image*;public class BMPFile extends Component{牋//私有常量牋private final static int BITMAPFILEHEADER_SIZE=;牋private final static int BITMAPINFOHEADER_SIZE=;牋//私有变量声明牋//位图文件标头牋private byte bitmapFileHeader []= new byte [ ];牋private byte bfType []={ B M};牋private int bfSize=;牋private int bfReserved=;牋private int bfReserved=;牋private int bfOffBits= BITMAPFILEHEADER_SIZE+ BITMAPINFOHEADER_SIZE;牋//位图信息标头牋private byte bitmapInfoHeader []= new byte [ ];牋private int biSize= BITMAPINFOHEADER_SIZE;牋private int biWidth=;牋private int biHeight=;牋private int biPlanes=;牋private int biBitCount=;牋private int biCompression=;牋private int biSizeImage= x;牋private int biXPelsPerMeter= x;牋private int biYPelsPerMeter= x;牋private int biClrUsed=;牋private int biClrImportant=;牋//位图原始数据牋private int bitmap [];牋//文件部分牋private FileOutputStream fo;牋//缺省构造函数牋public BMPFile(){牋}牋public void saveBitmap(String parFilename Image parImage intparWidth int parHeight){牋牋炉ry{牋牋牋牋fo= new FileOutputStream(parFilename);牋牋牋牋save(parImage parWidth parHeight);牋牋牋牋fo close();牋牋爙牋牋焘atch(Exception saveEx){牋牋牋牋saveEx printStackTrace();牋牋爙牋}牋/*牋? saveMethod是该进程的主方法该方法牋?将调用 convertImage方法以将内存图像转换为牋?字节数组 writeBitmapFileHeader方法创建并写入牋?位图文件标头 writeBitmapInfoHeader创建牋?信息标头 writeBitmap写入图像牋?牋?/牋private void save(Image parImage int parWidth int parHeight){牋牋炉ry{牋牋牋牋convertImage(parImage parWidth parHeight);牋牋牋牋writeBitmapFileHeader();牋牋牋牋writeBitmapInfoHeader();牋牋牋牋writeBitmap();牋牋爙牋牋焘atch(Exception saveEx){牋牋牋牋saveEx printStackTrace();牋牋爙牋}牋/*牋? convertImage将内存图像转换为位图格式(BRG)牋?它还计算位图信息标头所用的某些信息牋?牋?/牋private boolean convertImage(Image parImage int parWidth int parHeight){牋牋爄nt pad;牋牋燽itmap= new int [parWidth* parHeight];牋牋燩ixelGrabber pg= new PixelGrabber(parImage parWidth parHeight牋牋牋牋牋牋牋牋牋牋牋牋牋牋牋牋牋牋牋牋燽itmap parWidth);牋牋炉ry{牋牋牋牋pg grabPixels();牋牋爙牋牋焘atch(InterruptedException e){牋牋牋牋e printStackTrace();牋牋牋牋return(false);牋牋爙牋牋爌ad=(((parWidth*)%))* parHeight;牋牋燽iSizeImage=((parWidth* parHeight)*)+ pad;牋牋燽fSize= biSizeImage+ BITMAPFILEHEADER_SIZE+BITMAPINFOHEADER_SIZE;牋牋燽iWidth= parWidth;牋牋燽iHeight= parHeight;牋牋爎eturn(true);牋}牋/*牋? writeBitmap将象素捕获器返回的图像转换为牋?所需的格式请记住扫描行在位图文件中是牋?反向存储的!牋?牋?每个扫描行必须补足为个字节牋?/牋private void writeBitmap(){牋牋牋int size;牋牋牋int value;牋牋牋int j;牋牋牋int i;牋牋牋int rowCount;牋牋牋int rowIndex;牋牋牋int lastRowIndex; lishixinzhi/Article/program/Java/JSP/201311/19219
Java处理bmp图像,怎样操作BMP位图的数据
bmp图像文件数据分为三个部分:
1、前14个字节为文件信息头,在这部分信息中包含了位图信息标志、该bmp图像的大小和图像实际数据的相对偏移量这三部分有用的信息。
位图标志一定为“0x4D42”,否则,该文件不是bmp图像。
在VC++中,这14个字节对应一个数据类型,类型名为“BITMAPFILEHEADER”,它的定义为:
typedef struct tagBITMAPFILEHEADER{
WORD bfType;//位图信息标志
DWORD bfSize;//图像的大小
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;//图像实际数据的相对偏移量
} BITMAPFILEHEADER, FAR*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;
可以设一个该类型的变量:BITMAPFILEHEADER bmfh,将bmp图像文件的前14字节数据读入这个变量中,然后通过判断bmfh.bfType== 0x4D42,确定是不是为bmp图像。
2、接下来40个字节为位图信息头,其中存储了该bmp图像的有关信息。这些信息包括:图像宽度(像素)、图像高度(像素)、图像长度(字节,仅仅是图像实际数据的长度,不包括各个信息头)、水平分辨率、垂直分辨率、每个像素的存储位数等信息。
其中,通过“每个像素的存储位数”这个信息可以知道图像的颜色:
如果“每个像素的存储位数”的值只有四种:为1,说明图像只有两种颜色(黑、白);为4,说明图像有16种颜色;为8,说明图像有256种颜色;为24,说明该图像为真彩色图像,颜色数为2^24。这四种取值对应四种bmp图像,也就是说,bmp图像只有这四种。
在这四种bmp图像种,前三种都需要在图像文件中包含调色板数据,分别存储三种图像的2、16、256种颜色。而最后一种bmp格式的图像不需要调色板,因为这种图像的“每个像素的存储位数”值为24,也就是说,存储一个像素值需要24位,正好可以存储一个像素的颜色(红、绿、蓝各8位)。
在VC++中,这40个字节的位图信息头也有一个数据类型,类型名为“BITMAPINFOHEADER”,它的定义为:
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;//图像宽度(像素)
LONG biHeight;//图像高度(像素)
WORD biPlanes;
WORD biBitCount;//每个像素的存储位数
DWORD biCompression;
DWORD biSizeImage;//图像长度(字节,仅仅是图像实际数据的长度,不包括各个信息头)
LONG biXPelsPerMeter;//水平分辨率
LONG biYPelsPerMeter;//垂直分辨率
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, FAR*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER;
3、接下来若干个字节为调色板,只有前三种bmp图像有,第四种真彩色bmp图像没有这部分数据。
调色板是一个数组,每个数组元素有四字节,只有三个字节有用,另外一个没有。有用的三个字节存储一种颜色(红绿蓝各占一字节),这四个字节在VC++中定义为:
typedef struct tagRGBQUAD{
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
定义一个这种类型的数组即为调色板。数组的长度可由BITMAPINFOHEADER中的biBitCount推算出来。
4、上述三部分信息之后,即是实际的像素数据。一个像素的存储位数为1、4、8或16,正如前面所述。
如果是1位,对应的bmp图像应该有一个长度为2的调色板。这一位的值只能是0或1,用来指明该像素的颜色在调色板中的地址。
如果是4位,对应的bmp图像应该有一个长度为16的调色板。这4位的值有16种,同样指示该像素的颜色在调色板中的地址。
如果是8位,对应的bmp图像应该有一个长度为256的调色板。这8位的值有256种,同样指示该像素的颜色在调色板中的地址。
如果是24位,对应的bmp图像没有调色板,该像素的颜色由这24位数据直接表示。
bmp图像的数据就这几个部分。
任何一个bmp图像的像素都是由红绿蓝三种颜色组成(带调色板也好,不带调色板也好)。如果一个像素的红绿蓝三种色的值相等,那么该像素就是灰色的。灰度图是这样一种有严格规定的bmp图像:它是上述四种bmp图像的第三种,并且它的调色板的每个数组元素的红绿蓝三值都相同,所以灰度图的灰度种数是256。
若要保存图像,需要按顺序保存文件信息头、位图信息头、调色板(如果有)和图像的实际数据。程序可以这样写:
bool Write(CString FileName)
{
CFile file;
BITMAPFILEHEADER bmfh;
if(!(bmi&& pBits))
{
AfxMessageBox("Data is not valid!");
return FALSE;
}
//创建文件
if(!file.Open(FileName,CFile::modeCreate| CFile::modeWrite))
{
AfxMessageBox("File creating fails!");
return FALSE;
}
//填写文件信息头
bmfh.bfType= 0x4d42;
bmfh.bfReserved1= bmfh.bfReserved2= 0;
int nInfoSize= sizeof(BITMAPINFOHEADER)+ GetPaletteSize()* sizeof(RGBQUAD);
bmfh.bfOffBits= sizeof(bmfh)+ nInfoSize;
bmfh.bfSize= bmfh.bfOffBits+ bmi->bmiHeader.biSizeImage;
//写文件
file.Write((LPVOID)&bmfh, sizeof(bmfh));
file.Write((LPVOID)bmi, nInfoSize);
file.Write((LPVOID)pBits, bmi->bmiHeader.biSizeImage);
return TRUE;
}
java高手来,位图问题~~
作者 Jean-Pierre Dubé
摘要
虽然 Java提供了几种打开图像的机制,但保存图像并不是他的强项。这篇技巧将讲述怎么将图像保存在 24位位图文件中。另外,Jean-Pierre还提供了将图像文件写入位图文件所需的全部代码。
这篇技巧是 Java技巧 43的补充,那篇技巧说明了在 Java应用程式中加载位图文件的过程。本月我再提供一篇教程,说明怎么将图像保存在 24位位图文件中,其中还包含将图像对象写入位图文件的代码片断。
如果你在 Microsoft视窗系统环境中工作,那么创建位图文件的功能将为你提供许多方便。例如,在我的上一个项目中,我必须将 Java和 Microsoft Access对接。Java程式允许用户在屏幕上绘图。这幅图随后被打印到 Microsoft Access报表中。由于 Java不支持 OLE,我的唯一选择就是创建该图的一个位图文件,并通知 Microsoft Access报表在何处能找到这个位图文件。如果你写过向剪贴板发送图像的应用程式,则这个技巧可能对你有用--尤其是当你将这个信息传递给另一个应用程式时。
位图文件的格式
位图文件格式支持 4位 RLE(行程长度编码)及 8位和 24位编码。因为我们只处理 24位格式,所以下面我们查看一下该文件的结构。
位图文件分为三个部分。我已将他们列在下面。
第 1部分:位图文件的标头
标头包含位图文件的类型大小信息和版面信息。结构如下(摘自 C语言结构定义):
typedef struct tagBITMAPFILEHEADER{
UINT bfType;
DWORD bfSize;
UINT bfReserved1;
UINT bfReserved2;
DWORD bfOffBits;
}BITMAPFILEHEADER;
下面是对这个清单中的代码元素的说明:
bfType:指定文件类型,其值始终为 BM。
bfSize:指定整个文件的大小(以字节为单位)。
bfReserved1:保留--必须为 0。
bfReserved2:保留--必须为 0。
bfOffBits:指定从 BitmapFileHeader到图像首部的字节偏移量。
目前你已明白位图标头的用途就是标识位图文件。读取位图文件的每个程式都使用位图标头来进行文件验证。
第 2部分:位图信息标头
随后的标头称为信息标头,其中包含图像本身的属性。
下面说明怎么指定视窗系统 3.0(或更高版本)设备独立位图(DIB)的大小和颜色格式:
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
以上代码清单的每个元素说明如下:
biSize:指定 BITMAPINFOHEADER结构所需的字节数。
biWidth:指定位图的宽度(以象素为单位)。
biHeight:指定位图的高度(以象素为单位)。
biPlanes:指定目标设备的位面数。这个成员变量的值必须为 1。
biBitCount:指定每个象素的位数。其值必须为 1、4、8或 24。
biCompression:指定压缩位图的压缩类型。在 24位格式中,该变量被设置为 0。
biSizeImage:指定图像的大小(以字节为单位)。如果位图的格式是 BI_RGB,则将此成员变量设置为 0是有效的。
biXPelsPerMeter:为位图指定目标设备的水平分辨率(以“象素/米”为单位)。应用程式可用该值从最符合当前设备特征的资源群组中选择一个位图。
biYPelsPerMeter:为位图指定目标设备的垂直分辨率(以“象素/米”为单位)。
biClrUsed:指定位图实际所用的颜色表中的颜色索引数。如果 biBitCount设为 24,则 biClrUsed指定用来优化视窗系统调色板性能的参考颜色表。
biClrImportant:指定对位图的显示有重要影响的颜色索引数。如果此值为 0,则所有颜色都非常重要。
目前已定义了创建图像所需的全部信息。
第 3部分:图像
在 24位格式中,图像中的每个象素都由存储为 BRG的三字节 RGB序列表示。每个扫描行都被补足到 4位。为了使这个过程稍复杂一点,图像是自底而上存储的,即第一个扫描行是图像中的最后一个扫描行。下图显示了标头(BITMAPHEADER)和(BITMAPINFOHEADER)及部分图像。各个部分由垂线分隔:
0000000000 4D42 B536 0002 0000 0000 0036 0000| 0028
0000000020 0000 0107 0000 00E0 0000 0001 0018 0000
0000000040 0000 B500 0002 0EC4 0000 0EC4 0000 0000
0000000060 0000 0000 0000| FFFF FFFF FFFF FFFF FFFF
0000000100 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
*
目前,我们开始检视代码
目前我们已知道了 24位位图文件的结构,下面就是你期待已久的内容:用来将图像对象写入位图文件的代码。
import java.awt.*;
import java.io.*;
import java.awt.image.*;
public class BMPFile extends Component{
//---私有常量
private final static int BITMAPFILEHEADER_SIZE= 14;
private final static int BITMAPINFOHEADER_SIZE= 40;
//---私有变量声明
//---位图文件标头
private byte bitmapFileHeader []= new byte [14];
private byte bfType []={’B’,’M’};
private int bfSize= 0;
private int bfReserved1= 0;
private int bfReserved2= 0;
private int bfOffBits= BITMAPFILEHEADER_SIZE+ BITMAPINFOHEADER_SIZE;
//---位图信息标头
private byte bitmapInfoHeader []= new byte [40];
private int biSize= BITMAPINFOHEADER_SIZE;
private int biWidth= 0;
private int biHeight= 0;
private int biPlanes= 1;
private int biBitCount= 24;
private int biCompression= 0;
private int biSizeImage= 0x030000;
private int biXPelsPerMeter= 0x0;
private int biYPelsPerMeter= 0x0;
private int biClrUsed= 0;
private int biClrImportant= 0;
//---位图原始数据
private int bitmap [];
//---文件部分
private FileOutputStream fo;
//---缺省构造函数
public BMPFile(){
}
public void saveBitmap(String parFilename, Image parImage, int
parWidth, int parHeight){
try{
fo= new FileOutputStream(parFilename);
save(parImage, parWidth, parHeight);
fo.close();
}
catch(Exception saveEx){
saveEx.printStackTrace();
}
}
/*
* saveMethod是该进程的主方法。该方法
*将调用 convertImage方法以将内存图像转换为
*字节数组;writeBitmapFileHeader方法创建并写入
*位图文件标头;writeBitmapInfoHeader创建
*信息标头;writeBitmap写入图像。
*
*/
private void save(Image parImage, int parWidth, int parHeight){
try{
convertImage(parImage, parWidth, parHeight);
writeBitmapFileHeader();
writeBitmapInfoHeader();
writeBitmap();
}
catch(Exception saveEx){
saveEx.printStackTrace();
}
}
/*
* convertImage将内存图像转换为位图格式(BRG)。
*他还计算位图信息标头所用的某些信息。
*
*/
private boolean convertImage(Image parImage, int parWidth, int parHeight){
int pad;
bitmap= new int [parWidth* parHeight];
PixelGrabber pg= new PixelGrabber(parImage, 0, 0, parWidth, parHeight,
bitmap, 0, parWidth);
try{
pg.grabPixels();
}
catch(InterruptedException e){
e.printStackTrace();
return(false);
}
pad=(4-((parWidth* 3)% 4))* parHeight;
biSizeImage=((parWidth* parHeight)* 3)+ pad;
bfSize= biSizeImage+ BITMAPFILEHEADER_SIZE+
BITMAPINFOHEADER_SIZE;
biWidth= parWidth;
biHeight= parHeight;
return(true);
}
/*
* writeBitmap将象素捕捉器返回的图像转换为
*所需的格式。请记住:扫描行在位图文件中是
*反向存储的!
*
*每个扫描行必须补足为 4个字节。
*/
private void writeBitmap(){
int size;
int value;
int j;
int i;
int rowCount;
int rowIndex;
int lastRowIndex;
int pad;
int padCount;
byte rgb []= new byte [3];
size=(biWidth* biHeight)- 1;
pad= 4-((biWidth* 3)% 4);
if(pad== 4)//<====错误修正
pad= 0;//<====错误修正
rowCount= 1;
padCount= 0;
rowIndex= size- biWidth;
lastRowIndex= rowIndex;
try{
for(j= 0; j< size; j++){
value= bitmap [rowIndex];
rgb [0]=(byte)(value& 0xFF);
rgb [1]=(byte)((value>> 8)& 0xFF);
rgb [2]=(byte)((value>> 16)& 0xFF);
fo.write(rgb);
if(rowCount== biWidth){
padCount+= pad;
for(i= 1; i<= pad; i++){
fo.write(0x00);
}
rowCount= 1;
rowIndex= lastRowIndex- biWidth;
lastRowIndex= rowIndex;
}
else
rowCount++;
rowIndex++;
}
//---更新文件大小
bfSize+= padCount- pad;
biSizeImage+= padCount- pad;
}
catch(Exception wb){
wb.printStackTrace();
}
}
/*
* writeBitmapFileHeader将位图文件标头写入文件中。
*
*/
private void writeBitmapFileHeader(){
try{
fo.write(bfType);
fo.write(intToDWord(bfSize));
fo.write(intToWord(bfReserved1));
fo.write(intToWord(bfReserved2));
fo.write(intToDWord(bfOffBits));
}
catch(Exception wbfh){
wbfh.printStackTrace();
}
}
/*
*
* writeBitmapInfoHeader将位图信息标头
*写入文件中。
*
*/
private void writeBitmapInfoHeader(){
try{
fo.write(intToDWord(biSize));
fo.write(intToDWord(biWidth));
fo.write(intToDWord(biHeight));
fo.write(intToWord(biPlanes));
fo.write(intToWord(biBitCount));
fo.write(intToDWord(biCompression));
fo.write(intToDWord(biSizeImage));
fo.write(intToDWord(biXPelsPerMeter));
fo.write(intToDWord(biYPelsPerMeter));
fo.write(intToDWord(biClrUsed));
fo.write(intToDWord(biClrImportant));
}
catch(Exception wbih){
wbih.printStackTrace();
}
}
/*
*
* intToWord将整数转换为单字,返回值
*存储在一个双字节数组中。
*
*/
private byte [] intToWord(int parValue){
byte retValue []= new byte [2];
retValue [0]=(byte)(parValue& 0x00FF);
retValue [1]=(byte)((parValue>> 8)& 0x00FF);
return(retValue);
}
/*
*
* intToDWord将整数转换为双字,返回值
*存储在一个 4字节数组中。
*
*/
private byte [] intToDWord(int parValue){
byte retValue []= new byte [4];
retValue [0]=(byte)(parValue& 0x00FF);
retValue [1]=(byte)((parValue>> 8)& 0x000000FF);
retValue [2]=(byte)((parValue>> 16)& 0x000000FF);
retValue [3]=(byte)((parValue>> 24)& 0x000000FF);
return(retValue);
}
}
好了,文章到这里就结束啦,如果本次分享的java 位图是什么和java高手来,位图问题~~问题对您有所帮助,还望关注下本站哦!