C++ BMP转JPG方法三
来源:互联网 发布:java 物联网 开源框架 编辑:程序博客网 时间:2024/05/18 02:20
因为最近涉及将大的jpg缩小后再在网络上传输,所以需要将大的jpg转小的JPG。首先用Opencv将jpg读取到内存,缩小后,保存为bmp,再将bmp转JPG。如果直接是bmp文件也可以的。7万张图片从枚举到转换保存一共使用了半个小时。内存无泄露。
读取文件数据后创建IStream对象,再调用IStream类方法read将JPG数据以二进制流读取出来。
使用GetImageEncodersSize之前一定要初始化GDIplus。最好在函数里面
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
退出的时候记得
Gdiplus::GdiplusShutdown(gdiplusToken);
1.添加GDI头文件
int n = 0;void WriteJPGFile(BYTE *pData, DWORD dwLen){WCHAR wcPath[MAX_PATH] = {0};wsprintf(wcPath, L"F:\\test\\%d.jpg", ++n);HANDLE hFile = CreateFile(wcPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);if (hFile != INVALID_HANDLE_VALUE){DWORD dwWrite = 0;WriteFile(hFile, pData, dwLen, &dwWrite, NULL);CloseHandle(hFile);}}
void ResizeImage(IplImage **ipl, int nWidth, int nHeight){if (*ipl){while ((*ipl)->width >= nWidth || (*ipl)->height >= nHeight){DWORD dwWidth = (*ipl)->width / 2;DWORD dwHeight = (*ipl)->height / 2;IplImage* iplResize = cvCreateImage(cvSize(dwWidth, dwHeight), 8, 3);if (iplResize){cvResize((*ipl), iplResize);cvReleaseImage(&(*ipl));(*ipl) = cvCloneImage(iplResize);cvReleaseImage(&iplResize);}}}}
转换函数:
Bitmap* IplImage2Bitmap(IplImage* pIplImg){if (!pIplImg){return NULL;}Gdiplus::Bitmap *pBitmap = ::new Gdiplus::Bitmap((int)pIplImg->width, (int)pIplImg->height, PixelFormat24bppRGB);if (!pBitmap){return NULL;}BitmapData bmpData;Rect rect(0, 0, pIplImg->width, pIplImg->height);pBitmap->LockBits(&rect, ImageLockModeWrite, PixelFormat24bppRGB, &bmpData);BYTE *pByte = (BYTE*)bmpData.Scan0;if (pIplImg->widthStep == bmpData.Stride){memcpy(bmpData.Scan0, pIplImg->imageDataOrigin, pIplImg->imageSize);}pBitmap->UnlockBits(&bmpData);return pBitmap;}void bmp2jpg(char cPath[MAX_PATH]){IplImage *ipl = cvLoadImage(cPath);if (ipl){ResizeImage(&ipl, 300, 300);CLSID codecClsid;GetEncoderClsid(L"image/jpeg", &codecClsid);int iQuality = 100;EncoderParameters encoderParameters;encoderParameters.Count = 1;encoderParameters.Parameter[0].Guid = EncoderQuality;encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;encoderParameters.Parameter[0].NumberOfValues = 1;encoderParameters.Parameter[0].Value = &iQuality;Bitmap*pBitmap = IplImage2Bitmap(ipl);if (pBitmap){IStorage* pIStorage = NULL;IStream* pJPGStream = NULL;HRESULT hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &pIStorage);if (SUCCEEDED(hr)){hr = pIStorage->CreateStream(L"StreamImage2", STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pJPGStream);DWORD dwErr = GetLastError();if (SUCCEEDED(hr)){Status bStatus = pBitmap->Save(pJPGStream, &codecClsid);//将bmp转jpg后保存在内存中//Status bStatus = pImage.Save(L"f:\\1.jpg", &codecClsid);//如果是保存为文件则把注释去掉BYTE * pJPGData = NULL;while (!pJPGData){try{pJPGData = new BYTE[1024 * 1024];}catch (...){}}memset(pJPGData, 0, 1024 * 1024);LARGE_INTEGER move;move.QuadPart = 0;pJPGStream->Seek(move, STREAM_SEEK_SET, NULL);//定位到流的起始位置DWORD dwRead = 0;hr = pJPGStream->Read(pJPGData, 1024 * 1024, &dwRead);//在read之前必须seek。否则读取不出来数据WriteJPGFile(pJPGData, dwRead);delete[] pJPGData;}}// Get the class identifier for the JPEG encoder.if (pJPGStream){pJPGStream->Release();}if (pIStorage){pIStorage->Release();}::delete pBitmap;}else{OutputDebugString(L"图片转换失败");}cvReleaseImage(&ipl);}else{OutputDebugStringA(cPath);}}
调用函数:
void CIplimageToBmpDlg::OnBnClickedButton1(){WCHAR wcModule[MAX_PATH * 2] = { 0 };GetModuleFileName(NULL, wcModule, MAX_PATH * 2);::PathRemoveFileSpec(wcModule);if (::PathFileExistsW(wcModule)){wsprintf(wcModule + wcslen(wcModule), L"\\AD\\7万Bmp\\*.*");WIN32_FIND_DATAW FindFileData;HANDLE hFind = FindFirstFileW(wcModule, &FindFileData);if (hFind == INVALID_HANDLE_VALUE){return;}else{int nMAX_Ad_Pictures = 0;while (FindNextFileW(hFind, &FindFileData) != 0){WCHAR *p = PathFindExtension(FindFileData.cFileName);if (p){if (_wcsicmp(p, L".bmp") == 0 || _wcsicmp(p, L".jpg") == 0 || _wcsicmp(p, L".png") == 0){char cPath[MAX_PATH] = { 0 };WCHAR wcFilePath[MAX_PATH * 2] = { 0 };GetModuleFileName(NULL, wcFilePath, MAX_PATH * 2);::PathRemoveFileSpec(wcFilePath);wsprintf(wcFilePath + wcslen(wcFilePath), L"\\AD\\7万Bmp\\%s", FindFileData.cFileName);WideCharToMultiByte(CP_ACP, 0, wcFilePath, MAX_PATH, cPath, MAX_PATH, NULL, NULL);bmp2jpg(cPath);/*//将jpg转bmpwsprintf(wcFilePath + wcslen(wcFilePath), L"\\AD\\7万Bmp\\%s", FindFileData.cFileName);WideCharToMultiByte(CP_ACP, 0, wcFilePath, MAX_PATH, cPath, MAX_PATH, NULL, NULL);IplImage *ipl = cvLoadImage(cPath);if (ipl){char cPathPic[MAX_PATH] = {0};sprintf_s(cPathPic, "f:\\test\\%d.bmp", ++n);cvSaveImage(cPathPic, ipl);cvReleaseImage(&ipl);}*/}}}}// 查找结束FindClose(hFind);}AfxMessageBox(L"操作完成");}
demo下载地址:http://download.csdn.net/detail/sz76211822/9819193
0 0
- C++ BMP转JPG方法三
- C#BMP文件转JPG例程
- windows 批量 jpg 转 bmp 方法
- C++ BMP转JPG方法一
- C++ BMP转JPG方法二
- jpg转bmp&bmp转jpg
- delphi bmp转jpg
- bmp转JPG
- GDI+ BMP转JPG
- BMP转JPG
- jpg转bmp操作方法
- bmp转jpg、jpg转bmp、截屏保存jpg
- 转换jpg成bmp方法
- Bmp文件转Jpg格式
- BMP文件转JPG文件
- [VC]图片 BMP转JPG
- VC实现:bmp转jpg、jpg转bmp、截屏保存jpg
- VC实现:bmp转jpg、jpg转bmp、截屏保存jpg
- Linux 学习心得
- linux修改网卡名称
- AFNetworking(v3.0+)框架学习总结(三框架基本使用)
- MongoDB概览
- 【IMWeb训练营作业】todo list项目
- C++ BMP转JPG方法三
- http返回头中content-length与Transfer-Encoding: chunked的问题释疑
- 常见meta和link标签
- [bzoj4825][HNOI2017]单旋
- Python爬取网页信息时,经常使用的正则表达式及方法
- MySQL忘记密码
- Yii URL美化 Apache配置文件
- 《挑战程序设计竞赛》2.4 加工并存储数据的数据结构
- 继承和多态