WinCE平台下BMP转JPG代码备份3

 
  1 //带参数的保存位图函数
2 BOOL FileOperate::bmpSaveImage(PTSTR pstrFileName, BITMAPFILEHEADER *pbmfh)
3 {
4 BOOL bSuccess ;
5 DWORD dwBytesWritten ;
6 HANDLE hFile;
7
8 hFile = CreateFile ( pstrFileName, GENERIC_WRITE, 0, NULL,
9 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) ;
10
11 if (hFile == INVALID_HANDLE_VALUE) {
12 return FALSE ;
13 }
14
15 bSuccess = WriteFile (hFile, pbmfh, pbmfh->bfSize, &dwBytesWritten, NULL);
16
17 CloseHandle (hFile) ;
18
19 if (!bSuccess || (dwBytesWritten != pbmfh->bfSize)) {
20 DeleteFile (pstrFileName) ;
21 return FALSE ;
22 }
23 return TRUE ;
24 }
25
26 //************************************
27 // Method: SaveBmp
28 // FullName: FileOperate::SaveBmp
29 // Access: public static
30 // Returns: CString 位图的名称
31 // Qualifier: 保存位图
32 // Parameter: char * pcBmpDataTemp 位图数据区内容
33 //************************************
34 CString FileOperate::SaveBmp0(BYTE *pcBmpDataTemp)
35 {
36 // TODO: Add your control notification handler code here
37 IMAGE_SIZE tDispSize = {0};
38 DWORD dwPreMode;
39 PINGPONG_PR DataAddr;
40 BITMAPFILEHEADER *pFileHead = NULL; /* 位图文件的头指针 */
41 BITMAPINFO *pBmpInfo = NULL; /* 位图信息的指针 */
42 char *pcBmpData = NULL; /* 位图数据区的指针 */
43 DWORD dwImgeX; /* 位图水平像素 */
44 DWORD dwImgeY; /* 位图垂直像素 */
45
46 DWORD dwFileHeadSize = sizeof(BITMAPFILEHEADER); /* 位图文件的头区域大小 */
47 DWORD dwInfoSize = sizeof(BITMAPINFO) + 4 * 2; /* 位图文件的信息区大小 */
48 DWORD dwBipMapSize; /* 位图文件的数据区大小 */
49 CString cstrPathname;
50
51 cstrPathname+="\\FlashDisk2\\bmp\\";
52 cstrPathname+=GetTimeTag();
53 cstrPathname+=".bmp";
54 dwImgeX = 320;
55 dwImgeY = 240;
56
57 dwBipMapSize = 2 * dwImgeX * dwImgeY; /* 文件头指针指向整个位图的空间 320*240*2/1024 =150K*/
58 pFileHead = (BITMAPFILEHEADER*)malloc(dwFileHeadSize + dwInfoSize + dwBipMapSize);
59 pBmpInfo = (BITMAPINFO *)malloc(dwInfoSize);
60
61 pFileHead->bfOffBits = dwFileHeadSize + dwInfoSize; /* 以下为填充位图的空间 */
62 pFileHead->bfSize = dwFileHeadSize + dwInfoSize + dwBipMapSize;
63 pFileHead->bfType = 0x4D42;
64
65 pcBmpData = (char *) pFileHead + pFileHead->bfOffBits;
66
67 pBmpInfo->bmiHeader.biHeight = 0 - (signed)dwImgeY;
68 pBmpInfo->bmiHeader.biWidth = dwImgeX ;
69 pBmpInfo->bmiHeader.biBitCount = 16;
70 pBmpInfo->bmiHeader.biClrImportant = 0;
71 pBmpInfo->bmiHeader.biClrUsed = 0;
72 pBmpInfo->bmiHeader.biCompression = BI_BITFIELDS;
73 pBmpInfo->bmiHeader.biPlanes = 1;
74 pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
75 pBmpInfo->bmiHeader.biSizeImage = dwBipMapSize;
76
77 pBmpInfo->bmiColors[0].rgbBlue = 0x00;
78 pBmpInfo->bmiColors[0].rgbGreen = 0xF8;
79 pBmpInfo->bmiColors[0].rgbRed = 0x00;
80 pBmpInfo->bmiColors[0].rgbReserved = 0x00;
81 pBmpInfo->bmiColors[1].rgbBlue = 0xE0;
82 pBmpInfo->bmiColors[1].rgbGreen = 0x07;
83 pBmpInfo->bmiColors[1].rgbRed = 0x00;
84 pBmpInfo->bmiColors[1].rgbReserved = 0x00;
85 pBmpInfo->bmiColors[2].rgbBlue = 0x1F;
86 pBmpInfo->bmiColors[2].rgbGreen = 0x00;
87 pBmpInfo->bmiColors[2].rgbRed = 0x00;
88 pBmpInfo->bmiColors[2].rgbReserved = 0x00;
89
90 memcpy((void*)(pFileHead + 1), (void*)pBmpInfo, dwInfoSize);
91
92
93 //最后将RGB565的图片数据全部COPY到pcBmpData中了----这里可以通过读文件的形式将这些数据读上来。!!!!!!
94 //只需要在此处将那个RGB565的文件用二进制的格式读进来就OK了!!!
95 /*CFile hFile;
96 hFile.Open(_T("\\2010-9-23.bins"),CFile::modeRead);
97 hFile.Read(pcBmpData,dwBipMapSize);*/
98 memcpy(pcBmpData,pcBmpDataTemp,dwBipMapSize);//将图片数据区值COPY过来
99
100
101 // memcpy(bmpFileData,pFileHead,153666);//当程序运行到此处,C#程序中的临时数组已经有值了。
102
103
104 bmpSaveImage((PTSTR)cstrPathname.GetBuffer(0), pFileHead); /* 保存成BMP图片 */
105 cstrPathname.ReleaseBuffer();
106
107 free(pFileHead);
108 free(pBmpInfo);
109
110 return cstrPathname;
111 }
112
113
114
115
116 //************************************
117 // Method: SaveBmp
118 // FullName: FileOperate::SaveBmp
119 // Access: public static
120 // Returns: CString 位图的名称
121 // Qualifier: 保存位图
122 // Parameter: char * pcBmpDataTemp 位图数据区内容
123 //************************************
124 CString FileOperate::SaveBmp(char *pcBmpDataTemp,char *bmpFileData)
125 {
126 // TODO: Add your control notification handler code here
127 IMAGE_SIZE tDispSize = {0};
128 DWORD dwPreMode;
129 PINGPONG_PR DataAddr;
130 BITMAPFILEHEADER *pFileHead = NULL; /* 位图文件的头指针 */
131 BITMAPINFO *pBmpInfo = NULL; /* 位图信息的指针 */
132 char *pcBmpData = NULL; /* 位图数据区的指针 */
133 DWORD dwImgeX; /* 位图水平像素 */
134 DWORD dwImgeY; /* 位图垂直像素 */
135
136 DWORD dwFileHeadSize = sizeof(BITMAPFILEHEADER); /* 位图文件的头区域大小 */
137 DWORD dwInfoSize = sizeof(BITMAPINFO) + 4 * 2; /* 位图文件的信息区大小 */
138 DWORD dwBipMapSize; /* 位图文件的数据区大小 */
139 CString cstrPathname;
140
141 cstrPathname+="\\FlashDisk2\\bmp\\";
142 cstrPathname+=GetTimeTag();
143 cstrPathname+=".bmp";
144 dwImgeX = 320;
145 dwImgeY = 240;
146
147 dwBipMapSize = 2 * dwImgeX * dwImgeY; /* 文件头指针指向整个位图的空间 320*240*2/1024 =150K*/
148 pFileHead = (BITMAPFILEHEADER*)malloc(dwFileHeadSize + dwInfoSize + dwBipMapSize);
149 pBmpInfo = (BITMAPINFO *)malloc(dwInfoSize);
150
151 pFileHead->bfOffBits = dwFileHeadSize + dwInfoSize; /* 以下为填充位图的空间 */
152 pFileHead->bfSize = dwFileHeadSize + dwInfoSize + dwBipMapSize;
153 pFileHead->bfType = 0x4D42;
154
155 pcBmpData = (char *) pFileHead + pFileHead->bfOffBits;
156
157 pBmpInfo->bmiHeader.biHeight = 0 - (signed)dwImgeY;
158 pBmpInfo->bmiHeader.biWidth = dwImgeX ;
159 pBmpInfo->bmiHeader.biBitCount = 16;
160 pBmpInfo->bmiHeader.biClrImportant = 0;
161 pBmpInfo->bmiHeader.biClrUsed = 0;
162 pBmpInfo->bmiHeader.biCompression = BI_BITFIELDS;
163 pBmpInfo->bmiHeader.biPlanes = 1;
164 pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
165 pBmpInfo->bmiHeader.biSizeImage = dwBipMapSize;
166
167 pBmpInfo->bmiColors[0].rgbBlue = 0x00;
168 pBmpInfo->bmiColors[0].rgbGreen = 0xF8;
169 pBmpInfo->bmiColors[0].rgbRed = 0x00;
170 pBmpInfo->bmiColors[0].rgbReserved = 0x00;
171 pBmpInfo->bmiColors[1].rgbBlue = 0xE0;
172 pBmpInfo->bmiColors[1].rgbGreen = 0x07;
173 pBmpInfo->bmiColors[1].rgbRed = 0x00;
174 pBmpInfo->bmiColors[1].rgbReserved = 0x00;
175 pBmpInfo->bmiColors[2].rgbBlue = 0x1F;
176 pBmpInfo->bmiColors[2].rgbGreen = 0x00;
177 pBmpInfo->bmiColors[2].rgbRed = 0x00;
178 pBmpInfo->bmiColors[2].rgbReserved = 0x00;
179
180 memcpy((void*)(pFileHead + 1), (void*)pBmpInfo, dwInfoSize);
181
182
183 //最后将RGB565的图片数据全部COPY到pcBmpData中了----这里可以通过读文件的形式将这些数据读上来。!!!!!!
184 //只需要在此处将那个RGB565的文件用二进制的格式读进来就OK了!!!
185 /*CFile hFile;
186 hFile.Open(_T("\\2010-9-23.bins"),CFile::modeRead);
187 hFile.Read(pcBmpData,dwBipMapSize);*/
188 memcpy(pcBmpData,pcBmpDataTemp,dwBipMapSize);//将图片数据区值COPY过来
189
190
191 memcpy(bmpFileData,pFileHead,153666);//当程序运行到此处,C#程序中的临时数组已经有值了。
192
193
194 bmpSaveImage((PTSTR)cstrPathname.GetBuffer(0), pFileHead); /* 保存成BMP图片 */
195 cstrPathname.ReleaseBuffer();
196
197 free(pFileHead);
198 free(pBmpInfo);
199
200 return cstrPathname;
201 }
202
203
204
205
206
207
208 #endif
209
210
211
212 //pcBmpDataTemp--从摄像头中得到的565数据区内容
213 void FileOperate::ImageConvertDemo(BYTE *pInBmp565Data,//输入的RGB565位图的数据实体部分--不包括位图文件等信息
214 DWORD dwBitMapDataSize,//位图数据实体长度(不包括文件头等信息)153600
215 BYTE **ppOutMallocData,//传出的JPG图片数据实体
216 DWORD * pdwOutJpegMemSize,//传出的JPG图片数据的大小
217 int * pState //状态码:记录在执行此函数的过程中可能出现的问题
218 )
219 {
220
221 BYTE * pOutRgb555BmpData=NULL;//输出的555格式的位图数据实体
222 DWORD dwRgb555BmpFileDataLength=0;//153666;//暂时先赋一个值,最终还是要通过传递得到的----######
223
224
225 dwRgb555BmpFileDataLength=sizeof(BITMAPFILEHEADER) //位图文件信息头:14
226 + sizeof(BITMAPINFOHEADER) //位图信息头:40
227 + 3*sizeof(RGBQUAD)//RGB掩码:12
228 + dwBitMapDataSize;//数据实体部分:153600
229
230 IImageDemo imgDemo;
231
232 //FileOperate::SaveBmp0(pInBmp565Data);//测试代码:此处测试表明,可以取得到实时的数据了
233 imgDemo.ConvertBmpRgb565To555(pInBmp565Data,dwRgb555BmpFileDataLength,&pOutRgb555BmpData);//测试转码
234
235 BYTE * pJpegData=NULL;
236 DWORD dwpJpegDataLength;//Jpeg数组的长度
237 imgDemo.ConvertRgb555BmpToJpgInMem(pOutRgb555BmpData,dwRgb555BmpFileDataLength,&pJpegData,&dwpJpegDataLength);//因为是在函数内部动态分配的内存,所以需要用指针的指针
238
239 //传出数据
240 *pdwOutJpegMemSize=dwpJpegDataLength;//传出长度---在最终代码中要简化
241 *ppOutMallocData=pJpegData;
242
243 }


