C++ BMP转JPG方法一

读取文件数据后创建IStream对象,再调用IStream类方法read将JPG数据以二进制流读取出来。

使用GetImageEncodersSize之前一定要初始化GDIplus。最好在函数里面

ULONG_PTR gdiplusToken;

Gdiplus::GdiplusStartupInput gdiplusStartupInput;

Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);


退出的时候记得

Gdiplus::GdiplusShutdown(gdiplusToken);



1.添加GDI头文件

#include < Gdiplus.h>
#pragma comment(lib, "Gdiplus.lib")
using namespace Gdiplus;


#include <Objbase.h>
#include <Objidl.h>
#pragma comment(lib, "Ole32.lib")
#pragma comment(lib, "Uuid.lib")



2.定义两个公共函数:

INT GetEncoderClsid(const WCHAR *format, CLSID *pClsid)
{
	UINT  num = 0;          // number of image encoders    
	UINT  size = 0;         // size of the image encoder array in bytes    

	ImageCodecInfo* pImageCodecInfo = NULL;

	GetImageEncodersSize(&num, &size);
	if (size == 0){
		return -1;  // Failure   
	}

	pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
	if (pImageCodecInfo == NULL){
		return -1;  // Failure   
	}

	GetImageEncoders(num, size, pImageCodecInfo);

	for (UINT j = 0; j < num; ++j){
		if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0){
			*pClsid = pImageCodecInfo[j].Clsid;
			free(pImageCodecInfo);
			return j;  // Success    
		}
	}

	free(pImageCodecInfo);
	return -1;  // Failure   
}

void WriteJPGFile(BYTE *pData, DWORD dwLen)
{
	HANDLE hFile = CreateFile(L"F:\\1.jpg", 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);
	}
}

调用:

HANDLE hFile = CreateFile(L"F:\\nn\\m_2.bmp", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile != INVALID_HANDLE_VALUE){
		DWORD dwFilesize = GetFileSize(hFile, NULL);//获取文件大小
		HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFilesize);//分配文件内存
		if (hGlobal){
			BYTE *pvData = (BYTE*)GlobalLock(hGlobal);
			DWORD dwRead = 0;
			ReadFile(hFile, pvData, dwFilesize, &dwRead, NULL);//将文件数据读取到内存中
			GlobalUnlock(hGlobal);


			{
				IStream *pBMPStream = NULL;
				HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pBMPStream);//将二进制流存到流对象
				if (SUCCEEDED(hr)){
					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;

					Image pImage(pBMPStream);//这里可以改成图片路径
					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"StreamImage1", STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pJPGStream);
						DWORD dwErr = GetLastError();
						if (SUCCEEDED(hr)){
							Status bStatus = pImage.Save(pJPGStream, &codecClsid);//将bmp转jpg后保存在内存中
							//Status bStatus = pImage.Save(L"f:\\1.jpg", &codecClsid);//如果是保存为文件则把注释去掉

							BYTE * pJPGData = new BYTE[1024 * 1024];//申请1M的空间
							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 (pBMPStream){
						pBMPStream->Release();
					}
					if (pIStorage){
						pIStorage->Release();
					}
				}
			}

			GlobalFree(hGlobal);
		}

		CloseHandle(hFile);
	}
