duilib加载网络图片到程序

来源:赵克立博客 分类: C/C++ 标签:duilib发布时间:2017-11-25 10:18:02最后更新:2019-10-30 15:20:15浏览:5658
版权声明:
本文为博主原创文章,转载请声明原文链接...谢谢。o_0。
更新时间:
2019-10-30 15:20:15
温馨提示:
学无止境,技术类文章有它的时效性,请留意文章更新时间,如发现内容有误请留言指出,防止别人"踩坑",我会及时更新文章

duilib做网络开发的时候肯定会用到把图片从网络直接下载后加载到程序里的功能。网络下载图片后一般都是存在字节数组里,如果保存到本地后再用duilib加载就很简单啦,直接设置路径就可以加载,但是下载后本来就是在内存的,如果再保存到本地再加载到程序,麻烦啦一步效率还不好。下面添加一个方法实现直接从内存加载图片数据使用。

首先在CRenderEngine 这个类中添加一个从内存中加载图片数据转成HBITMAP的函数,原来已经有一个函数啦。只不过是传入一个图片字符串路径。然后读取到内存返回的。这里只是把原来的代码修改下直接从内存取数据转成HBITMAP

HBITMAP CRenderEngine::LoadImage(unsigned char* bytesImg,DWORD bytesLength, LPCTSTR type , DWORD mask)
{
    LPBYTE pImage = NULL;
    int x = 1, y = 1, n;
    if (!type || _tcscmp(type, RES_TYPE_COLOR) != 0) {
        pImage = stbi_load_from_memory(bytesImg, bytesLength, &x, &y, &n, 4);
        //delete[] pData;
        if (!pImage) {
            //::MessageBox(0, _T("解析图片失败"), _T("抓BUG"), MB_OK);
            return NULL;
        }
    }
    BITMAPINFO bmi;
    ::ZeroMemory(&bmi, sizeof(BITMAPINFO));
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = x;
    bmi.bmiHeader.biHeight = -y;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biSizeImage = x * y * 4;
    bool bAlphaChannel = false;
    LPBYTE pDest = NULL;
    HBITMAP hBitmap = ::CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void**)&pDest, NULL, 0);
    if (!hBitmap) {
        //::MessageBox(0, _T("CreateDIBSection失败"), _T("抓BUG"), MB_OK);
        return NULL;
    }
    //BYTE bColorBits[4] = { 0 };
    //if (type && _tcscmp(type, RES_TYPE_COLOR) == 0) {
    //  LPTSTR pstr = NULL;
    //  LPCTSTR pstrValue = bitmap.m_lpstr;
    //  if (*pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
    //  DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
    //  pImage = (LPBYTE)&clrColor;
    //  /* BGRA -> RGBA */
    //  bColorBits[3] = pImage[3];
    //  bColorBits[2] = pImage[0];
    //  bColorBits[1] = pImage[1];
    //  bColorBits[0] = pImage[2];
    //  pImage = bColorBits;
    //}
    for (int i = 0; i < x * y; i++)
    {
        pDest[i * 4 + 3] = pImage[i * 4 + 3];
        if (pDest[i * 4 + 3] < 255)
        {
            pDest[i * 4] = (BYTE)(DWORD(pImage[i * 4 + 2])*pImage[i * 4 + 3] / 255);
            pDest[i * 4 + 1] = (BYTE)(DWORD(pImage[i * 4 + 1])*pImage[i * 4 + 3] / 255);
            pDest[i * 4 + 2] = (BYTE)(DWORD(pImage[i * 4])*pImage[i * 4 + 3] / 255);
            bAlphaChannel = true;
        }
        else
        {
            pDest[i * 4] = pImage[i * 4 + 2];
            pDest[i * 4 + 1] = pImage[i * 4 + 1];
            pDest[i * 4 + 2] = pImage[i * 4];
        }
        if (*(DWORD*)(&pDest[i * 4]) == mask) {
            pDest[i * 4] = (BYTE)0;
            pDest[i * 4 + 1] = (BYTE)0;
            pDest[i * 4 + 2] = (BYTE)0;
            pDest[i * 4 + 3] = (BYTE)0;
            bAlphaChannel = true;
        }
    }
    if (!type || _tcscmp(type, RES_TYPE_COLOR) != 0) {
        stbi_image_free(pImage);
    }
    //TImageInfo* data = new TImageInfo;
    //data->hBitmap = hBitmap;
    //data->pBits = pDest;
    //data->nX = x;
    //data->nY = y;
    //data->bAlpha = bAlphaChannel;
    //data->bUseHSL = false;
    //data->pSrcBits = NULL;
    //return data;
    return hBitmap;
}

使用方法如下

//下面随后演示从网络下载图片后加载
TCHAR bdurl[] = _T("http://www.zhaokeli.com/public/home/blog/images/touxiang.jpg");
//定义接收图片的缓冲区..
unsigned char lpPicBuff[1024 * 100] = { 0 };
DWORD dwSize = 1024 * 1000;
Ank::Helper::DownloadFile(bdurl, _T(""), NULL, _T(""), lpPicBuff,&dwSize);
//字节数据转成位图
HBITMAP img=CRenderEngine::LoadImage(lpPicBuff, dwSize);
BITMAP bmp;
GetObject(img, sizeof(BITMAP), &bmp);
// 先释放图片占用内存(会自动判断不存在的话返回),防止多次加载时内存泄露
m_PaintManager.RemoveImage(bdurl);
m_PaintManager.AddImage(bdurl,img,bmp.bmWidth,bmp.bmHeight,true);
m_pBtnLoadImg->SetHotImage(bdurl);

上面代码中从网络下载图片的代码需要自己实现。

效果

1910301572407116896943.gif


微信号:kelicom QQ群:215861553 紧急求助须知
Win32/PHP/JS/Android/Python