1.3转换图片格式

GetImage.h

 1 #pragma once
2
3
4 #include "initguid.h "//如果不引用此头文件,就会出现 无法解析外部符号的错误
5 #include "imaging.h"//图片转码测试
6
7
8
9
10 class GetImage
11 {
12 public:
13 GetImage(DWORD dwRGB_Width,DWORD dwRGB_Height);
14 GetImage(void);
15 ~GetImage(void);
16
17
18 public:
19 DWORD dwRGB_Width; /* RGB 通道的输出图像的宽度 */
20 DWORD dwRGB_Height; /* RGB 通道的输出图像的高度 */
21
22 public:
23 //转换图片格式,并得到jpeg文件的数组
24 void GetJpegBytes(
25 BYTE *pInBmp565Data,//输入的RGB565位图的数据实体部分(不包括文件头等信息)
26 DWORD dwBitMapDataSize,//位图数据实体长度(不包括文件头等信息)
27 BYTE **ppOutMallocData,//传出的JPG图片数据实体的指针
28 DWORD * pdwOutJpegMemSize,//传出的JPG图片数据的大小
29 int * pState //状态码:记录在执行此函数的过程中可能出现的问题
30 );
31
32
33 private:
34
35 //将Rgb565编码格式的位图转成Rgb555的位图
36 void ConvertBmpRgb565To555(
37 BYTE * pInRgb565BmpData, //输入的565格式的位图数据实体
38 DWORD dwRgb555BmpFileDataLength,//位图文件大小
39 BYTE ** ppOutRgb555BmpData//输出的555格式的位图数据实体
40 );
41
42 //将数组转换到IStream中
43 void CopyByteArrayToISream(
44 BYTE *pInByteArray,//输入的字节数组
45 DWORD dwArrayLength,//字节数组的长度
46 IStream **ppOutIStream//传出的由字节转换的流
47 );
48
49 /*
50 *函数介绍:根据编码器类型名称,得到指定的编码器CLSID
51 *入口参数:pImagingFactory: Image工厂接口对象
52 wszMimeType : Image编码格式名称
53 *出口参数:pclsid :编码器的CLSID
54 *返回值:TRUE : 成功; FALSE: 失败
55 */
56 BOOL GetEnCodecCLSID(IImagingFactory * pImagingFactory, WCHAR * wszMimeType , CLSID * pclsid);
57
58
59 //Rgb555编码的BMP位图转JPG--在内存中进行
60 void ConvertRgb555BmpToJpgInMem(
61 BYTE * pInRgb555BmpFileData, //输入的RGB555位图文件流--包括位图数据实体及文件和位图信息
62 DWORD dwRgb555BmpFileDataLength,//RGB555位图文件流的长度
63 BYTE ** ppOutJpegData,//输出的JPG位图文件数据流
64 DWORD * dwpOutJpegDataLegth//转码后的JPG位图大小
65 );
66
67 };
 

