【发布时间】:2014-07-10 09:18:40
【问题描述】:
我目前正在做我的第一个 C++ 编程任务,我的目标是仅使用基本 IO 标头来缩放位图图像。
我使用http://en.wikipedia.org/wiki/BMP_file_format#DIB_header_.28bitmap_information_header.29 作为查找标头信息的参考指南。
我的问题是创建一种算法来根据添加单个像素来放大图像。 我制作了一系列带有注释的 for 循环(它们使用标题信息来确定它们需要运行多少),但我不知道接下来在操作实际像素方面要做什么,这就是我需要帮助
当我运行程序时,会创建一个新的 BMP 文件(称为 Image2),但它已损坏且大小为 1kb(很可能是因为程序未完成)。
这是代码,如果有人也可以就此批评我或让我知道任何不良做法以避免我目前正在做的事情,我将不胜感激。
int main()
{
FILE* pFile = NULL;
FILE* pFile2 = NULL;
//Open Image.bmp (In directory) as read binary
pFile = fopen("Image.bmp", "rb");
//Scan through the program and set to send.
fseek (pFile, 0, SEEK_END);
//Read file data
int fileData = ftell (pFile);
//set back to start of char pointer
rewind (pFile);
//Create a Char Filebuffer, this will be where data is viewed.
char* FileBuffer = new char[fileData];
//Read pFile into Filebuffer
fread(FileBuffer, fileData, 1, pFile);
//Read out BMP Header Data and Cast to Int
int ImageSize = *(int*)&FileBuffer[2];
int ImageOffset = *(int*)&FileBuffer[10]; //ImageOffset = Image Header Size
int ImageHeight = *(int*)&FileBuffer[18];
int ImageWidth = *(int*)&FileBuffer[20];
int BitsPerPixel = *(int*)&FileBuffer[24];
//Create a New Buffer that starts off at Pixel Data
char* NewFileBuffer = FileBuffer + ImageOffset;
std::cout << "Enter the amount of times you want to scale the image by." << std::endl;
std::cin >> ScaleValue;
std::cout << "\n";
//Create New Image row/height/size variables
int RowSizeOld = (BitsPerPixel * ImageWidth +31)/32 * 4;
int RowSizeNew = (BitsPerPixel *(ImageWidth * ScaleValue) + 31) / 32 * 4;
int NewImageSize = ImageOffset + (RowSizeNew * (ScaleValue * ImageHeight) );
int NewImageHeight = ImageHeight * ScaleValue;
int NewImageWidth = ImageWidth * ScaleValue;
// These ints define the colour values for RGB and Padding
int r = ImageOffset + 1;
int g = ImageOffset + 2;
int b= ImageOffset + 3;
int p = ImageOffset + 4;
//Rescale Image here, for (Newfile buffer [0])
// This for loop figures out how many times the newHeight variable must iterate
for (int newHeight = 0 ; newHeight < NewImageHeight ; newHeight++)
{
//This line scales up the amount of rows in terms of scale value
for(int doubleLine = 0 ; doubleLine < ScaleValue ; doubleLine++)
{
//This for loop then figures out the width of the new image in pixels as an int value
for (int newWidth = 0 ; newWidth < NewImageWidth ; newWidth++)
{
//This loop figures out how many times you need to increase the pixel density (for each pixel)
for (int pixelMultiplier = 0 ; pixelMultiplier < ScaleValue ; pixelMultiplier++)
{
//Move pixel data around to scale image (This is where I'm having trouble)
}
}
}
}
//Create a new File pointer, add image name + bmp string
FILE* pFile2;
pFile2 = fopen("Image2.bmp", "wb");
fwrite(NewFileBuffer, (NewImageSize + ImageOffset), sizeof(char) , pFile2);
return 0;
}
这是我在 SE 上的第一篇文章,如果代码格式有点粗或问题难以理解,我深表歉意(我已通读论坛并修改了我的代码以使其更具可读性)
【问题讨论】:
-
您是否在调试器中检查了
ImageSize、ImageOffset等的值,或者在阅读后添加了std::cout << "ImageSize " << ImageSize << ... << '\n';以确保它们正确无误?例如,您可能遇到字节顺序问题。您的代码也会在某些系统上崩溃,因为您正在取消引用可能不在对齐地址的int*s,尽管在 x86 上这没关系(但速度较慢)。使用fclose()也是一个好主意。 -
另外,您正在覆盖已将原始图像读入的缓冲区:首先,它不足以缩放> = 1,其次您需要在缩放时继续查看它计算输出值。您也没有将更新的标头信息写入输出文件。
-
我使用了您的建议并检查了值,结果发现我一直在读取 BMP 标头中的错误值,感谢您的好消息!我还是个新手,我的讲师是取消引用 int* 值的人,但我会查找对齐值和字节顺序问题是什么。