用C语言读取16位bmp图片的每个像素的信息~

用C语言读取16位bmp图片的每个像素的信息~,第1张

没有什么不同。

读出 BITMAPINFO 结构:

typedef struct tagBITMAPINFO {

BITMAPINFOHEADER bmiHeader;

RGBQUAD bmiColors[1];

} BITMAPINFO;

以后,

BITMAPINFOHEADER 结构 里就有 biBitCount

biBitCount 等于 16 就是16位,等于24 就是24位,等于32 就是32位。

颜色在哪,要考虑 biCompression 压缩方法,若等于 BI_RGB, bmiColors 就等于 NULL 在 bitmap 数组里 每个WORD 就是 一个像素点 5个 bits 兰,5个 bits 绿,再5个 bits 红,最高位不用。

其它方法自己看资料吧。

/

你还是听听高先生的建议吧,

前面我给你的回答除了使用了c++的‘

//’注释以外,使用纯C语言编写的。

你如果仅仅是想完你说的目的,

虽然一小段代码可以就完成但是却不太容易读懂 。

图像右下角坐标为(0,0)

/

#include<stdioh>

int main()

{

int width,height,x,y;

unsigned short bitCount;

int offbits;

int bitPerLine;

unsigned char data;

FILE bmpfp = fopen("E:\\风景\\风景1bmp","rb");

fseek(bmpfp,18,SEEK_SET);

fread(&width,sizeof(int),1,bmpfp);

fread(&height,sizeof(int),1,bmpfp);

printf("width : %d , height : %d\n",width,height);

fseek(bmpfp,2,SEEK_CUR);

fread(&bitCount,sizeof(bitCount),1,bmpfp);

fseek(bmpfp,10,SEEK_SET);

fread(&offbits,sizeof(int),1,bmpfp);

if(bitCount==24){

bitPerLine = ( (width3)%4==0 ) width3 : ( (width3)/4 )4 + 4;

while(1){

printf("请输出坐标:");

scanf("%d%d",&x,&y);

if(x>width||y>height) return 0;

fseek(bmpfp, 18 + offbits + bitPerLine y + 3x , SEEK_SET);

fread(&data,sizeof(data),1,bmpfp);

printf("该点蓝色分量:%d",data);

fread(&data,sizeof(data),1,bmpfp);

printf("该点绿色分量:%d",data);

fread(&data,sizeof(data),1,bmpfp);

printf("该点红色分量:%d\n",data);

}

}else{

printf("不是真彩位图!");

}

}

/

运行结果:

width : 700 , height : 382

请输出坐标:0 0

该点蓝色分量:68该点绿色分量:82该点红色分量:80

/

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字节数据读入这个变量中,然后通过判断bmfhbfType == 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(!fileOpen(FileName,CFile::modeCreate | CFile::modeWrite))

{

AfxMessageBox("File creating fails!");

return FALSE;

}

//填写文件信息头

bmfhbfType = 0x4d42;

bmfhbfReserved1 = bmfhbfReserved2 = 0;

int nInfoSize = sizeof(BITMAPINFOHEADER) + GetPaletteSize() sizeof(RGBQUAD);

bmfhbfOffBits = sizeof(bmfh) + nInfoSize;

bmfhbfSize = bmfhbfOffBits + bmi->bmiHeaderbiSizeImage;

//写文件

fileWrite( (LPVOID)&bmfh, sizeof(bmfh));

fileWrite( (LPVOID)bmi, nInfoSize);

fileWrite( (LPVOID)pBits, bmi->bmiHeaderbiSizeImage);

return TRUE;

}

>

using SystemRuntimeInteropServices;

[DllImport("gdi32dll")]

public static extern IntPtr ExtCreateRegion(IntPtr lpXform, uint nCount,

ref byte lpRgnData);

public static int RGN_AND = 1;

public static int RGN_OR = 2;

public static int RGN_XOR = 3;

public static int RGN_DIFF = 4;

public static int RGN_COPY = 5;

public static int RGN_MIN = RGN_AND;

public static int RGN_MAX = RGN_COPY;

[DllImport("gdi32dll")]