GetImage.cpp

  1 #include "StdAfx.h"
2 #include "GetImage.h"
3
4 #include "CamException.h"
5
6 //#include "epccameralib.h"//摄像头驱动
7
8
9 GetImage::GetImage(void)
10 {
11 }
12
13
14 GetImage::GetImage(DWORD dwWidth,DWORD dwHeight)
15 {
16 dwRGB_Height=dwHeight;
17 dwRGB_Width=dwWidth;
18 }
19
20
21 GetImage::~GetImage(void)
22 {
23 }
24
25
26 void GetImage::GetJpegBytes(
27 BYTE *pInBmp565Data,//输入的RGB565位图的数据实体部分--不包括位图文件等信息
28 DWORD dwBitMapDataSize,//位图数据实体长度(不包括文件头等信息)153600
29 BYTE **ppOutMallocData,//传出的JPG图片数据实体
30 DWORD * pdwOutJpegMemSize,//传出的JPG图片数据的大小
31 int * pState //状态码:记录在执行此函数的过程中可能出现的问题
32 )
33 {
34
35 try
36 {
37 BYTE * pOutRgb555BmpData=NULL;//输出的555格式的位图数据实体
38 DWORD dwRgb555BmpFileDataLength=0;//位图文件长度153666
39
40
41 dwRgb555BmpFileDataLength=sizeof(BITMAPFILEHEADER) //位图文件信息头:14
42 + sizeof(BITMAPINFOHEADER) //位图信息头:40
43 + 3*sizeof(RGBQUAD)//RGB掩码:12
44 + dwBitMapDataSize;//数据实体部分:153600
45
46 //将位图数据转码成555数据,并加上相关文件头,最后形成555位图文件
47 ConvertBmpRgb565To555(pInBmp565Data,dwRgb555BmpFileDataLength,&pOutRgb555BmpData);
48
49
50 #pragma region //测试没有取到图片的情况
51
52
53 //CFile hSaveFile;
54 //hSaveFile.Open(L"\\565bmp.bin",CFile::modeCreate | CFile::modeWrite |CFile::modeNoTruncate);
55 ////创立一个txt文件。
56 //hSaveFile.SeekToEnd(); //文件末尾
57
58 //hSaveFile.Write(pInBmp565Data,dwBitMapDataSize);
59 //hSaveFile.Close();
60
61 #pragma endregion
62
63
64
65
66
67 if (pOutRgb555BmpData==NULL)
68 {
69 throw CString("ConvertBmpRgb565To555位图图片格式转码失败");
70 }
71
72 BYTE * pJpegData=NULL;
73 DWORD dwpJpegDataLength;//Jpeg数组的长度
74 ConvertRgb555BmpToJpgInMem(pOutRgb555BmpData,dwRgb555BmpFileDataLength,&pJpegData,&dwpJpegDataLength);
75 //因为是在函数内部动态分配的内存,所以需要用指针的指针
76
77 if (pOutRgb555BmpData!=NULL)
78 {
79 free(pOutRgb555BmpData);//555位图数据使用完毕后,就释放
80 pOutRgb555BmpData=NULL;
81 }
82
83 if (pJpegData==NULL)
84 {
85 throw CString("ConvertRgb555BmpToJpgInMem位图压缩失败");
86 }
87
88 //传出数据
89 *pdwOutJpegMemSize=dwpJpegDataLength;//传出长度---在最终代码中要简化
90 *ppOutMallocData=pJpegData;
91 }
92 catch(CString exMsg)
93 {
94 exMsg=L"GetJpegBytes(BYTE*,DWORD,BYTE**,DWORD*,int*):" + exMsg;
95 CamException::WriteToFile(exMsg);
96 }
97 catch (CException* e)
98 {
99 TCHAR szCause[255];
100 e->GetErrorMessage(szCause, 255);
101 CString exMsg=CString(szCause);
102 exMsg=L"GetJpegBytes(BYTE*,DWORD,BYTE**,DWORD*,int*):" + exMsg;
103 CamException::WriteToFile(exMsg);
104 }
105
106 }
107
108
109
110 //将Rgb565编码格式的位图转成Rgb555的位图---位图的大小不会变化,只是数据的编码方式发生变化
111 void GetImage::ConvertBmpRgb565To555(
112 BYTE * pInRgb565BmpData,//输入的565格式的位图数据实体----不包括位图文件信息
113 DWORD dwRgb555BmpFileDataLength,//位图文件大小153666
114 BYTE ** ppOutRgb555BmpFileData//输出的555格式的位图文件数据流--可以形成完整文件
115 )
116 {
117
118 try
119 {
120 #pragma region //设置位图文件
121 BITMAPFILEHEADER *pFileHead = NULL; /* 位图文件的头指针 */
122 BITMAPINFO *pBmpInfo = NULL; /* 位图信息的指针 */
123 char *pcBmpData = NULL; /* 位图数据区的指针 */
124 DWORD dwImgeX; /* 位图水平像素 */
125 DWORD dwImgeY; /* 位图垂直像素 */
126
127 DWORD dwFileHeadSize = sizeof(BITMAPFILEHEADER); /* 位图文件的头区域大小 */
128 DWORD dwInfoSize = sizeof(BITMAPINFO) + 4 * 2; /* 位图文件的信息区大小 */
129 DWORD dwBipMapSize; /* 位图文件的数据区大小 */
130
131
132
133 dwBipMapSize = 2 * dwRGB_Height * dwRGB_Width; //文件头指针指向整个位图的空间 320*240*2/1024 =150K
134 pFileHead = (BITMAPFILEHEADER*)malloc(dwFileHeadSize + dwInfoSize + dwBipMapSize);
135 if (pFileHead==NULL)
136 {
137 throw CString("pFileHead位图信息头内存分配失败");
138 }
139
140 pBmpInfo = (BITMAPINFO *)malloc(dwInfoSize);
141
142 if (pBmpInfo==NULL)
143 {
144 free(pFileHead);
145 pFileHead==NULL;//释放已经申请到的内存
146 throw CString("pBmpInfo位图信息头内存分配失败");
147 }
148
149 pFileHead->bfOffBits = dwFileHeadSize + dwInfoSize; /* 以下为填充位图的空间 */
150 pFileHead->bfSize = dwFileHeadSize + dwInfoSize + dwBipMapSize;
151 pFileHead->bfType = 0x4D42;//位图文件的 类型代码
152
153 pcBmpData = (char *) pFileHead + pFileHead->bfOffBits;
154
155 pBmpInfo->bmiHeader.biHeight = 0 - (signed)dwRGB_Height;
156 pBmpInfo->bmiHeader.biWidth = dwRGB_Width ;
157
158 pBmpInfo->bmiHeader.biBitCount = 16;
159 pBmpInfo->bmiHeader.biClrImportant = 0;
160 pBmpInfo->bmiHeader.biClrUsed = 0;
161 //pBmpInfo->bmiHeader.biCompression = BI_BITFIELDS;//RGB565格式
162 pBmpInfo->bmiHeader.biCompression = BI_RGB;//RGB555格式
163 pBmpInfo->bmiHeader.biPlanes = 1;
164 pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
165 pBmpInfo->bmiHeader.biSizeImage = dwBipMapSize;
166
167
168 memcpy((void*)(pFileHead + 1), (void*)pBmpInfo, dwInfoSize);
169 memcpy(pcBmpData,pInRgb565BmpData,dwBipMapSize);//将摄像头数据复制到位图文件内存缓冲区中
170
171 #pragma endregion
172
173 #pragma region //进行颜色分量提取,并转码成RGB555
174
175
176 char * p555Data=NULL;
177 p555Data=(char*)malloc(dwBipMapSize);//申请一片数据作为555数据的缓冲区
178
179 if (p555Data==NULL)
180 {
181 free(pFileHead);
182 pFileHead=NULL;
183 free(pBmpInfo);
184 pBmpInfo=NULL;
185 throw CString("p555Data内存分配失败");
186 }
187
188 DWORD width=dwRGB_Width;//320
189 DWORD height=dwRGB_Height;//240
190 int pitch=width+width%2;//偏移量
191
192 for (int i=0;i<height;i++)//图片的高度是240
193 {
194 for (int j=0;j<width;j++)
195 {
196
197 //分解出RGB三分量---RGB565的
198 UCHAR b=pcBmpData[(i*pitch+j)*2]&0x1F;
199 UCHAR g=((((pcBmpData[(i*pitch+j)*2+1]<<5)&0xFF)>>2) & 0x38) +((pcBmpData[(i*pitch+j)*2]>>5)&0x07);
200 UCHAR r=(pcBmpData[(i*pitch+j)*2+1]>>3)&0x1F;
201
202 g=g/2;//把g分量从RGB565标准转码成RGB555标准
203
204
205 //将新的RGB分量弄到RGB555的图片数据区中.
206 p555Data[(i*pitch+j)*2] = ((g<<5)&0xE0)+b;//gb分量
207 p555Data[(i*pitch+j)*2+1] = (r<<2)+(g/8);//rg分量
208
209 }
210 }
211
212 memcpy(pcBmpData,p555Data,dwBipMapSize);//将新的数据区内容复制到原来的数据区中进行了数据覆盖
213
214 #pragma endregion
215
216 //---*****传出参数
217 *ppOutRgb555BmpFileData=(BYTE *)malloc(dwRgb555BmpFileDataLength);
218 if (*ppOutRgb555BmpFileData==NULL)
219 {
220 free(pFileHead);
221 pFileHead=NULL;
222 free(pBmpInfo);
223 pBmpInfo=NULL;
224 free(p555Data);
225 p555Data=NULL;
226 throw CString("*ppOutRgb555BmpFileData内存分配失败");
227 }
228 memcpy(*ppOutRgb555BmpFileData,pFileHead,dwRgb555BmpFileDataLength);
229
230
231 free(pFileHead);
232 free(pBmpInfo);
233 free(p555Data);
234 }
235 catch(CString exMsg)
236 {
237 exMsg=L"ConvertBmpRgb565To555(BYTE*,DWORD,BYTE**):" + exMsg;
238 CamException::WriteToFile(exMsg);
239 }
240 catch (CException* e)
241 {
242 TCHAR szCause[255];
243 e->GetErrorMessage(szCause, 255);
244 CString exMsg=CString(szCause);
245 exMsg=L"ConvertBmpRgb565To555(BYTE*,DWORD,BYTE**):" + exMsg;
246 CamException::WriteToFile(exMsg);
247 }
248
249
250 }
251
252
253
254
255 // //Rgb555编码的BMP位图转JPG--在内存中进行
256 void GetImage::ConvertRgb555BmpToJpgInMem(
257 BYTE * pInRgb555BmpFileData, //输入的RGB555位图文件流--包括位图数据实体及文件和位图信息
258 DWORD dwRgb555BmpFileDataLength,//RGB555位图文件流的长度
259 BYTE ** ppOutJpegData,//传出的JPG文件数据流
260 DWORD * dwpOutJpegDataLegth//JPG文件流大小
261 )
262 {
263
264 try
265 {
266 #pragma region
267 HRESULT hr;//保存每个步骤的中间结果,判断过程运行是否正确----到时候有必要写个异常日志记录
268 TCHAR *tszMime;//输出图片格式
269 tszMime = L"image/jpeg"; //指定转换后,图象文件的格式
270
271 IStream *pRgb555BmpStream = NULL; // 流接口对象---读取BMP文件,然后在内存中保存此文件数据
272 IStream * pJpegStream=NULL;//用来保存转换的JPG文件
273 IImagingFactory * pImagingFactory = NULL ; //Image工厂接口对象
274 IImageSink *pImageSink = NULL; //Image Sink接口对象
275 IImageDecoder *pImageDecoder = NULL; //解码器接口对象
276 IImageEncoder *pImageEncoder = NULL; //编码器接口对象
277 CLSID clsidEncoder; //编码器CLSID
278
279
280
281 //小技巧:有些变量虽然只在函数体里局部用到,但是因为是动态分配的内存,需要最后手动释放内存,最好放在最前面声明,防止最后遗忘了。
282 STATSTG * pIStreamState=NULL;//得到pJpegStream的状态
283 BYTE * pJpegData=NULL;//用来存储从文件流中剥出来的数据。
284
285
286
287 //初始化COM环境
288 if (FAILED(hr = CoInitializeEx(NULL, COINIT_MULTITHREADED)))
289 {
290 TRACE(L"COINIT_MULTITHREADED ERROR");
291 return;
292 }
293
294 CopyByteArrayToISream(pInRgb555BmpFileData,dwRgb555BmpFileDataLength,&pRgb555BmpStream);//承接数据
295
296
297 //将流指针移到流起点。-----一般都要进行一下这样的测试
298 LARGE_INTEGER dlibMove0;
299 dlibMove0.HighPart=0;
300 dlibMove0.LowPart=0;
301 pRgb555BmpStream->Seek(dlibMove0,STREAM_SEEK_SET,NULL);
302
303
304 //得到Image工厂接口对象---用指定的类标识符创建一个Com对象,用指定的类标识符创建一个未初始化的对象。
305 hr = CoCreateInstance(CLSID_ImagingFactory,//创建的Com对象的类标识符(CLSID)
306 NULL,//指向接口IUnknown的指针
307 CLSCTX_INPROC_SERVER,//运行可执行代码的上下文
308 IID_IImagingFactory,//创建的Com对象的接口标识符
309 (void**) &pImagingFactory);//用来接收指向Com对象接口地址的指针变量
310
311 if (FAILED(hr))
312 {
313 TRACE(L"IMAGE FACTORY CREATED ERROR");
314 goto finish;
315 }
316
317
318 //创建解码器接口
319 if (FAILED(hr = pImagingFactory->CreateImageDecoder(pRgb555BmpStream, DecoderInitFlagBuiltIn1st, &pImageDecoder)))
320 {
321 goto finish;
322 }
323
324
325 //根据编码器类型名称得到编码器CLSID
326 if (!GetEnCodecCLSID(pImagingFactory,tszMime, &clsidEncoder ))//tszMime = L"image/jpeg"; //指定转换后,图象文件的格式
327 {
328 goto finish;
329 }
330
331 if (FAILED(hr = CreateStreamOnHGlobal(NULL,TRUE,&pJpegStream)))//必需要和某个内存区域关联,或者进行一次实例化,比如用COleStreamFile
332 {
333 goto finish;
334 }
335
336 if (FAILED(hr = pImagingFactory->CreateImageEncoderToStream(&clsidEncoder, pJpegStream, &pImageEncoder)))
337 {
338 goto finish;
339 }
340
341 //得到编码器接口的sink对象。此ImageSink接口作为一个槽或者管道来理解;
342 //是用于负责pImageEncoder和pImageDecoder之间的传输
343 if (FAILED(hr = pImageEncoder->GetEncodeSink(&pImageSink)))
344 {
345 goto finish;
346 }
347 //开始解码
348 if (FAILED(hr = pImageDecoder->BeginDecode(pImageSink, NULL)))
349 {
350 goto finish;
351 }
352 //循环解码,直到结束
353 for(;;)//for循环其实只运行了一个周期
354 {
355 //解码
356 hr = pImageDecoder->Decode();//解码后,生成一个8K的文件
357 //继续解码后面的部分
358 if (E_PENDING == hr)
359 {
360 Sleep(500);
361 } //失败
362 else if (FAILED(hr))
363 {
364 //终止解码
365 pImageDecoder->EndDecode(hr);
366 goto finish;
367 }
368 else
369 {
370 //解码成功
371 break;
372 }
373 }
374
375 pImageDecoder->EndDecode(hr);//结束解码
376 pImageSink->Release();//释放pImageSink对象
377 pImageSink = NULL;
378 pImageEncoder->TerminateEncoder();//结束编码,此时就已经完成了文件格式的转换
379
380 #pragma region //从流中提取数据到BYTE数组中
381
382 DWORD dwStreamLengthLowPart;//状态中的长度分量--低位(因为实际图片数据不需要高位那么长)
383 //得到pJpegStream的长度--然后提取出数据,保存到BYTE数组中
384 pIStreamState=(STATSTG *)malloc(sizeof(STATSTG));//如果不动态开辟空间,将无法传值进来。
385 if (NULL == pIStreamState)//如果申请内存没有成功
386 {
387 CamException::WriteToFile(L"pIStreamState申请内存失败");
388 goto finish;
389 }
390
391 if (FAILED(hr=pJpegStream->Stat(pIStreamState,STATFLAG_NONAME)))
392 {
393 CamException::WriteToFile(L"pJpegStream获取状态失败");
394 goto finish;
395 }
396 dwStreamLengthLowPart = pIStreamState->cbSize.LowPart;//取出流状态中的长度分量
397 free(pIStreamState);
398 pIStreamState=NULL;//指针置空,防止野指针出现
399
400
401 pJpegData = (BYTE *)malloc(dwStreamLengthLowPart);//用来存储从文件流中剥出来的数据。
402 if (NULL == pJpegData)//如果申请内存没有成功
403 {
404 goto finish;
405 }
406
407 //将流指针移到流起点。
408 LARGE_INTEGER dlibMove;
409 dlibMove.HighPart=0;
410 dlibMove.LowPart=0;
411 pJpegStream->Seek(dlibMove,STREAM_SEEK_SET,NULL);
412
413 hr=pJpegStream->Read(pJpegData,dwStreamLengthLowPart,NULL);//将流文件内容放置到数据中
414 if (FAILED(hr))
415 {
416 goto finish;
417 }
418
419 #pragma endregion
420
421 *ppOutJpegData=pJpegData;//将图片数据指针传递出去
422 *dwpOutJpegDataLegth = dwStreamLengthLowPart;//此处传值可能出了点小故障,明天就干脆把这两个参数封装到一个自定义的结构里面,然后动态生成吧。
423
424
425 finish:
426
427 //释放pRgb555BmpStream对象
428 if (pRgb555BmpStream)
429 pRgb555BmpStream->Release();
430 if (pJpegStream)
431 pJpegStream->Release();
432
433 //释放pImageSink对象
434 if (pImageSink)
435 pImageSink->Release();
436 //释放pImageDecoder对象
437 if (pImageDecoder)
438 pImageDecoder->Release();
439 //释放pImageEncoder对象
440 if (pImageEncoder)
441 pImageEncoder->Release();
442 //释放IImagingFactory接口对象
443 if (pImagingFactory)
444 pImagingFactory->Release();
445 //释放程序占用的COM资源
446 CoUninitialize();
447 #pragma endregion
448 }
449 catch(CString exMsg)
450 {
451 exMsg=L"ConvertBmpRgb565To555(BYTE*,DWORD,BYTE**):" + exMsg;
452 CamException::WriteToFile(exMsg);
453 }
454 catch (CException* e)
455 {
456 TCHAR szCause[255];
457 e->GetErrorMessage(szCause, 255);
458 CString exMsg=CString(szCause);
459 exMsg=L"ConvertBmpRgb565To555(BYTE*,DWORD,BYTE**):" + exMsg;
460 CamException::WriteToFile(exMsg);
461 }
462
463
464 }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值