我仍然是C++的noob,我目前正在嘗試創建一個程序,它將256色位圖手動加載到數組中,並打印出每個像素的值CONSOL。看來這些價值觀,大多數時候,是不正確的。當從24位位圖讀取像素時出現奇怪的值
我的其他輸出(例如信息頭內的值)都很好,除了biSizeImage
,它是5字節。這不應該是25字節嗎?
出於測試目的,我拍了兩張5 x 5的圖像。其中一個是全黑的,另一個是全白的。
我希望爲黑色,類似這樣的輸出:
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
但我得到:
0 0 0 0 0
0 0 0 0 0
3452816845 3452816845 3452816845 3452816845 3452816845
3452816845 3452816845 3452816845 3452816845 3452816845
3452816845 3452816845 3452816845 3452816845 3452816845
隨着全白畫面我的結果是更奇怪:
4294967295 255 4294967295 255 4294967295
255 4294967295 255 4294967295 255
3452816845 3452816845 3452816845 3452816845 3452816845
3452816845 3452816845 3452816845 3452816845 3452816845
3452816845 3452816845 3452816845 3452816845 3452816845
下面你可以看到我現在的代碼:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
using namespace std;
#pragma pack(push,1)
typedef struct tagBITMAPFILEHEADER {
unsigned short bfType; // Specifies the type of file. This member must be BM. (0x4D42)
unsigned int bfSize; // Specifies the size of the file, in bytes.
short bfReserved1; // Reserved; must be set to zero.
short bfReserved2; // Reserved; must be set to zero.
unsigned int bfOffBits; // Specifies the byte offset from the BITMAPFILEHEADER structure to the actual bitmap data in the file.
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER {
unsigned int biSize; // Specifies the number of bytes required by the BITMAPINFOHEADER structure.
int biWidth; // Specifies the width of the bitmap, in pixels.
int biHeight; // Specifies the height of the bitmap, in pixels.
unsigned short biPlanes; // Specifies the number of planes for the target device. This member must be set to 1.
unsigned short biBitCount; // Specifies the number of bits per pixel. This value must be 1,4, 8, or 24.
unsigned int biCompression; // Specifies the type of compression for a compressed bitmap. Itcan be one of the following values: BI_RGB, BI_RLE8, BI_RLE4
unsigned int biSizeImage; // Specifies the size, in bytes, of the image. It is valid to set this member to zero if the bitmap is in the BI_RGB format.
int biXPelsPerMeter; // Specifies the horizontal resolution, in pixels per meter, of the target device for the bitmap.
int biYPelsPerMeter; // Specifies the vertical resolution, in pixels per meter, of the target device for the bitmap.
unsigned int biClrUsed; // Specifies the number of color indexes in the color table actually used by the bitmap.
unsigned int biClrImportant; // Specifies the number of color indexes that are considered important for displaying the bitmap. If this value is zero, all colors are important.
} BITMAPINFOHEADER;
typedef struct tagRGBPIXEL{
unsigned char b;
unsigned char g;
unsigned char r;
} rgbPIXEL;
#pragma pack(pop)
typedef struct tagBITMAP{
BITMAPFILEHEADER FILEHEADER;
BITMAPINFOHEADER INFOHEADER;
rgbPIXEL* IMAGEDATA;
}BITMAP;
void main(){
string sImageLocation = "C:/BMP.bmp";
BITMAP bmpImage;
FILE* fbmpImage = NULL;
unsigned int ImagePixelAmount = 0;
bool bImageLoaded = false;
do{
//Open the image file
fopen_s(&fbmpImage, sImageLocation.c_str(), "rb");
//Check whether the image could be loaded successfully or not
if(fbmpImage == NULL){
cout << "Loading the image file failed!" << " " << endl;
}
if(fbmpImage != NULL){
cout << "Loaded the image file successfully!" << endl;
bImageLoaded = true;
}
cout << endl;
cout << endl;
cout << endl;
//Read the BITMAP FILE HEADER
fseek(fbmpImage, 0, SEEK_SET);
fread(&bmpImage.FILEHEADER, sizeof(BITMAPFILEHEADER), 1, fbmpImage);
//Check if the image is a valid bitmap file
if(bmpImage.FILEHEADER.bfType != 19778){
bImageLoaded = false;
cout << "Image is not a valid Bitmap file!" << endl;
fclose(fbmpImage);
}
}while(bImageLoaded = false);
//Show the information of the BITMAP FILE HEADER in the consol
cout << "Bitmap File Header Data Values:" << endl;
cout << endl;
cout << "Image Type: " << bmpImage.FILEHEADER.bfType << endl;
cout << "Image Size: " << bmpImage.FILEHEADER.bfSize << " Bytes" << endl;
cout << "Reserved: " << bmpImage.FILEHEADER.bfReserved1 << endl;
cout << "Reserved: " << bmpImage.FILEHEADER.bfReserved2 << endl;
cout << "Byte Offset: " << bmpImage.FILEHEADER.bfOffBits << endl;
cout << endl;
cout << endl;
cout << endl;
//Read the BITMAP INFO HEADER
fread(&bmpImage.INFOHEADER, sizeof(BITMAPINFOHEADER), 1, fbmpImage);
cout << "Bitmap Info Header Data Values: " << endl;
cout << endl;
cout << "Size of Bitmap Info Header: " << bmpImage.INFOHEADER.biSize << " Bytes" << endl;
cout << "Width of Bitmap: " << bmpImage.INFOHEADER.biWidth << " Pixel" << endl;
cout << "Height of Bitmap: " << bmpImage.INFOHEADER.biHeight << " Pixel" << endl;
cout << "Size of Image Data: " << bmpImage.INFOHEADER.biHeight << " Bytes" << endl;
cout << "Bit Count: " << bmpImage.INFOHEADER.biBitCount << " Bits Per Pixel" << endl;
cout << "Amount of color indexes: " << bmpImage.INFOHEADER.biClrUsed << endl;
cout << "Compression: " << bmpImage.INFOHEADER.biCompression << endl;
cout << endl;
cout << endl;
cout << endl;
ImagePixelAmount = bmpImage.INFOHEADER.biHeight * bmpImage.INFOHEADER.biWidth;
//Create space in memory and read in pixel data from the image
bmpImage.IMAGEDATA = (rgbPIXEL*)malloc(sizeof(rgbPIXEL) * ImagePixelAmount);
cout << "Memory for image created" << endl;
fseek(fbmpImage, bmpImage.FILEHEADER.bfOffBits, SEEK_SET);
fread(bmpImage.IMAGEDATA, ImagePixelAmount * sizeof(rgbPIXEL), 1, fbmpImage);
fclose(fbmpImage);
//Show the pixel data in the consol in numbers instead of ASCII-symbols
for(int y =0; y < bmpImage.INFOHEADER.biHeight; y++){
for(int x = 0; x < bmpImage.INFOHEADER.biWidth; x++){
cout << "Red: " <<(unsigned int) bmpImage.IMAGEDATA[y * bmpImage.INFOHEADER.biWidth + x].r << " ";
cout << "Green: " <<(unsigned int) bmpImage.IMAGEDATA[y * bmpImage.INFOHEADER.biWidth + x].g << " ";
cout << "Blue: " <<(unsigned int) bmpImage.IMAGEDATA[y * bmpImage.INFOHEADER.biWidth + x].b << " ";
}
cout << endl;
}
cout << endl;
cout << endl;
cout << endl;
cout << "Press any key to quit the programm" << endl;
_getch();
return;
}
更新:
根據Hans Passant,我將我的代碼更改爲加載24位位圖。使用紅色位圖,我會假設每個像素的打印值是red = 255, green = 0 and blue = 0
。然而,我收到的每個像素的實際值是red = 237, green = 28 and blue = 36
。與其他圖像我有同樣的麻煩。
是否bmpImage。INFOHEADER.biSizeImage == ImagePixelAmount * sizeof(int); ? –
對古代圖像格式的不懈追求是不可阻擋的,8bpp只在20年前變得至關重要。你的malloc()調用是錯誤的,8bpp圖像中的一個像素是一個字節,而不是'unsigned int'。而一張8bpp圖片有一張顏色表。 –
謝謝你的答案! @PierreEmmanuelLallemant:可悲的是,情況並非如此。 – StirriX