public static extern int CombineRgn(IntPtr hrgnDest, IntPtr hrgnSrc1, IntPtr hrgnSrc2,

int fnCombineMode);

[DllImport("gdi32dll")]public static extern bool DeleteObject(IntPtr hObject);

public Region ImageToRegion(Image AImage, Color ATransparent)

{

//转贴请注明出处ZswangY37(wjhu111#21cncom) 时间2007-05-25

if (AImage == null) return null;

Bitmap vBitmap = new Bitmap(AImage);

BitmapData vBitmapData = vBitmapLockBits(

new Rectangle(0, 0, vBitmapWidth, vBitmapHeight),

ImageLockModeReadOnly, PixelFormatFormat32bppRgb);

int vAddress = (int)vBitmapDataScan0;

int vOffset = vBitmapDataStride - vBitmapWidth 4; // 每行多出的字节数

int h = vBitmapHeight, w = vBitmapWidth;

int vTransparent = ColorTranslatorToWin32(ATransparent); // 透明色

int vAllocRect = (0x1000 - sizeof(uint) 8) / sizeof(int); // 预分配的矩形数

if (h w < vAllocRect) vAllocRect = h w;

Byte[] vBuffer = new byte[sizeof(uint) 8 + sizeof(int) 4 vAllocRect];

//头信息dwSize\iType\nCount\nRegSize

uint vCount = 0;

vBuffer[0] = sizeof(uint) 8; //dwSize//头信息大小

vBuffer[4] = 1; //iType//int RDH_RECTANGLES = 1;//数据类型

IntPtr vResult = IntPtrZero;

uint vPointer = sizeof(uint) 8;

bool vWriteRect = false; bool vWriteAlways = false;

for (int y = 0; y < h; y++)

{

int vBlockStart = 0;

bool vLastMaskBit = false;

for (int x = 0; x < w; x++)

{

int i = MarshalReadInt32((IntPtr)vAddress) & 0x00FFFFFF;

if (vTransparent == i) // 透明色

{

if (vLastMaskBit)

vWriteRect = true;

}

else

{

if (!vLastMaskBit)

{

vBlockStart = x;

vLastMaskBit = true;

}

}

if (x == w - 1)

{

if (y == h - 1)

{

vWriteRect = true;

vWriteAlways = true;

}

else if (vLastMaskBit)

{

vWriteRect = true;

}

x++;

}

if (vWriteRect)

{

if (vLastMaskBit)

{

vCount++;

WriteRect(vBuffer, ref vPointer,

new Rectangle(vBlockStart, y, x - vBlockStart, 1));

}

if (vCount == vAllocRect || vWriteAlways)

{

vBuffer[8] = (byte)vCount;

vBuffer[9] = (byte)(vCount >> 8);

vBuffer[10] = (byte)(vCount >> 16);

vBuffer[11] = (byte)(vCount >> 24);

IntPtr hTemp = ExtCreateRegion(IntPtrZero,

sizeof(uint) 8 + sizeof(int) 4 vCount,

ref vBuffer[0]);

if (vResult == IntPtrZero)

vResult = hTemp;

else

{

CombineRgn(vResult, vResult, hTemp, RGN_OR);

DeleteObject(hTemp);

}

vCount = 0;

vPointer = sizeof(uint) 4;

vWriteAlways = false;

}

vWriteRect = false;

vLastMaskBit = false;

}

vAddress += 4;

}

vAddress += vOffset;

}

vBitmapUnlockBits(vBitmapData);

return RegionFromHrgn(vResult);

}

private void WriteRect(byte[] ARGNData, ref uint ptr, Rectangle r)

