!关于用C语言读取24位BMP图的有关问题
高手请进!关于用C语言读取24位BMP图的问题
是这样的,我想把一张24位的bmp的像素分别存到3个一维数组R[ ],G[ ],B[ ]里,但是输出某一行的R,G,B后发现有错位,后来百度了一下,原因是BMP存放时遵循了对齐原则,因为长度不是4的倍数所以进行了比特填充,而我没有注意到这个问题,错把一些填充位也读到了RGB数组里,导致了错位。搞了一天都不知道怎么跳过填充位,求高手帮忙解答。
现在已经得到了该位图数据的宽度和高度:bmpWidth与bmpHeight
这个是小弟的代码,求帮忙
void separate(unsigned char* imgBuf, int* R,int* G,int* B,int lineByte) //imgBuf是读取图像数据的指针, lineByte是每行像素所占字节数
{
int i, j;
//int k = 0;
for (i = 0; i < bmpHeight; i++)
{
for (j = 0; j < bmpWidth; j++)
{
R[i*bmpWidth + j] = *(imgBuf + i*lineByte + j * 3 + 2);
G[i*bmpWidth + j] = *(imgBuf + i*lineByte + j * 3 + 1);
B[i*bmpWidth + j] = *(imgBuf + i*lineByte + j * 3 + 0);
//k++;
}
}
//printf("\nthe value of k is %d\n", k);
}
------解决思路----------------------
------解决思路----------------------
没有填充位!!!
BITMAPINFOHEADER指定了biBitCount
如果为8,黑白图,r[i]=b[i]=g[i]=bmp[i]
如果为16,bmp[i]=(r[i]&0x1f<<10)
------解决思路----------------------
(g[i]&0x1f<<5)
------解决思路----------------------
b[i]&0x1f
如果为24,bmp[i]=(r[i]<<16)
------解决思路----------------------
(g[i]<<8)
------解决思路----------------------
b[i]
如果为32,带通道alpha,bmp[i]=( alpha[i]<<24)(r[i]<<16)
------解决思路----------------------
(g[i]<<8)
------解决思路----------------------
b[i]
------解决思路----------------------
pad就是跳过填充的部分, 你的lineByte有没有算正确对齐到4字节, 比如宽度为10, 那么linebyte应为32不是30
lineByte =(bmpWidth*3+3)&~3
------解决思路----------------------
仅供参考:
是这样的,我想把一张24位的bmp的像素分别存到3个一维数组R[ ],G[ ],B[ ]里,但是输出某一行的R,G,B后发现有错位,后来百度了一下,原因是BMP存放时遵循了对齐原则,因为长度不是4的倍数所以进行了比特填充,而我没有注意到这个问题,错把一些填充位也读到了RGB数组里,导致了错位。搞了一天都不知道怎么跳过填充位,求高手帮忙解答。
现在已经得到了该位图数据的宽度和高度:bmpWidth与bmpHeight
这个是小弟的代码,求帮忙
void separate(unsigned char* imgBuf, int* R,int* G,int* B,int lineByte) //imgBuf是读取图像数据的指针, lineByte是每行像素所占字节数
{
int i, j;
//int k = 0;
for (i = 0; i < bmpHeight; i++)
{
for (j = 0; j < bmpWidth; j++)
{
R[i*bmpWidth + j] = *(imgBuf + i*lineByte + j * 3 + 2);
G[i*bmpWidth + j] = *(imgBuf + i*lineByte + j * 3 + 1);
B[i*bmpWidth + j] = *(imgBuf + i*lineByte + j * 3 + 0);
//k++;
}
}
//printf("\nthe value of k is %d\n", k);
}
------解决思路----------------------
int *rgb[]={B,G,R};
int pad =lineByte - bmpWidth *3;
unsigned char* imgBufEnd =imgBuf +(bmpHeight-1)*lineByte;
while(imgBuf<imgBufEnd){
for(int i=0;i<bmpWidth;i++)
for(int j=0;j<3;j++)
*rgb[j]++ =*imgBuf++;
imgBuf +=pad;
}
------解决思路----------------------
没有填充位!!!
BITMAPINFOHEADER指定了biBitCount
如果为8,黑白图,r[i]=b[i]=g[i]=bmp[i]
如果为16,bmp[i]=(r[i]&0x1f<<10)
------解决思路----------------------
(g[i]&0x1f<<5)
------解决思路----------------------
b[i]&0x1f
如果为24,bmp[i]=(r[i]<<16)
------解决思路----------------------
(g[i]<<8)
------解决思路----------------------
b[i]
如果为32,带通道alpha,bmp[i]=( alpha[i]<<24)(r[i]<<16)
------解决思路----------------------
(g[i]<<8)
------解决思路----------------------
b[i]
------解决思路----------------------
pad就是跳过填充的部分, 你的lineByte有没有算正确对齐到4字节, 比如宽度为10, 那么linebyte应为32不是30
lineByte =(bmpWidth*3+3)&~3
------解决思路----------------------
仅供参考:
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")
using namespace std;
using namespace Gdiplus;
int main() {
GdiplusStartupInput gdiplusstartupinput;
ULONG_PTR gdiplustoken;
GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);
wstring infilename(L"1.jpg");
string outfilename("color.txt");
Bitmap* bmp = new Bitmap(infilename.c_str());
UINT height = bmp->GetHeight();
UINT width = bmp->GetWidth();
cout << "width " << width << ", height " << height << endl;
Color color;
ofstream fout(outfilename.c_str());
for (UINT y = 0; y < height; y++)
for (UINT x = 0; x < width ; x++) {
bmp->GetPixel(x, y, &color);
fout << x << "," << y << ";"
<< (int)color.GetRed() << ","
<< (int)color.GetGreen() << ","
<< (int)color.GetBlue() << endl;
}
fout.close();
delete bmp;
GdiplusShutdown(gdiplustoken);
return 0;
}