关于WINCE下JPG图片的显示

来源:互联网 发布:js用ajax提交form表单 编辑:程序博客网 时间:2024/05/22 05:30

近期有个需求,要做一个拍照后把图片四个一组显示出来,并且可以删除可以预览,顺便回顾了一下windows的GDI(WIN32)。

一开始使用的方法是

void DrawImage(LPCTSTR szFileName,HDC hdc,RECT rc)
{
    IImagingFactory *pImgFactory = NULL;
    IImage *pImage = NULL;
    FillRect(hdc,&rc,(HBRUSH)GetStockObject(WHITE_BRUSH));
    // Normally you would only call CoInitialize/CoUninitialize
    // once per thread.  This sample calls CoInitialize in this
    // draw function simply to illustrate that you must call
    // CoInitialize before calling CoCreateInstance.

    // Create the imaging factory.
    if (SUCCEEDED(CoCreateInstance (CLSID_ImagingFactory,
        NULL,
        CLSCTX_INPROC_SERVER,
        IID_IImagingFactory,
        (void **)&pImgFactory)))
    {
        // Load the image from the JPG file.
        if (SUCCEEDED(pImgFactory->CreateImageFromFile(
            szFileName,
            &pImage)))
        {
            // Draw the image.
            pImage->Draw(hdc, &rc, NULL);
            pImage->Release();
        }
        pImgFactory->Release();
    }
}
采用这个办法,在WINPAINT的消息中直接把取得的窗体DC穿进去,然后传进去文件名以及画图位置就可以,奈何这种方法要把一张图先解码出来,然后再缩小,再画到指定区域,导致画一张图非常慢,大概在300-400毫秒之间,一张图片还好说,如果是四张图片那就需要1600毫秒,严重影响了程序的流畅度。之后采用了一个分步骤完成的方法,就是图片保存的时候就把图片LOAD到pImage中,之后再在WINPAINT消息中画出来。可是发现速度完全没有一点提高。看来CreateImageFromFile这个函数只是进行了一些准备工作,而解码,画图都是在DRAW函数中完成的。

之后在网上看到打开jpg的另一种方法,用CIMAGE类,结果发现CIMAGE类在CE下进行了限制,只能读入资源内的图片。所以这个解决方案也被否决了。

其实一开始我就想到了双缓冲的办法,无奈没有在WINDOWS的GDI下操作过,也不知道这种方法到底能不能解决我的问题,因为双缓冲算法是解决闪烁的,可是我这个是显示慢。后来,我把双缓冲算法的一部分拿出来,也就是在用户保存的时候,我把这张图通过兼容DC先画一份保存在内存当中,接下来再在显示的时候,把内存中的这几张图拷贝到屏幕上来,最终解决了这个问题。代码:

用户保存图片时,进行如下操作:

BOOL CapturePreviewDlg::LoadJpegImage(LPCTSTR szFileName,int nPicNum)
{
    IImagingFactory *pImgFactory=NULL;
    IImage *pImage=NULL;
    // Normally you would only call CoInitialize/CoUninitialize
    // once per thread.  This sample calls CoInitialize in this
    // draw function simply to illustrate that you must call
    // CoInitialize before calling CoCreateInstance.

    // Create the imaging factory.
    if (SUCCEEDED(CoCreateInstance (CLSID_ImagingFactory,
        NULL,
        CLSCTX_INPROC_SERVER,
        IID_IImagingFactory,
        (void **)&pImgFactory)))
    {
        // Load the image from the JPG file.
        if (SUCCEEDED(pImgFactory->CreateImageFromFile(
            szFileName,
            &pImage)))
        {
            HDC dc=CreateCompatibleDC(NULL);
            DeleteObject(g_Bitmap[nPicNum]);
            g_Bitmap[nPicNum]=CreateBitmap(70,70,1,16,NULL);
            HBITMAP h_oldBit=(HBITMAP)SelectObject(dc,g_Bitmap[nPicNum]);
            RECT temprect={0,0,70,70};
            pImage->Draw(dc,&temprect,NULL);
            SelectObject(dc,h_oldBit);
            DeleteDC(dc);
            pImage->Release();
            return TRUE;
        }
        else
            pImgFactory->Release();
            return FALSE;
    }
    return FALSE;
}

 

用户需要查看图片列表时,进行如下操作

BOOL CaptureImageListDlg::DrawJpegImage(int nPicNum,HDC hdc,RECT rc)
{
    if (g_Bitmap[nPicNum]!=NULL)
    {
        HDC dc=CreateCompatibleDC(NULL);
        HBITMAP h_oldbitmap=(HBITMAP)SelectObject(dc,g_Bitmap[nPicNum]);
        BitBlt(hdc,rc.left,rc.top,70,70,dc,0,0,SRCCOPY);
        SelectObject(dc,h_oldbitmap);
        DeleteDC(dc);
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

原创粉丝点击