{

ARGNData[ptr] = (byte)rX;

ARGNData[ptr + 1] = (byte)(rX >> 8);

ARGNData[ptr + 2] = (byte)(rX >> 16);

ARGNData[ptr + 3] = (byte)(rX >> 24);

ARGNData[ptr + 4] = (byte)rY;

ARGNData[ptr + 5] = (byte)(rY >> 8);

ARGNData[ptr + 6] = (byte)(rY >> 16);

ARGNData[ptr + 7] = (byte)(rY >> 24);

ARGNData[ptr + 8] = (byte)rRight;

ARGNData[ptr + 9] = (byte)(rRight >> 8);

ARGNData[ptr + 10] = (byte)(rRight >> 16);

ARGNData[ptr + 11] = (byte)(rRight >> 24);

ARGNData[ptr + 12] = (byte)rBottom;

ARGNData[ptr + 13] = (byte)(rBottom >> 8);

ARGNData[ptr + 14] = (byte)(rBottom >> 16);

ARGNData[ptr + 15] = (byte)(rBottom >> 24);

ptr += 16;

}

private void button1_Click(object sender, EventArgs e)

{

Region = ImageToRegion(pictureBox1Image, ColorFromArgb(216, 233, 236));

}

来源:>

楼上的基本正确,

问题一:

int[] rgb = new int[3];最好用二维数组

int[] rgb = new int[3][widthheight]

问题二:

rgb[0] = (pixel & 0xff0000 ) >> 16 ;

rgb[1] = (pixel & 0xff00 ) >> 8 ;

rgb[2] = (pixel & 0xff );

会把数组内的值覆盖,获得就是最后像素点的RGB值;

我写了一个希望可以帮助到你

package imageReadAndWrite;

import javaawtimageBufferedImage;

import javaioFileInputStream;

import javaioFileNotFoundException;

import javaioFileOutputStream;

import javaioIOException;

import comsunimagecodecjpegJPEGCodec;

import comsunimagecodecjpegJPEGImageDecoder;

import comsunimagecodecjpegJPEGImageEncoder;

/

JPG File reader/writer Uses native comsun libraries (which may deprecate at

any time)

@author PhoenixZJG

@version 10

/

public class JPGFile implements xxxFile {

private int[] ints = null;

private byte bytes[] = null; // bytes which make up binary PPM image

private double doubles[] = null;

private int[][] imageRGB = null;

private String filename = null; // filename for PPM image

private int height = 0;

private int width = 0;

/

Read the PPM File

@throws FileNotFoundException

if the directory/image specified is wrong

@throws IOException

if there are problems reading the file

/

public JPGFile(String filename) throws FileNotFoundException, IOException {

thisfilename = filename;

readImage();

}

/

Get the height of the PPM image

@return the height of the image

/

public int getHeight() {

return height;

}

/

Get the width of the PPM image

@return the width of the image

/

public int getWidth() {

return width;

}

/

Get the data as byte array Data is of any type that has been read from

the file (usually 8bit RGB)

@return The data of the image

/

public byte[] getBytes() {

return bytes;

}

/

Get the data as double array Data is of any type that has been read from

the file (usually 8bit RGB put into an 64bit double)

@return The data of the image

/

public double[] getDouble() {

return doubles;

}

/

Get the data as double array Data is of any type that has been read from

the file (usually 8bit RGB put into an 64bit double)

@return The data of the image

/

public int[] getInt() {

return ints;

}

/

Get the data as integer array Data is of any type that has been read from

the file (usually 8bit RGB put into an 64bit double)

@return The data of the image

/

public int[][] getImageRGB() {

return imageRGB;

}

/

Write to <code>fn</code> file the <code>data</code> using the

<code>width, height</code> variables Data is assumed to be 8bit RGB

@throws FileNotFoundException

if the directory/image specified is wrong

@throws IOException

if there are problems reading the file

/

public static void writeImage(String fn, int[] data, int width, int height)

throws FileNotFoundException, IOException {

FileOutputStream fOut = new FileOutputStream(fn);

JPEGImageEncoder jpeg_encode = JPEGCodeccreateJPEGEncoder(fOut);

BufferedImage image = new BufferedImage(width, height,

BufferedImageTYPE_INT_RGB);

imagesetRGB(0, 0, width, height, data, 0, width);

jpeg_encodeencode(image);

fOutclose();

}

/

Read the image from the specified file

@throws FileNotFoundException

pretty obvious

@throws IOException

filesystem related problems

/

private void readImage() throws FileNotFoundException, IOException {

FileInputStream fIn = new FileInputStream(filename);

JPEGImageDecoder jpeg_decode = JPEGCodeccreateJPEGDecoder(fIn);

BufferedImage image = jpeg_decodedecodeAsBufferedImage();

width = imagegetWidth();

height = imagegetHeight();

int[] rgbdata = new int[width height];

imagegetRGB(0, 0, width, height, rgbdata, 0, width);

ints = rgbdata;

bytes = new byte[rgbdatalength];

doubles = new double[rgbdatalength];

imageRGB = new int[3][rgbdatalength];

for (int i = 0; i < byteslength; i++) {

bytes[i] = (byte) (rgbdata[i] & 0xFF);

doubles[i] = (double) (rgbdata[i]);

imageRGB[0][i] = (rgbdata[i] & 16711680) >> 16;

imageRGB[1][i] = (rgbdata[i] & 65280) >> 8;

imageRGB[2][i] = (rgbdata[i] & 255);

}

}

}

