C 将位图文件读入结构
我想将位图文件读入结构并像制作镜像效果一样对其进行操作,但我无法理解应该创建哪种结构才能读入它C 将位图文件读入结构,c,bitmap,structure,bitmapimage,C,Bitmap,Structure,Bitmapimage,我想将位图文件读入结构并像制作镜像效果一样对其进行操作,但我无法理解应该创建哪种结构才能读入它 感谢您的帮助。»这是手动加载.BMP文件的方式 位图文件格式: 位图文件头 位图信息头 调色板数据 位图数据 代码部分也是如此。这是我们需要创建的用于保存位图文件头的结构 #pragma pack(push, 1) typedef struct tagBITMAPFILEHEADER { WORD bfType; //specifies the file type DWORD
感谢您的帮助。»这是手动加载.BMP文件的方式 位图文件格式:
- 位图文件头
- 位图信息头
- 调色板数据
- 位图数据
#pragma pack(push, 1)
typedef struct tagBITMAPFILEHEADER
{
WORD bfType; //specifies the file type
DWORD bfSize; //specifies the size in bytes of the bitmap file
WORD bfReserved1; //reserved; must be 0
WORD bfReserved2; //reserved; must be 0
DWORD bfOffBits; //specifies the offset in bytes from the bitmapfileheader to the bitmap bits
}BITMAPFILEHEADER;
#pragma pack(pop)
bftype字段检查您是否正在加载.BMP文件,如果是,则该字段应为0x4D42
现在我们需要创建BitMapInfo头结构。这保存有关位图的信息
#pragma pack(push, 1)
typedef struct tagBITMAPINFOHEADER
{
DWORD biSize; //specifies the number of bytes required by the struct
LONG biWidth; //specifies width in pixels
LONG biHeight; //specifies height in pixels
WORD biPlanes; //specifies the number of color planes, must be 1
WORD biBitCount; //specifies the number of bits per pixel
DWORD biCompression; //specifies the type of compression
DWORD biSizeImage; //size of image in bytes
LONG biXPelsPerMeter; //number of pixels per meter in x axis
LONG biYPelsPerMeter; //number of pixels per meter in y axis
DWORD biClrUsed; //number of colors used by the bitmap
DWORD biClrImportant; //number of colors that are important
}BITMAPINFOHEADER;
#pragma pack(pop)
unsigned char *LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
{
FILE *filePtr; //our file pointer
BITMAPFILEHEADER bitmapFileHeader; //our bitmap file header
unsigned char *bitmapImage; //store image data
int imageIdx=0; //image index counter
unsigned char tempRGB; //our swap variable
//open file in read binary mode
filePtr = fopen(filename,"rb");
if (filePtr == NULL)
return NULL;
//read the bitmap file header
fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER),1,filePtr);
//verify that this is a .BMP file by checking bitmap id
if (bitmapFileHeader.bfType !=0x4D42)
{
fclose(filePtr);
return NULL;
}
//read the bitmap info header
fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER),1,filePtr);
//move file pointer to the beginning of bitmap data
fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);
//allocate enough memory for the bitmap image data
bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);
//verify memory allocation
if (!bitmapImage)
{
free(bitmapImage);
fclose(filePtr);
return NULL;
}
//read in the bitmap image data
fread(bitmapImage,bitmapInfoHeader->biSizeImage,1,filePtr);
//make sure bitmap image data was read
if (bitmapImage == NULL)
{
fclose(filePtr);
return NULL;
}
//swap the R and B values to get RGB (bitmap is BGR)
for (imageIdx = 0;imageIdx < bitmapInfoHeader->biSizeImage;imageIdx+=3)
{
tempRGB = bitmapImage[imageIdx];
bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
bitmapImage[imageIdx + 2] = tempRGB;
}
//close file and return bitmap image data
fclose(filePtr);
return bitmapImage;
}
现在开始加载位图
#pragma pack(push, 1)
typedef struct tagBITMAPINFOHEADER
{
DWORD biSize; //specifies the number of bytes required by the struct
LONG biWidth; //specifies width in pixels
LONG biHeight; //specifies height in pixels
WORD biPlanes; //specifies the number of color planes, must be 1
WORD biBitCount; //specifies the number of bits per pixel
DWORD biCompression; //specifies the type of compression
DWORD biSizeImage; //size of image in bytes
LONG biXPelsPerMeter; //number of pixels per meter in x axis
LONG biYPelsPerMeter; //number of pixels per meter in y axis
DWORD biClrUsed; //number of colors used by the bitmap
DWORD biClrImportant; //number of colors that are important
}BITMAPINFOHEADER;
#pragma pack(pop)
unsigned char *LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
{
FILE *filePtr; //our file pointer
BITMAPFILEHEADER bitmapFileHeader; //our bitmap file header
unsigned char *bitmapImage; //store image data
int imageIdx=0; //image index counter
unsigned char tempRGB; //our swap variable
//open file in read binary mode
filePtr = fopen(filename,"rb");
if (filePtr == NULL)
return NULL;
//read the bitmap file header
fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER),1,filePtr);
//verify that this is a .BMP file by checking bitmap id
if (bitmapFileHeader.bfType !=0x4D42)
{
fclose(filePtr);
return NULL;
}
//read the bitmap info header
fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER),1,filePtr);
//move file pointer to the beginning of bitmap data
fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);
//allocate enough memory for the bitmap image data
bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);
//verify memory allocation
if (!bitmapImage)
{
free(bitmapImage);
fclose(filePtr);
return NULL;
}
//read in the bitmap image data
fread(bitmapImage,bitmapInfoHeader->biSizeImage,1,filePtr);
//make sure bitmap image data was read
if (bitmapImage == NULL)
{
fclose(filePtr);
return NULL;
}
//swap the R and B values to get RGB (bitmap is BGR)
for (imageIdx = 0;imageIdx < bitmapInfoHeader->biSizeImage;imageIdx+=3)
{
tempRGB = bitmapImage[imageIdx];
bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
bitmapImage[imageIdx + 2] = tempRGB;
}
//close file and return bitmap image data
fclose(filePtr);
return bitmapImage;
}
稍后我将介绍如何写入.BMP,如何加载targa文件,以及如何显示它们。«
引自:(用户:BeholderOf)。(完成了一些小的修正)一个简短的工作示例
它将wav文件转换为bmp(很久以前,我玩得很开心)
代码:
#include <stdio.h>
#include <strings.h>
#include <sndfile.h>
#include <stdlib.h>
#include <math.h>
#define RATE 44100
typedef struct {
unsigned short type; /* Magic identifier */
unsigned int size; /* File size in bytes */
unsigned int reserved;
unsigned int offset; /* Offset to image data, bytes */
} HEADER;
typedef struct {
unsigned int size; /* Header size in bytes */
int width,height; /* Width and height of image */
unsigned short planes; /* Number of colour planes */
unsigned short bits; /* Bits per pixel */
unsigned int compression; /* Compression type */
unsigned int imagesize; /* Image size in bytes */
int xresolution,yresolution; /* Pixels per meter */
unsigned int ncolours; /* Number of colours */
unsigned int importantcolours; /* Important colours */
} INFOHEADER;
typedef struct {
unsigned char r,g,b,junk;
} COLOURINDEX;
int main(int argc, char *argv[]){
int i,j,rd;
int gotindex = 0;
unsigned char grey,r,g,b;
double ampl;
short _2byte[2];
HEADER header;
INFOHEADER infoheader;
COLOURINDEX colourindex[256];
FILE *fptr;
SNDFILE* sndfile = NULL;
SF_INFO sfinfo;
long rate = RATE;
void (*bmpread)();
void _eightbit(){
if(fread(&grey, sizeof(unsigned char), 1, fptr) != 1){
fprintf(stderr,"Image read failed\n");
exit(-1);
}
if (gotindex){
ampl = colourindex[grey].r * 64. +
colourindex[grey].g * 128.+
colourindex[grey].b * 64.;
} else {
ampl = grey * 256. - 32768.;
}
// printf("%.2f\n", ampl);
}
void _twentyfourbit(){
do{
if((rd = fread(&b, sizeof(unsigned char), 1, fptr)) != 1) break;
if((rd = fread(&g, sizeof(unsigned char), 1, fptr)) != 1) break;
if((rd = fread(&r, sizeof(unsigned char), 1, fptr)) != 1) break;
}while(0);
if(rd != 1){
fprintf(stderr,"Image read failed\n");
exit(-1);
}
ampl = r * 64. + g * 128. + b * 64. - 32768.;
// printf("%.2f\n", ampl);
}
if (argc < 3){
printf("Usage: %s <input.bmp> <output.wav> [samplerate]\n", argv[0]);
printf("For example:\n\t%s pict.bmp sample.wav 44100 2\n", argv[0]);
exit(0);
}
printf("Input file: %s\n", argv[1]);
printf("Output file: %s\n", argv[2]);
if(argc > 3) rate = atoi(argv[3]);
if(rate < 4000) rate = 4000;
//if(argc > 4) channels = atoi(argv[4]);
sfinfo.samplerate = rate;
sfinfo.channels = 2;
sfinfo.format = SF_FORMAT_WAV|SF_FORMAT_PCM_16;
if((fptr = fopen(argv[1],"r")) == NULL) {
fprintf(stderr,"Unable to open BMP file \"%s\"\n",argv[1]);
exit(-1);
}
/* Read and check BMP header */
if(fread(&header.type, 2, 1, fptr) != 1){
fprintf(stderr, "Failed to read BMP header\n");
exit(-1);
}
if(header.type != 'M'*256+'B'){
fprintf(stderr, "File is not bmp type\n");
exit(-1);
}
do{
if((rd = fread(&header.size, 4, 1, fptr)) != 1) break;
printf("File size: %d bytes\n", header.size);
if((rd = fread(&header.reserved, 4, 1, fptr)) != 1) break;
if((rd = fread(&header.offset, 4, 1, fptr)) != 1) break;
printf("Offset to image data is %d bytes\n", header.offset);
}while(0);
if(rd =! 1){
fprintf(stderr, "Error reading file\n");
exit(-1);
}
/* Read and check the information header */
if (fread(&infoheader, sizeof(INFOHEADER), 1, fptr) != 1) {
fprintf(stderr,"Failed to read BMP info header\n");
exit(-1);
}
printf("Image size = %d x %d\n", infoheader.width, infoheader.height);
printf("Number of colour planes is %d\n", infoheader.planes);
printf("Bits per pixel is %d\n", infoheader.bits);
printf("Compression type is %d\n", infoheader.compression);
printf("Number of colours is %d\n", infoheader.ncolours);
printf("Number of required colours is %d\n", infoheader.importantcolours);
/* Read the lookup table if there is one */
for (i=0; i<255; i++){
colourindex[i].r = rand() % 256;
colourindex[i].g = rand() % 256;
colourindex[i].b = rand() % 256;
colourindex[i].junk = rand() % 256;
}
if (infoheader.ncolours > 0) {
for (i=0; i<infoheader.ncolours; i++){
do{
if ((rd = fread(&colourindex[i].b, sizeof(unsigned char),1,fptr)) != 1)
break;
if ((rd = fread(&colourindex[i].g, sizeof(unsigned char),1,fptr)) != 1)
break;
if ((rd = fread(&colourindex[i].r, sizeof(unsigned char),1,fptr)) != 1)
break;
if ((rd = fread(&colourindex[i].junk, sizeof(unsigned char),1,fptr)) != 1)
break;
}while(0);
if(rd != 1){
fprintf(stderr,"Image read failed\n");
exit(-1);
}
printf("%3d\t%3d\t%3d\t%3d\n", i,
colourindex[i].r, colourindex[i].g, colourindex[i].b);
}
gotindex = 1;
}
if(infoheader.bits < 8){
printf("Too small image map depth (%d < 8)\n", infoheader.bits);
exit(-1);
}
/* Seek to the start of the image data */
fseek(fptr, header.offset, SEEK_SET);
printf("Creating 16bit WAV %liHz.\n", rate);
sndfile = sf_open(argv[2], SFM_WRITE, &sfinfo);
if(sndfile == NULL){
fprintf(stderr, "Cannot open output file!\n"); exit(-1);
}
bmpread = _eightbit;
if(infoheader.bits == 24)
bmpread = _twentyfourbit;
/* Read the image */
for (j=0;j<infoheader.height;j++) {
_2byte[1] = 32700;
for (i=0;i<infoheader.width;i++) {
bmpread();
_2byte[0] = (short)ampl;
sf_write_short(sndfile, _2byte, 2);
_2byte[1] = 0;
} // i
} // j
fclose(fptr);
sf_close(sndfile);
}
#包括
#包括
#包括
#包括
#包括
#定义费率44100
类型定义结构{
无符号短类型;/*魔术标识符*/
无符号整数大小;/*文件大小(字节)*/
无符号整数保留;
无符号整数偏移量;/*图像数据偏移量,字节*/
}收割台;
类型定义结构{
无符号整数大小;/*头大小(字节)*/
int width,height;/*图像的宽度和高度*/
无符号短平面;/*颜色平面的数量*/
无符号短位;/*位/像素*/
无符号整数压缩;/*压缩类型*/
无符号int-imagesize;/*图像大小(字节)*/
int x分辨率,y分辨率;/*每米像素*/
无符号整数n颜色;/*颜色数*/
无符号int importantColor;/*重要颜色*/
}信息头;
类型定义结构{
无符号字符r、g、b、junk;
}颜色指数;
int main(int argc,char*argv[]){
int i,j,rd;
int GOTDINDEX=0;
无符号字符灰色,r,g,b;
双安培;
短字节[2];
收割台;
信息头信息头;
色度指数色度指数[256];
文件*fptr;
SNDFILE*SNDFILE=NULL;
SF_信息sfinfo;
长期利率=利率;
无效(*bmpread)();
无效_eightbit(){
if(fread(&grey,sizeof(unsigned char),1,fptr)!=1){
fprintf(stderr,“图像读取失败\n”);
出口(-1);
}
如果(索引){
ampl=颜色指数[灰色].r*64+
颜色指数[灰色].g*128+
颜色指数[灰色].b*64。;
}否则{
ampl=灰色*256.-32768。;
}
//printf(“%.2f\n”,ampl);
}
void _二十四位(){
做{
如果((rd=fread(&b,sizeof(unsigned char),1,fptr))!=1)中断;
如果((rd=fread(&g,sizeof(unsigned char),1,fptr))!=1)中断;
如果((rd=fread(&r,sizeof(unsigned char),1,fptr))!=1)中断;
}而(0);
如果(rd!=1){
fprintf(stderr,“图像读取失败\n”);
出口(-1);
}
振幅=r*64.+g*128.+b*64.-32768。;
//printf(“%.2f\n”,ampl);
}
如果(argc<3){
printf(“用法:%s[samplerate]\n”,argv[0]);
printf(“例如:\n\t%s pict.bmp sample.wav 44100 2\n”,argv[0]);
出口(0);
}
printf(“输入文件:%s\n”,argv[1]);
printf(“输出文件:%s\n”,argv[2]);
如果(argc>3)速率=atoi(argv[3]);
如果(速率<4000)速率=4000;
//如果(argc>4)通道=atoi(argv[4]);
sfinfo.samplerate=速率;
sfinfo.channels=2;
sfinfo.format=SF_格式_WAV | SF_格式_PCM_16;
if((fptr=fopen(argv[1],“r”)==NULL){
fprintf(stderr,“无法打开BMP文件\%s\”\n”,argv[1]);
出口(-1);
}
/*读取并检查BMP标题*/
if(fread(&header.type,2,1,fptr)!=1){
fprintf(stderr,“读取BMP头失败\n”);
出口(-1);
}
if(header.type!='M'*256+'B'){
fprintf(stderr,“文件不是bmp类型\n”);
出口(-1);
}
做{
如果((rd=fread(&header.size,4,1,fptr))!=1)中断;
printf(“文件大小:%d字节\n”,header.size);
如果((rd=fread(&header.reserved,4,1,fptr))!=1)中断;
如果((rd=fread(&header.offset,4,1,fptr))!=1)中断;
printf(“到图像数据的偏移量为%d字节\n”,头.Offset);
}而(0);
如果(rd=!1){
fprintf(stderr,“读取文件时出错”);
出口(-1);
}
/*阅读并检查信息标题*/
if(fread(&infoheader,sizeof(infoheader),1,fptr)!=1){
fprintf(stderr,“读取BMP信息头失败\n”);
出口(-1);
}
printf(“图像大小=%d x%d\n”,infoheader.width,infoheader.height);
printf(“颜色平面的数量为%d\n”,infoheader.planes);
printf(“每像素位数为%d\n”,infoheader.Bits);
printf(“压缩类型为%d\n”,infoheader.Compression);
printf(“颜色数为%d\n”,infoheader.ncolours);
printf(“所需颜色的数量为%d\n”,infoheader.importantColor);
/*如果有查找表,请阅读该表*/
对于(i=0;i=0){
对于(i=0;i),要读取位图,您需要@ollo回答的结构,但还有一种更简单的方法
- 如果您使用的是windows,则只需在代码中添加
#include
,即可访问所有结构,而无需将它们写入单独的文件
- 如果您需要一些示例代码,那么我已经在bmp文件上实现了各种过滤器,如:
灰度
边缘检测
模糊
乌贼墨
在CS50x课程中,但问题是生成的output.bmp在CS上完全正确