|
Posted on 2009-09-16 18:06 李熙建 阅读(2056) 评论(1) 编辑 收藏 引用 所属分类: QT
之前遇到QT不支持TGA图片显示的缺陷,人家写的一种弥补的办法,借用一下,手动写一个函数,加载TGA图片,希望对遇到同样问题的朋友有用。如果你有更好的方法也不妨告诉我,非常感谢!
1 #define QT3_SUPPORT 2 #include <QtGui/QApplication.h> 3 #include <qlabel.h> 4 #include <qpixmap.h> 5 6 7 #pragma pack(push, 1) 8 struct TgaHeader 9  { 10 char identsize; // size of ID field that follows 18 byte header (0 usually) 11 char colourmaptype; // type of colour map 0=none, 1=has palette 12 char imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed 13 14 short colourmapstart; // first colour map entry in palette 15 short colourmaplength; // number of colours in palette 16 char colourmapbits; // number of bits per palette entry 15,16,24,32 17 18 short xstart; // image x origin 19 short ystart; // image y origin 20 21 short width; // image width in pixels 22 short height; // image height in pixels 23 24 char bits; // image bits per pixel 8,16,24,32 25 char descriptor; // image descriptor bits (vh flip bits) 26 27 }; 28 #pragma pack(pop) 29 30 QPixmap loadTGA(const char *filename); 31 32 int main(int argc, char *argv[]) 33  { 34 QApplication displayTGA(argc, argv); 35 QLabel *label =new QLabel("DisplayTGAFormatimage",0); 36 //QPixmap pm("rockbump.tga"); 37 QPixmap pm(loadTGA("rockbump.tga")); 38 39 label->setPixmap(pm); 40 displayTGA.setMainWidget(label); 41 label->show(); 42 return displayTGA.exec(); 43 } 44 45 QPixmap loadTGA(const char *filename) 46  { 47 // check if file has tga extension 48 bool isTga = false; 49 int len = strlen(filename); 50 if(len >= 3) 51 { 52 char ext[3]; 53 ext[0] = tolower(filename[len - 3]); 54 ext[1] = tolower(filename[len - 2]); 55 ext[2] = tolower(filename[len - 1]); 56 if(ext[0] == 't' && ext[1] == 'g' && ext[2] == 'a') 57 isTga = true; 58 } 59 60 if(!isTga) 61 return QPixmap(filename); 62 63 // stupid Qt doesn't know how to load tga, so we'll load it by ourselves 64 QPixmap pixmap; 65 66 FILE *fp; // file streams would be more c++ oh well :D 67 fp = fopen(filename, "rb"); 68 69 if(!fp) 70 return pixmap; 71 72 TgaHeader header; 73 fread(&header, sizeof(TgaHeader), 1, fp); 74 75 // we only deal with rgb images, unmapped and rle, and no additional header information 76 if(header.imagetype != 2 && header.imagetype != 10 && !header.identsize && !header.colourmaptype) 77 { 78 fclose(fp); 79 return pixmap; 80 } 81 82 int bytesPerPixel = header.bits/8; 83 int imageSize = header.width * header.height * bytesPerPixel; 84 uchar *imageData = new uchar[imageSize]; 85 fread(imageData, imageSize, 1, fp); 86 fclose(fp); 87 88 // decode rle, if any 89 if(header.imagetype == 10) 90 { 91 uchar *rleData = new uchar[imageSize]; 92 memcpy(rleData, imageData, imageSize); 93 94 int i = 0; 95 int r = 0; 96 while(i < imageSize && r < imageSize) 97 { 98 int num = (rleData[r]&0x7F) + 1; 99 if(rleData[r] > 127) // is rle 100 { 101 for(int k = 0; k < num; ++k) 102 { 103 if(r + 1 + bytesPerPixel >= imageSize || i >= imageSize) 104 return pixmap; // corrupt image data! 105 106 memcpy(&imageData[i], &rleData[r + 1], bytesPerPixel); 107 i += bytesPerPixel; 108 } 109 r += bytesPerPixel + 1; 110 } 111 else 112 { 113 if(r + num * bytesPerPixel + 1 >= imageSize) 114 return pixmap; // corrupt image data! 115 116 memcpy(&imageData[i], &rleData[r + 1], num * bytesPerPixel); 117 i += num * bytesPerPixel; 118 r += num * bytesPerPixel + 1; 119 } 120 } 121 122 delete[] rleData; 123 } 124 125 QImage::Format format; 126 switch(header.bits) 127 { 128 case 16 : format = QImage::Format_RGB16; break; 129 case 24 : format = QImage::Format_RGB32; break; 130 case 32 : format = QImage::Format_ARGB32; break; 131 default : delete[] imageData; return pixmap; // any other than 16, 24 or 32 would be a broken image 132 }; 133 QImage image(imageData, header.width, header.height, format); 134 135 // deal with the TGA flipping of axis 136 // bit5 == 0 : flip 137 // bit5 == 1 : don't flip 138 image = image.mirrored(0, !(header.descriptor&16)); // copies the image. performance loss, but who cares ;-) 139 140 pixmap = QPixmap::fromImage(image); 141 142 delete[] imageData; 143 144 return pixmap; 145 }
Feedback
# re: QT显示TGA图片 回复 更多评论
2012-11-25 15:50 by
经测试,在Linux下此方法不行。程序有时候出现异常,有时候会显示错误的图像。我的环境是Ubuntu11.10,Qt4.8.3,Qt Creator2.41。
|