VC/MFC实现:位图CBitmap对象保存成为bmp,bmp转jpg,截屏保存jpg(GDI+)

8 篇文章 0 订阅

位图对象保存为bmp:

加载位图及路径

strExtension = "bmp";
m_strFile = filedlg.GetPathName() + '.' + strExtension;  
UpdateData(FALSE); 
SaveBitmapToFile(m_picture.GetBitmap(), m_strFile);
保存位图代码实现

BOOL CMakeSealDlg::SaveBitmapToFile(HBITMAP hBitmap, CString lpFileName)   //hBitmap   为刚才的屏幕位图句柄   lpFileName   为位图文件名  
{            
	//设备描述表  
	HDC  hDC;  
	//当前分辨率下每象素所占字节数  
	int  iBits;  
	//位图中每象素所占字节数  
	WORD  wBitCount;  
	//定义调色板大小,  位图中像素字节大小  ,位图文件大小  ,  写入文件字节数    
	DWORD  dwPaletteSize=0,  dwBmBitsSize=0,  dwDIBSize=0,  dwWritten=0;    
	//位图属性结构    
	BITMAP  Bitmap;      
	//位图文件头结构  
	BITMAPFILEHEADER  bmfHdr;      
	//位图信息头结构    
	BITMAPINFOHEADER  bi;      
	//指向位图信息头结构      
	LPBITMAPINFOHEADER  lpbi;      
	//定义文件,分配内存句柄,调色板句柄    
	HANDLE  fh,  hDib,  hPal,hOldPal=NULL;    

	//计算位图文件每个像素所占字节数    
	hDC  =  CreateDC("DISPLAY",  NULL,  NULL,  NULL);  
	iBits  =  GetDeviceCaps(hDC,  BITSPIXEL)  *  GetDeviceCaps(hDC,  PLANES);    
	DeleteDC(hDC);    
	if  (iBits <= 1)                     
		wBitCount = 1;    
	else  if  (iBits <= 4)            
		wBitCount  =  4;    
	else  if  (iBits <= 8)       
		wBitCount = 8;    
	else  
		wBitCount = 24;    

	GetObject(hBitmap,  sizeof(Bitmap),  (LPSTR)&Bitmap);  
	bi.biSize = sizeof(BITMAPINFOHEADER);  
	bi.biWidth = Bitmap.bmWidth;  
	bi.biHeight = Bitmap.bmHeight;  
	bi.biPlanes = 1;  
	bi.biBitCount = wBitCount;  
	bi.biCompression = BI_RGB;  
	bi.biSizeImage = 0;  
	bi.biXPelsPerMeter = 0;  
	bi.biYPelsPerMeter = 0;  
	bi.biClrImportant = 0;  
	bi.biClrUsed = 0;  

	dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;  

	//为位图内容分配内存    
	hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));    
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);   
	*lpbi = bi;    

	//  处理调色板      
	hPal = GetStockObject(DEFAULT_PALETTE);    
	if(hPal)    
	{    
		hDC = ::GetDC(NULL);    
		hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE);    
		RealizePalette(hDC);    
	}  

	//  获取该调色板下新的像素值    
	GetDIBits(hDC, hBitmap, 0, (UINT)Bitmap.bmHeight, 
		(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)    
		+ dwPaletteSize, (BITMAPINFO*)lpbi,  DIB_RGB_COLORS);    

	//恢复调色板      
	if  (hOldPal)    
	{    
		::SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);    
		RealizePalette(hDC);    
		::ReleaseDC(NULL, hDC);    
	}    

	//创建位图文件      
	fh = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,    
		FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);    

	if(fh == INVALID_HANDLE_VALUE)   
		return  FALSE;    

	//  设置位图文件头    
	bmfHdr.bfType = 0x4D42;  //  "BM"    
	dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
		+ dwPaletteSize + dwBmBitsSize;      
	bmfHdr.bfSize = dwDIBSize;    
	bmfHdr.bfReserved1 = 0;    
	bmfHdr.bfReserved2 = 0;    
	bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER)
		+ dwPaletteSize;    
	//  写入位图文件头    
	WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);    
	//  写入位图文件其余内容    
	WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);    
	//清除      
	GlobalUnlock(hDib);    
	GlobalFree(hDib);    
	CloseHandle(fh);    

	return TRUE;  	
}

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   
}

 

