这种图像格式在BMP格式的基础上添加了一个alpha通道,这非常有用,特别是在一些游戏设计里头。
Targa文件格式也主要分为两个部分:头部跟图像数据部分。其中头部数据如下定义
typedef struct tagTARGAFILEHEADER { unsigned char imageIDLength; //标识(ID)数据项中的字符数 //0表示么有标识(ID)数据项 unsigned char colorMapType; //颜色位图的类型,必须为 unsigned char imageTypeCode; //未压缩的RGB为 //未压缩的灰度为 short int colorMapOrigin; //颜色图(低---高)的原点(起点);总为 short int colorMapLength; //颜色图(低---高)的长度,总为 short int colorMapEntrySize; //颜色图元素大小尺寸(低---高),总为 short int imageXOrigin; //颜色图(低---高)左下角的X坐标,总为 short int imageYOrigin; //颜色图(低---高)左下角的Y坐标,总为 short int imageWidth; //颜色图(低---高)的像素宽度 short int imageHeight; //颜色图(低---高)的像素高度 unsigned char bitCount; //位数;,24,32 unsigned char imageDescriptor; //24位=0x00,位=0x08 }TARGAFILEHEADER;
知道了文件结构,加载进去就好办了。与BMP位图有点不同的是,我们需要注意每个像素有4个字节大小,分别为BGRA.
首先我们先定义一个结构体保存TGA文件有用的数据。
typedef struct { unsigned char imageTypeCode; short int imageWidth; short int imageHeight; unsigned char bitCount; unsigned char *imageData; } TGAFILE;
接下来看下读取TGA文件的图像数据的函数。
// LoadTGAFile() // desc: loads the TGA file "filename" into the tgaFile data structure int LoadTGAFile(char *filename, TGAFILE *tgaFile) { FILE *filePtr; unsigned char ucharBad; // garbage unsigned char data short int sintBad; // garbage short int data long imageSize; // size of the TGA image int colorMode; // 4 for RGBA or 3 for RGB long imageIdx; // counter variable unsigned char colorSwap; // swap variable // open the TGA file filePtr = fopen(filename, "rb"); if (!filePtr) return 0; // read first two bytes of garbage fread(&ucharBad, sizeof(unsigned char), 1, filePtr); fread(&ucharBad, sizeof(unsigned char), 1, filePtr); // read in the image type fread(&tgaFile->imageTypeCode, sizeof(unsigned char), 1, filePtr); // for our purposes, the image type should be either a 2 (color) or a 3 (greyscale) if ((tgaFile->imageTypeCode != 2) && (tgaFile->imageTypeCode != 3)) { fclose(filePtr); return 0; } // read 13 bytes of garbage data fread(&sintBad, sizeof(short int), 1, filePtr); fread(&sintBad, sizeof(short int), 1, filePtr); fread(&ucharBad, sizeof(unsigned char), 1, filePtr); fread(&sintBad, sizeof(short int), 1, filePtr); fread(&sintBad, sizeof(short int), 1, filePtr); // read image dimensions fread(&tgaFile->imageWidth, sizeof(short int), 1, filePtr); fread(&tgaFile->imageHeight, sizeof(short int), 1, filePtr); // read image bit depth fread(&tgaFile->bitCount, sizeof(unsigned char), 1, filePtr); // read 1 byte of garbage data fread(&ucharBad, sizeof(unsigned char), 1, filePtr); // colorMode -> 3 = BGR, 4 = BGRA colorMode = tgaFile->bitCount / 8; imageSize = tgaFile->imageWidth * tgaFile->imageHeight * colorMode; // allocate memory for image data tgaFile->imageData = (unsigned char*)malloc(sizeof(unsigned char)*imageSize); // read in image data fread(tgaFile->imageData, sizeof(unsigned char), imageSize, filePtr); // change BGR to RGB so OpenGL can read the image data for (imageIdx = 0; imageIdx < imageSize; imageIdx += colorMode) { colorSwap = tgaFile->imageData[imageIdx]; tgaFile->imageData[imageIdx] = tgaFile->imageData[imageIdx + 2]; tgaFile->imageData[imageIdx + 2] = colorSwap; } // close the file fclose(filePtr); return 1; }
下面看下怎么使用
typedef struct { unsigned char imageTypeCode; short int imageWidth; short int imageHeight; unsigned char bitCount; unsigned char *imageData; } TGAFILE; TGAFILE *myTGA; myTGA = (TGAFILE*)malloc(sizeof(TGAFILE)); LoadTGAFile("test.tga", myTGA); // draw the bitmap image DrawBitmap(myTGA->imageWidth, myTGA->imageHeight, myTGA->imageData);
其中DrawBitmap如下:
// DrawBitmap // desc: draws the bitmap image data in bitmapImage at the location // (0,0) in the window. (200,200) is the lower-left corner // of the bitmap. void DrawBitmap(long width, long height, unsigned char* bitmapImage) { glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glRasterPos2i(0,0); // 这里使用的是GL_RGB,若tga文件是位的(有alpha通道),就改为GL_RGBA glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, bitmapImage); }
下面的是将TGA图像数据写进文件中的函数
// saves an array of pixels as a TGA image int WriteTGAFile(char *filename, short int width, short int height, unsigned char* imageData) { unsigned char byteSkip; // used to fill in the data fields that we don‘t care about short int shortSkip; unsigned char imageType; // type of image we‘re writing to file int colorMode; unsigned char colorSwap; int imageIdx; unsigned char bitDepth; long imageSize; FILE *filePtr; // create file for writing binary mode filePtr = fopen(filename, "wb"); if (!filePtr) { fclose(filePtr); return 0; } imageType = 2; // RGB, uncompressed bitDepth = 24; // 24-bitdepth colorMode = 3; // RGB color mode byteSkip = 0; shortSkip = 0; // write 2 bytes of blank data fwrite(&byteSkip, sizeof(unsigned char), 1, filePtr); fwrite(&byteSkip, sizeof(unsigned char), 1, filePtr); // write imageType fwrite(&imageType, sizeof(unsigned char), 1, filePtr); fwrite(&shortSkip, sizeof(short int), 1, filePtr); fwrite(&shortSkip, sizeof(short int), 1, filePtr); fwrite(&byteSkip, sizeof(unsigned char), 1, filePtr); fwrite(&shortSkip, sizeof(short int), 1, filePtr); fwrite(&shortSkip, sizeof(short int), 1, filePtr); // write image dimensions fwrite(&width, sizeof(short int), 1, filePtr); fwrite(&height, sizeof(short int), 1, filePtr); fwrite(&bitDepth, sizeof(unsigned char), 1, filePtr); // write 1 byte of blank data fwrite(&byteSkip, sizeof(unsigned char), 1, filePtr); // calculate the image size imageSize = width * height * colorMode; // change image data from RGB to BGR for (imageIdx = 0; imageIdx < imageSize ; imageIdx += colorMode) { colorSwap = imageData[imageIdx]; imageData[imageIdx] = imageData[imageIdx + 2]; imageData[imageIdx + 2] = colorSwap; } // write the image data fwrite(imageData, sizeof(unsigned char), imageSize, filePtr); // close the file fclose(filePtr); return 1; }
原文:http://blog.csdn.net/epluguo/article/details/19014625