读取位图文件
Reading Bitmap file
我尝试读取位图文件。这是我的程序:
#include<iostream>
#include<fstream>
#include <string>
#include<windows.h>
using namespace std;
#pragma pack(1)
struct header
{
char header[2];
int32_t filesize;
int16_t reser;
int16_t reser1;
int32_t dataoffset;
};
struct infoheader
{
int32_t headersize;
int32_t width;
int32_t height;
int16_t plans;
int16_t bpp;
int32_t compression;
int32_t datasize;
int32_t re;
int32_t ve;
int32_t color;
int32_t importantcolor;
};
struct PIxel
{
unsigned char G;
unsigned char B;
unsigned char R;
};
int main()
{
header h;
infoheader info;
PIxel *p;
ifstream file("bmp2.bmp", ios::binary);
if (file.is_open())
{
cout << "true" << endl;
file.read((char*)&h, sizeof(h));
file.read((char*)&info, sizeof(info));
cout << info.width << " " << info.height << " " << h.filesize << " " << info.bpp << endl;
int pa = info.width % 4;
int size = info.width * info.height * (info.bpp / 3) + pa * info.height;
char* arr = new char[size];
file.read(arr, size);
char* temp = arr;
int sizep = info.height * info.width;
p = new PIxel[sizep];
for (int i = 0; i < info.height; i++)
{
for (int j = 0; j < info.width; j++)
{
p[i * info.height + j].B = *(temp++);
p[i * info.height + j].G = *(temp++);
p[i * info.height + j].R = *(temp++);
//p = p + 3;
}
p += pa;
}
HWND consoleWindow = GetConsoleWindow();
HDC hdc = GetDC(consoleWindow);
for (int i = 0; i < info.height; i++)
{
for (int j = 0; j < info.width; j++)
{
PIxel m = p[i * info.height + j];
SetPixel(hdc, i, j, RGB(m.R, m.G, m.B));
}
}
ReleaseDC(consoleWindow, hdc);
}
}
它有效,但我的控制台上的图像不正确...
你能帮我解决一下吗?
我相信您对错误的指针进行了填充调整。填充存在于源图像上。您不希望它出现在目标图像上。您正在使用 p += pa;
计算填充,您应该将此行替换为 temp += pa
以计算源图像的填充。
int size = info.width * info.height * (info.bpp / 3) + pa * info.height;
以上尺寸计算不正确。每像素位数应除以 8。for 循环中的索引也是错误的。它最终乘以高度 x 高度。
此外,SetPixel(... i, j ...)
应更改为 SetPixel(... j, i ...)
,因为 i
在您的情况下指的是 y 轴。
如前一个答案所述,填充也必须修复。
请注意,您可以使用 LoadImage
和其他 Windows GDI 函数来打开和绘制位图。
int size = (info.width * (info.bpp / 8) + pa) * info.height;
...
for(int i = info.height - 1; i >= 0; i--)
{
for(int j = 0; j < info.width; j++)
{
int index = i * (info.width) + j;
p[index].B = *(temp++);
p[index].G = *(temp++);
p[index].R = *(temp++);
}
temp += pa;
}
for(int i = 0; i < info.height; i++)
{
for(int j = 0; j < info.width; j++)
{
int index = i * (info.width) + j;
PIxel m = p[index];
SetPixel(hdc, j, i, RGB(m.R, m.G, m.B));
}
}
我尝试读取位图文件。这是我的程序:
#include<iostream>
#include<fstream>
#include <string>
#include<windows.h>
using namespace std;
#pragma pack(1)
struct header
{
char header[2];
int32_t filesize;
int16_t reser;
int16_t reser1;
int32_t dataoffset;
};
struct infoheader
{
int32_t headersize;
int32_t width;
int32_t height;
int16_t plans;
int16_t bpp;
int32_t compression;
int32_t datasize;
int32_t re;
int32_t ve;
int32_t color;
int32_t importantcolor;
};
struct PIxel
{
unsigned char G;
unsigned char B;
unsigned char R;
};
int main()
{
header h;
infoheader info;
PIxel *p;
ifstream file("bmp2.bmp", ios::binary);
if (file.is_open())
{
cout << "true" << endl;
file.read((char*)&h, sizeof(h));
file.read((char*)&info, sizeof(info));
cout << info.width << " " << info.height << " " << h.filesize << " " << info.bpp << endl;
int pa = info.width % 4;
int size = info.width * info.height * (info.bpp / 3) + pa * info.height;
char* arr = new char[size];
file.read(arr, size);
char* temp = arr;
int sizep = info.height * info.width;
p = new PIxel[sizep];
for (int i = 0; i < info.height; i++)
{
for (int j = 0; j < info.width; j++)
{
p[i * info.height + j].B = *(temp++);
p[i * info.height + j].G = *(temp++);
p[i * info.height + j].R = *(temp++);
//p = p + 3;
}
p += pa;
}
HWND consoleWindow = GetConsoleWindow();
HDC hdc = GetDC(consoleWindow);
for (int i = 0; i < info.height; i++)
{
for (int j = 0; j < info.width; j++)
{
PIxel m = p[i * info.height + j];
SetPixel(hdc, i, j, RGB(m.R, m.G, m.B));
}
}
ReleaseDC(consoleWindow, hdc);
}
}
它有效,但我的控制台上的图像不正确...
你能帮我解决一下吗?
我相信您对错误的指针进行了填充调整。填充存在于源图像上。您不希望它出现在目标图像上。您正在使用 p += pa;
计算填充,您应该将此行替换为 temp += pa
以计算源图像的填充。
int size = info.width * info.height * (info.bpp / 3) + pa * info.height;
以上尺寸计算不正确。每像素位数应除以 8。for 循环中的索引也是错误的。它最终乘以高度 x 高度。
此外,SetPixel(... i, j ...)
应更改为 SetPixel(... j, i ...)
,因为 i
在您的情况下指的是 y 轴。
如前一个答案所述,填充也必须修复。
请注意,您可以使用 LoadImage
和其他 Windows GDI 函数来打开和绘制位图。
int size = (info.width * (info.bpp / 8) + pa) * info.height;
...
for(int i = info.height - 1; i >= 0; i--)
{
for(int j = 0; j < info.width; j++)
{
int index = i * (info.width) + j;
p[index].B = *(temp++);
p[index].G = *(temp++);
p[index].R = *(temp++);
}
temp += pa;
}
for(int i = 0; i < info.height; i++)
{
for(int j = 0; j < info.width; j++)
{
int index = i * (info.width) + j;
PIxel m = p[index];
SetPixel(hdc, j, i, RGB(m.R, m.G, m.B));
}
}