上述代码可以复制,粘贴使用,有方法的注视,getImageRGB() 就可以获得所有像素的RGB值,你就可以在其他方法里处理这个二维数组,得到你想要的平均值了,处理后的值,记得把值逆运算,再转换到Int[]里,就可以用,writeImage()输出图像了。

法,再有针对性的研究VC如何做图像处理,有以下资料可参考(网上多得是)

1. 图像文件的格式;

2. 图像编程的基础- *** 作调色板;

3. 图像数据的读取、存储和显示、如何获取图像的尺寸等;

4. 利用图像来美化界面;

5. 图像的基本 *** 作:图像移动、图像旋转、图像镜像、图像的缩放、图像的剪切板 *** 作;

6. 图像显示的各种特技效果;

7. 图像的基本处理:图像的二值化、图像的亮度和对比度的调整、图像的边缘增强、如何得到图像的直方图、图像直方图的修正、图像的平滑、图像的锐化等、图像的伪彩色、彩色图像转换为黑白图像、物体边缘的搜索等等;

8. 二值图像的处理:腐蚀、膨胀、细化、距离变换等;

9. 图像分析:直线、圆、特定物体的识别;

10.JEPG、GIF、PCX等格式文件相关 *** 作;

11.图像文件格式的转换;

12.图像的常用变换:付利叶变换、DCT变换、沃尔什变换等;

13.AVI视频流的 *** 作;

图像处理技术博大精深,不仅需要有很强的数学功底,还需要熟练掌握一门计算机语言,在当前流行的语言中,我个人觉的Visual C++这个开发平台是图像开发人员的首选工具。本讲座只是起到抛砖引玉的作用,希望和广大读者共同交流。

VC数字图像处理编程讲座之二

第一节 图像的文件格式

要利用计算机对数字化图像进行处理,首先要对图像的文件格式要有清楚的认识,因为我们前面说过,自然界的图像以模拟信号的形式存在,在用计算机进行处理以前,首先要数字化,比如摄像头(CCD)摄取的信号在送往计算机处理前,一般情况下要经过数模转换,这个任务常常由图像采集卡完成,它的输出一般为裸图的形式;如果用户想要生成目标图像文件,必须根据文件的格式做相应的处理。随着科技的发展,数码像机、数码摄像机已经进入寻常百姓家,我们可以利用这些设备作为图像处理系统的输入设备来为后续的图像处理提供信息源。无论是什么设备,它总是提供按一定的图像文件格式来提供信息,比较常用的有BMP 格式、JPEG格式、GIF格式等等,所以我们在进行图像处理以前,首先要对图像的格式要有清晰的认识,只有在此基础上才可以进行进一步的开发处理。

