MFC 屏幕截图(libjpeg bmp转jpg)

Posted K.I.S.S.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MFC 屏幕截图(libjpeg bmp转jpg)相关的知识,希望对你有一定的参考价值。

项目中需要用到的功能。

void Screenshot()
{
    CDC *pDC;
    pDC = CDC::FromHandle(GetDC(GetDesktopWindow()));
    if(pDC == NULL)
        return;
    int BitPerPixel = pDC->GetDeviceCaps(BITSPIXEL);
    int Width = pDC->GetDeviceCaps(HORZRES);
    int Height = pDC->GetDeviceCaps(VERTRES);

    CDC memDC;
    if(memDC.CreateCompatibleDC(pDC) == 0)
        return;

    CBitmap memBitmap, *oldmemBitmap;
    if(memBitmap.CreateCompatibleBitmap(pDC, Width, Height) == NULL)
        return;

    oldmemBitmap = memDC.SelectObject(&memBitmap);
    if(oldmemBitmap == NULL)
        return;
    if(memDC.BitBlt(0, 0, Width, Height, pDC, 0, 0, SRCCOPY) == 0)
        return;

    CPoint po;
    GetCursorPos(&po);
    HICON hinco = (HICON)GetCursor();
    memDC.DrawIcon(po.x-10 , po.y - 10 , hinco);

    BITMAP bmp;
    memBitmap.GetBitmap(&bmp);

    BITMAPINFOHEADER bih = {0};
    bih.biBitCount = bmp.bmBitsPixel;
    bih.biCompression = BI_RGB;
    bih.biHeight = bmp.bmHeight;
    bih.biPlanes = 1;
    bih.biSize = sizeof(BITMAPINFOHEADER);
    bih.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;
    bih.biWidth = bmp.bmWidth;

    BITMAPFILEHEADER bfh = {0};
    bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    bfh.bfSize = bfh.bfOffBits + bmp.bmWidthBytes * bmp.bmHeight;
    bfh.bfType = (WORD)0x4d42;

    BYTE* pImgBuff = new BYTE[bmp.bmWidthBytes * bmp.bmHeight];

    GetDIBits(memDC.m_hDC, (HBITMAP) memBitmap.m_hObject
        , 0, Height, pImgBuff, (LPBITMAPINFO) &bih, DIB_RGB_COLORS);
    memDC.SelectObject(oldmemBitmap);

    BYTE* pJpg = NULL;
    int nJpgSize = BmpToJpeg(pImgBuff, bmp.bmWidth, bmp.bmHeight, &pJpg);

    if (NULL != pJpg)
    {
        delete[] pJpg;
    }

    delete [] pImgBuff;
}

附上 BmpToJpeg

int BmpToJpeg(BYTE *pSrc, int nWidth, int nHeight, BYTE** ppDes)
{
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    JSAMPROW row_pointer[1];
    int row_stride;
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);

    DWORD dwLen = nWidth * nHeight * 3;
    jpeg_mem_dest(&cinfo, ppDes, &dwLen);

    cinfo.image_width = nWidth;
    cinfo.image_height = nHeight;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;

    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, JPEG_QUALITY, TRUE);
    jpeg_start_compress(&cinfo, TRUE);

    row_stride = nWidth * 3;
    for (int i=0, j=0; j < nWidth*nHeight*4; i+=3, j+=4)    //BGRA => RGB
    {
        *(pSrc+i)=*(pSrc+j+2);
        *(pSrc+i+1)=*(pSrc+j+1);
        *(pSrc+i+2)=*(pSrc+j);
    }

    while (cinfo.next_scanline < cinfo.image_height)
    {
        row_pointer[0] = &pSrc[(cinfo.image_height - cinfo.next_scanline - 1) * row_stride];
        (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }
    jpeg_finish_compress(&cinfo);

    jpeg_destroy_compress(&cinfo);
    return dwLen;
}

需要用到的头文件

#define JPEG_QUALITY 50
extern "C"
{
#include "jpeglib.h"
#include "jmorecfg.h"
#include "jconfig.h"
}

 

以上是关于MFC 屏幕截图(libjpeg bmp转jpg)的主要内容,如果未能解决你的问题,请参考以下文章

vc 截取屏幕

使用libjpeg-turboYUV转JPG

图像格式转换之BMP格式转换为JPG格式

OpenGL 中的 BMP 屏幕截图

如何在 SDL 2 中获取并保存 BMP 屏幕截图?

JavaCV开发详解之26补充篇:视频连续截图并按日期格式生成图片文件名称,支持png,jpg,bmp等格式快速连续截图