之前遇到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
}

2

3

4

5

6

7

8

9



10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33



34

35

36

37

38

39

40

41

42

43

44

45

46



47

48

49

50

51



52

53

54

55

56

57

58

59

60

61

62

63

64

65

66


67

68

69

70

71

72

73

74

75

76

77



78

79

80

81

82

83

84

85

86

87

88

89

90



91

92

93

94

95

96

97



98

99

100



101

102



103

104

105

106

107

108

109

110

111

112



113

114

115

116

117

118

119

120

121

122

123

124

125

126

127



128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145