demo: http://download.csdn.net/detail/sz76211822/9819193

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VC++ JPEG与BMP图像互JPG图形库只有14个函数,他们都是非常有用的: 1. void init_jpeg() <---jpgdll中的函数 1. void init_jpeg1() <--jpegdll中的函数 本函数初始化JPEG API动态链接库,它必须在其它JPEG API函数之前调用。在程序中此函数只须调用一次。 函数调用语句样例: init_jpeg(); . 2. void findwindow(char *title) 1. void findwindow1(char *title) 本函数取程序窗口的图形句柄,用于其它函数绘图处理。 Title为程序窗口的标题,若标题很长,取前几个字就可以了。 函数调用语句样例: hl=findwindow("JPEG TEST"); . 3. long showjpg(char *fliename, long hwnd, long left, long top) 2. long showjpg1(char *fliename, long hwnd, long left, long top) 本函数打开一个JPG图形文件,并在窗口的(left,top)位置显示。 hwnd为窗口图形句柄,(left,top)为图形显示的左上角位置。 函数调用语句样例: rs=showjpg("c:\jpgdemo\demo.jpg",hwnd,10,10) .. 4. long show_bmp(char *fliename, long hwnd, long left, long top) 3. long show_bmp1(char *fliename, long hwnd, long left, long top) 本函数打开一个BMP图形文件,并在窗口的(left,top)位置显示。 hwnd为窗口图形句柄,(left,top)为图形显示的左上角位置。 函数调用语句样例: rs=showbmp("c:\jpgdemo\demo.bmp",hwnd,10,10) . 5. long jpg_to_bmp(char *jpgfilename, char *bmpfilename) 5. long jpg_to_bmp1(char *jpgfilename, char *bmpfilename) 本函数将一个JPG图形文件换为BMP图形文件。 函数调用语句样例: rs=jpg_to_bmp("c:\jpgdemo\demo.jpg","c:\temp\demo.bmp") . 6. long bmp_to_jpg(char *jpgfilename, char *bmpfilename,long quality) 5. long bmp_to_jpg1(char *jpgfilename, char *bmpfilename,long quality) 本函数将一个BMP图形文件换为JPG图形文件。 Quality为换的质量和图形压缩情况,取值0-100。一般取75。 函数调用语句样例: rs=bmp_to_jpg("c:\jpgdemo\demo.bmp","c:\temp\demo.jpg",75) . 7. long copy_to_bmp(long hwnd, char *bmpfilename, long type) 6. long copy_to_bmp1(long hwnd, char *bmpfilename, long type) 本函数将程序窗口内容硬拷贝到一个BMP图形文件。 hwnd为窗口图形句柄, Type=0, 拷贝整个窗口。 Type=1, 拷贝用户区域 函数调用语句样例: rs=copy_to_bmp("c:\temp\demo.bmp",hwnd,0) . 8. long copy_to_jpeg(long hwnd, char *bmpfilename, long type,long quality) 7. long copy_to_jpeg1(long hwnd, char *bmpfilename, long type,long quality) 本函数将程序窗口内容硬拷贝到一个JPG图形文件。 hwnd为窗口图形句柄, Type=0, 拷贝整个窗口。 Type=1, 拷贝用户区域 quality为图形质量,取值0-100。一般取75。 函数调用语句样例: rs=copy_to_jpeg("c:\temp\demo.jpeg",hwnd,0,75) . 9. long to_clip(long hwnd, long type) 8. long to_clip1(long hwnd, long type) 本函数将程序窗口内容硬拷贝到剪贴板,你可以用"Paste"方式在其它图形软件中编辑。 hwnd为窗口图形句柄, Type=0, 拷贝整个窗口。 Type=1, 拷贝用户区域 函数调用语句样例: rs=to_clip(hwnd,0) . 10. long clip_to_jpeg(char *name,long hl,long quality) 10 long clip_to_jpeg1(char *name,long hl,long quality) 本函数将当前剪贴板上的图形硬拷贝到一个JPG图形文件。 hwnd为窗口图形句柄, Type=0, 拷贝整个窗口。 Type=1, 拷贝用户区域 quality为图形质量,取值0-100。一般取75。 函数调用语句样例: rs=clip_to_jpeg("bird2.jpg",hWnd,75); . 11. long clip_to_bmp(char *name,long hl) 11. long clip_to_bmp1(char *name,long hl) 本函数将当前剪贴板上的图形硬拷贝到一个JPG图形文件。 hwnd为窗口图形句柄, 函数调用语句样例: rs=clip_to_bmp("bird2.bmp",hWnd,75); . 12. void Area_Copy(long hl,long left,long top,long w,long h) 12. void Area_Copy1(long hl,long left,long top,long w,long h) 本函数将程序窗口上的一个区域的内容硬拷贝到剪贴板,你可以用"Paste"方式在其它图形软件中编辑。 hwnd为窗口图形句柄, (left,top)为图形拷贝区域左上角位置 w为图形拷贝区域的宽度 h为图形拷贝区域的高宽度 函数调用语句样例:Area_Copy(hWnd,0,0,300,400); . 13. long Area_to_jpeg(long hl,long left,long top,long w,long h,char * name,long qa) 13.long Area_to_jpeg1(long hl,long left,long top,long w,long h,char * name,long qa) 本函数将程序窗口上的一个区域的内容硬拷贝到JPG图形文件。 hwnd为窗口图形句柄, (left,top)为图形拷贝区域左上角位置 w为图形拷贝区域的宽度 h为图形拷贝区域的高宽度 quality为图形质量,取值0-100。一般取75。 函数调用语句样例:Area_to_jpeg(hWnd,0,0,300,400,"bird3.jpg",75); . 14. long Area_to_bmp(long hl,long left,long top,long w,long h,char * name) 14. long Area_to_bmp1(long hl,long left,long top,long w,long h,char * name) 本函数将程序窗口上的一个区域的内容硬拷贝到BMP图形文件。 hwnd为窗口图形句柄, (left,top)为图形拷贝区域左上角位置 w为图形拷贝区域的宽度 h为图形拷贝区域的高宽度 函数调用语句样例:Area_to_bmp(hWnd,0,0,300,400,"bird3.bmp");

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值