在讲述图像文件格式前,先对图像作一个简单的分类。除了最简单的图像外,所有的图像都有颜色,而单色图像则是带有颜色的图像中比较简单的格式,它一般由黑色区域和白色区域组成,可以用一个比特表示一个像素,"1"表示黑色,"0"表示白色,当然也可以倒过来表示,这种图像称之为二值图像。我们也可以用8个比特(一个字节)表示一个像素,相当于把黑和白等分为256个级别,"0"表示为黑,"255"表示为白,该字节的数值表示相应像素值的灰度值或亮度值,数值越接近"0",对应像素点越黑,相反,则对应像素点越白,此种图像我们一般称之为灰度图像。单色图像和灰度图像又统称为黑白图像,与之对应存在着彩色图像,这种图像要复杂一些,表示图像时,常用的图像彩色模式有RGB模式、CMYK模式和HIS模式,一般情况下我们只使用RGB模式,R 对应红色,G对应绿色,B对应蓝色,它们统称为三基色,这三中色彩的不同搭配,就可以搭配成各种现实中的色彩,此时彩色图像的每一个像素都需要3个样本组成的一组数据表示,其中每个样本用于表示该像素的一个基本颜色。

对于现存的所有的图像文件格式,我们在这里主要介绍BMP图像文件格式,并且文件里的图像数据是未压缩的,因为图像的数字化处理主要是对图像中的各个像素进行相应的处理,而未压缩的BMP图像中的像素数值正好与实际要处理的数字图像相对应,这种格式的文件最合适我们对之进行数字化处理。请读者记住,压缩过的图像是无法直接进行数字化处理的,如JPEG、GIF等格式的文件,此时首先要对图像文件解压缩,这就要涉及到一些比较复杂的压缩算法。后续章节中我们将针对特殊的文件格式如何转换为BMP格式的文件问题作专门的论述,经过转换,我们就可以利用得到的未压缩的BMP文件格式进行后续处理。对于JPEG、GIF等格式,由于涉及到压缩算法,这要求读者掌握一定的信息论方面的知识,如果展开的话,可以写一本书,限于篇幅原因,我们只作一般性的讲解,有兴趣的朋友可以参考相关书籍资料。

一、BMP文件结构

1 BMP文件组成

BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。文件头主要包含文件的大小、文件类型、图像数据偏离文件头的长度等信息;位图信息头包含图象的尺寸信息、图像用几个比特数值来表示一个像素、图像是否压缩、图像所用的颜色数等信息。颜色信息包含图像所用到的颜色表,显示图像时需用到这个颜色表来生成调色板,但如果图像为真彩色,既图像的每个像素用24个比特来表示,文件中就没有这一块信息,也就不需要 *** 作调色板。文件中的数据块表示图像的相应的像素值,需要注意的是:图像的像素值在文件中的存放顺序为从左到右,从下到上,也就是说,在BMP文件中首先存放的是图像的最后一行像素,最后才存储图像的第一行像素,但对与同一行的像素,则是按照先左边后右边的的顺序存储的;另外一个需要读者朋友关注的细节是:文件存储图像的每一行像素值时,如果存储该行像素值所占的字节数为4的倍数,则正常存储,否则,需要在后端补0,凑足4的倍数。

2 BMP文件头

BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。其结构定义如下:

typedef struct tagBITMAPFILEHEADER

{

WORD bfType; // 位图文件的类型,必须为"BM"

DWORD bfSize; // 位图文件的大小,以字节为单位

WORD bfReserved1; // 位图文件保留字,必须为0

WORD bfReserved2; // 位图文件保留字,必须为0

DWORD bfOffBits; // 位图数据的起始位置,以相对于位图文件头的偏移量表示,以字节为单位

} BITMAPFILEHEADER;该结构占据14个字节。

3 位图信息头

BMP位图信息头数据用于说明位图的尺寸等信息。其结构如下:

typedef struct tagBITMAPINFOHEADER{

DWORD biSize; // 本结构所占用字节数

LONG biWidth; // 位图的宽度,以像素为单位

LONG biHeight; // 位图的高度,以像素为单位

WORD biPlanes; // 目标设备的平面数不清,必须为1

WORD biBitCount// 每个像素所需的位数,必须是1(双色), 4(16色),8(256色)或24(真彩色)之一

DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一

DWORD biSizeImage; // 位图的大小,以字节为单位

LONG biXPelsPerMeter; // 位图水平分辨率,每米像素数

LONG biYPelsPerMeter; // 位图垂直分辨率,每米像素数

DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数

DWORD biClrImportant;// 位图显示过程中重要的颜色数

} BITMAPINFOHEADER;该结构占据40个字节。

