VC GDI+ 窗口截图内存BMP转JPG,压缩、JPG再转IStream流,IStream流再转 BYTE

   最近用到 PC远程监控,用GDI+屏幕截图内存BMP转JPG,压缩 ,JPG再转IStream流,IStream流再转BYTE,通过SOCKET 转发;


/****************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);
    }
}
/****************BMP转JPG 压缩 转字节流*********用法示例**************************

// 将当前屏幕保存成为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);   

		IStream *stream = NULL;
	if( ::CreateStreamOnHGlobal( NULL, TRUE, &stream ) != S_OK )
	{
		return  ;
	}
		/* save the image to stream */


	VOID * outbuf = NULL;
	size_t nDatalen =0;

	/* read the stream to buffer */
	if( !stream_to_mem( stream, &outbuf, &nDatalen  ) )
	{
		stream->Release();
		//return  ;
	}
    stream->Release();
	///可以把数据流通过 线程 socket  发送出去;

	free(outbuf);
   
    ::DeleteObject(hbmp);   
    ::DeleteObject(hmemdc);   
    return;   
}  
  
/****************stream_to_mem **************************

Stream to byte
************************************************************/
static bool stream_to_mem( IStream *stream, void **outbuf, size_t *size )
{
    ULARGE_INTEGER ulnSize;
    LARGE_INTEGER lnOffset;
    lnOffset.QuadPart = 0;
    /* get the stream size */
    if( stream->Seek( lnOffset, STREAM_SEEK_END, &ulnSize ) != S_OK )
    {
        return false;
    }
    if( stream->Seek( lnOffset, STREAM_SEEK_SET, NULL ) != S_OK )
    {
        return false;
    }

    /* read it */
    *outbuf = malloc( (size_t)ulnSize.QuadPart );
    *size = (size_t) ulnSize.QuadPart;
    ULONG bytesRead;
    if( stream->Read( *outbuf, (ULONG)ulnSize.QuadPart, &bytesRead ) != S_OK )
    {
        free( *outbuf );
        return false;
    }

    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   
}



 

demo 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

恋恋西风

up up up

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

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

打赏作者

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

抵扣说明:

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

余额充值