2 animada animada 于 2014.12.13 23:15 提问

C++ 处理图片像素时无法读取内存

//bmps 中装的是CImage
for(int i = 0; i < bmps[nIndex].GetHeight(); i++){
for(int j = 0; j < bmps[nIndex].GetWidth();j++){
BYTE * tp1=(BYTE*)bmps[nIndex].GetPixelAddress(i,j);
BYTE * tp2=(BYTE*)bmps[nIndex+1].GetPixelAddress(i,j);
BYTE * tpOut=(BYTE*)bitmap.GetPixelAddress(i,j);
_asm{
emms
mov eax,fadetA

movupd xmm3,[eax]

mov ebx,fadetB
movupd xmm4,[ebx]

            mov ecx,tp1             
            movupd xmm5,[ecx]//这里tp1无法读取内存
            mov edx,tp2
            movupd xmm6,[edx]

            pxor xmm7,xmm7
            punpcklbw   xmm5,xmm7       
            punpcklbw   xmm6,xmm7
            punpcklbw   xmm3,xmm7       
            punpcklbw   xmm4,xmm7

            pmullw      xmm5,xmm3
            pmullw      xmm6,xmm4
            psrlw       xmm5,8  
            psrlw       xmm6,8  
            paddw       xmm5,xmm6   

            packuswb    xmm5,xmm7               

            mov edi,tpOut
            movsd [edi],xmm5                

            EMMS;           
            }
        }
    }
    delete []fadetA;
    delete []fadetB;
    //tmp = bitmap;
    //CDC* pDC;
    //pDC = GetWindowDC();  
    //bitmap.Draw(pDC->m_hDC,0,0);  
    Ondraw();
}

3个回答

chenlycly
chenlycly   Rxr 2014.12.14 10:44
已采纳

给你一段代码参考一下:
CImage* CCatchScreenDlg::LoadCImage( UINT nID, LPCTSTR lpszType, HINSTANCE hInstance )
{
CImage* pImage = NULL;

hInstance = ( NULL == hInstance ) ? ::AfxGetResourceHandle() : hInstance;

if( RT_BITMAP == lpszType )
{
    pImage = new CImage();
    pImage->LoadFromResource( hInstance, nID );
    if ( !pImage->IsNull() )
    {
        return pImage;
    }
    else
    {
        WriteScreenCatchLog( _T("[CCatchScreenDlg::LoadCImage]CImage::LoadFromResource失败") );

        delete pImage;
        pImage = NULL;
        return NULL;
    }
}   

CString strLog;
HRSRC hRsrc = ::FindResource( hInstance, MAKEINTRESOURCE(nID), lpszType ); 
ASSERT( hRsrc != NULL );
if ( NULL == hRsrc ) 
{
    WriteScreenCatchLog( _T("[CCatchScreenDlg::LoadCImage]::FindResource失败") );
    return NULL;
}

DWORD dwSize = ::SizeofResource( hInstance, hRsrc);
LPBYTE lpRsrc = (LPBYTE)::LoadResource( hInstance, hRsrc);
ASSERT( lpRsrc != NULL );
if ( NULL == hRsrc ) 
{
    WriteScreenCatchLog( _T("[CCatchScreenDlg::LoadCImage]::LoadResource失败") );
    return NULL;
}

HGLOBAL hMem = ::GlobalAlloc( GMEM_FIXED, dwSize );
if ( NULL == hMem ) 
{
    WriteScreenCatchLog( _T("[CCatchScreenDlg::LoadCImage]::GlobalAlloc失败") );

    ::FreeResource( lpRsrc );
    return NULL;
}

LPBYTE pMem = (LPBYTE)::GlobalLock( hMem );
if ( NULL == pMem ) 
{
    WriteScreenCatchLog( _T("[CCatchScreenDlg::LoadCImage]::GlobalLock失败") );

    ::GlobalUnlock( hMem );
    ::GlobalFree( hMem );
    ::FreeResource( lpRsrc );
    return NULL;
}

memcpy( pMem, lpRsrc, dwSize );
IStream * pStream = NULL;
HRESULT hr = ::CreateStreamOnHGlobal( hMem, FALSE, &pStream );
if ( pStream != NULL && hr == S_OK ) 
{
    pImage = new CImage();
    HRESULT hrs = pImage->Load( pStream );

    pStream->Release();

    //释放
    ::GlobalUnlock( hMem );
    ::GlobalFree( hMem );
    ::FreeResource( lpRsrc );

    if ( hrs == S_OK )
    {
        if ( pImage->GetBPP() == 32 )
        {
            for(int i = 0; i < pImage->GetWidth(); i++)   
            {   
                for(int j = 0; j < pImage->GetHeight(); j++)   
                {   
                    unsigned char* pucColor = reinterpret_cast<unsigned char *>(pImage->GetPixelAddress(i , j));   
                    pucColor[0] = pucColor[0] * pucColor[3] / 255;   
                    pucColor[1] = pucColor[1] * pucColor[3] / 255;   
                    pucColor[2] = pucColor[2] * pucColor[3] / 255;   
                }   
            }
        }

        return pImage;
    }
    else
    {
        delete pImage;
        pImage = NULL;
        return NULL;
    }
}
else
{
    WriteScreenCatchLog( _T("[CCatchScreenDlg::LoadCImage]::CreateStreamOnHGlobal失败") );

    ::GlobalUnlock( hMem );
    ::GlobalFree( hMem );
    ::FreeResource( lpRsrc );
    return NULL;
}

}


caozhy
caozhy   Ds   Rxr 2014.12.14 00:12

看代码这不是C++而是汇编,而且用的是MMX,不知道你要做什么。

caozhy
caozhy   Ds   Rxr 2014.12.14 00:13

一般来说,像像素的饱和运算之类的,直接用C++写,用Intel C++编译器,可以产生质量很高的iSSE2/iSSE3指令,手写MMX指令早就没人干了。

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!