注意:对于BMP文件格式,在处理单色图像和真彩色图像的时候,无论图象数据多么庞大,都不对图象数据进行任何压缩处理,一般情况下,如果位图采用压缩格式,那么16色图像采用RLE4压缩算法,256色图像采用RLE8压缩算法。

4 颜色表

颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:

typedef struct tagRGBQUAD {

BYTErgbBlue;// 蓝色的亮度(值范围为0-255)

BYTErgbGreen; // 绿色的亮度(值范围为0-255)

BYTErgbRed; // 红色的亮度(值范围为0-255)

BYTErgbReserved;// 保留,必须为0

} RGBQUAD;

颜色表中RGBQUAD结构数据的个数由BITMAPINFOHEADER 中的biBitCount项来确定,当biBitCount=1,4,8时,分别有2,16,256个颜色表项,当biBitCount=24时,图像为真彩色,图像中每个像素的颜色用三个字节表示,分别对应R、G、B值,图像文件没有颜色表项。位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:

typedef struct tagBITMAPINFO {

BITMAPINFOHEADER bmiHeader; // 位图信息头

RGBQUAD bmiColors[1]; // 颜色表

} BITMAPINFO;

注意:RGBQUAD数据结构中,增加了一个保留字段rgbReserved,它不代表任何颜色,必须取固定的值为"0",同时, RGBQUAD结构中定义的颜色值中,红色、绿色和蓝色的排列顺序与一般真彩色图像文件的颜色数据排列顺序恰好相反,既:若某个位图中的一个像素点的颜色的描述为"00,00,ff,00",则表示该点为红色,而不是蓝色。

5 位图数据

位图数据记录了位图的每一个像素值或该对应像素的颜色表的索引值,图像记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。这种格式我们又称为Bottom_Up位图,当然与之相对的还有Up_Down形式的位图,它的记录顺序是从上到下的,对于这种形式的位图,也不存在压缩形式。位图的一个像素值所占的字节数:当biBitCount=1时,8个像素占1个字节;当biBitCount=4时,2个像素占1个字节;当 biBitCount=8时,1个像素占1个字节;当biBitCount=24时,1个像素占3个字节,此时图像为真彩色图像。当图像不是为真彩色时,图像文件中包含颜色表,位图的数据表示对应像素点在颜色表中相应的索引值,当为真彩色时,每一个像素用三个字节表示图像相应像素点彩色值,每个字节分别对应R、G、B分量的值,这时候图像文件中没有颜色表。上面我已经讲过了,Windows规定图像文件中一个扫描行所占的字节数必须是4的倍数(即以字为单位),不足的以0填充,图像文件中一个扫描行所占的字节数计算方法:

DataSizePerLine= (biWidth biBitCount+31)/8;// 一个扫描行所占的字节数

位图数据的大小按下式计算(不压缩情况下):

DataSize= DataSizePerLine biHeight。

上述是BMP文件格式的说明,搞清楚了以上的结构,就可以正确的 *** 作图像文件,对它进行读或写 *** 作了。

。。。。。。

使用opencv的库吧,安装很简单,处理图像的功能很强大

#include "cvh"

#include "highguih"

int main( int argc, char argv )

{

IplImage pImg; //声明IplImage指针

//载入图像

if( argc == 2 &&

(pImg = cvLoadImage(“XXXbmp”, 1)) != 0 )//这里bmp要放到工程文件夹下,否则写绝对路径,取像素值请用:pImgptr<Vec3b>(i)[j]

{

cvNamedWindow( "Image", 1 );//创建窗口

cvShowImage( "Image", pImg );//显示图像

cvWaitKey(0); //等待按键

cvDestroyWindow( "Image" );//销毁窗口

cvReleaseImage( &pImg ); //释放图像

return 0;

}

return -1;

}

以上就是关于用C语言读取16位bmp图片的每个像素的信息~全部的内容,包括:用C语言读取16位bmp图片的每个像素的信息~、已有一个bmp图片用标准c获取其任意点(给定坐标)像素信息、如何提取BMP图像数据的提取等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9780704.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-01
下一篇2023-05-01

发表评论

登录后才能评论

评论列表(0条)

    保存