/****************BMP转JPG*********用法示例**************************

Bitmap newbitmap(L"d:\\d.bmp");//加载BMP
const unsigned short *pFileName=L"d:\\new.jpg";//保存路径
SaveFile(&newbitmap,pFileName );

************************************************************/

void SaveFile(Bitmap* pImage, const wchar_t* pFileName)//
{
    EncoderParameters encoderParameters;
    CLSID jpgClsid; 
GetEncoderClsid(L"image/jpeg", &jpgClsid);
    encoderParameters.Count = 1;
    encoderParameters.Parameter[0].Guid = EncoderQuality;
    encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
    encoderParameters.Parameter[0].NumberOfValues = 1;

    // Save the image as a JPEG with quality level 100.
    ULONG             quality;
    quality = 100;
    encoderParameters.Parameter[0].Value = &quality;
    Status status = pImage->Save(pFileName, &jpgClsid, &encoderParameters);
    if (status != Ok) 
    {
        wprintf(L"%d Attempt to save %s failed.\n", status, pFileName);
    }
}


// 将当前屏幕保存成为jpg图片       
// 参数   xs = 图象x轴大小,   ys = 图象y轴大小,   quality = jpeg图象质量       
void SaveCurScreenJpg(LPCWSTR   pszFileName,   int   xs,   int   ys,   int   quality)   
{   
    HWND hwnd = ::GetDesktopWindow();   
    HDC hdc = GetWindowDC(NULL);   
    int x = GetDeviceCaps(hdc, HORZRES);   
    int y = GetDeviceCaps(hdc, VERTRES);   
    HBITMAP hbmp = ::CreateCompatibleBitmap(hdc, x, y), hold;   
    HDC hmemdc = ::CreateCompatibleDC(hdc);   
    hold = (HBITMAP)::SelectObject(hmemdc,   hbmp);   
    BitBlt(hmemdc, 0, 0, x, y, hdc, 0, 0, SRCCOPY);   
    SelectObject(hmemdc, hold);   
    
    Bitmap bit(xs, ys), bit2(hbmp, NULL);   
    Graphics g(&bit);   
    g.ScaleTransform((float)xs/x,   (float)ys/y);   
    g.DrawImage(&bit2,   0,   0);   
    
    CLSID                           encoderClsid;   
    EncoderParameters   encoderParameters;   
    
    encoderParameters.Count   =   1;   
    encoderParameters.Parameter[0].Guid   =   EncoderQuality;   
    encoderParameters.Parameter[0].Type   =   EncoderParameterValueTypeLong;   
    encoderParameters.Parameter[0].NumberOfValues   =   1;   
    encoderParameters.Parameter[0].Value   =   &quality;   
    
    GetEncoderClsid(L"image/jpeg",   &encoderClsid);   
    bit.Save(pszFileName,   &encoderClsid,   &encoderParameters);   
   
    ::DeleteObject(hbmp);   
    ::DeleteObject(hmemdc);   
    return;   
}  


HBITMAP   ReturnHBITMAP(CString   FileName)//FileName可能是bmp、dib、png、gif、jpeg/jpg、tiff、emf等文件的文件名 

          Bitmap   tempBmp(FileName.AllocSysString())   ; 
        Color       backColor;       
        HBITMAP       HBitmap;   
        tempBmp.GetHBITMAP(backColor,&HBitmap); 
        return   HBitmap;

}

参考资料:

1、http://www.xuebuyuan.com/370397.html

2、http://www.cnblogs.com/carekee/articles/1824069.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

i胡说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值