i have these code for get image pixel data:

typedef std::vector<BYTE> pixeldata;
pixeldata GetImagePixel(HDC hdcImage)
{
    BITMAP bmp = {0};
    BITMAPINFO Info = {0};
    memset( &bmp, 0, sizeof(BITMAP) );
    HBITMAP hBitmap =(HBITMAP) GetCurrentObject(hdcImage, OBJ_BITMAP);
    GetObject(hBitmap, sizeof(BITMAP), &bmp);

    BITMAPINFO info { };
    info.bmiHeader.biSize = sizeof(info.bmiHeader);
    info.bmiHeader.biWidth = bmp.bmWidth;
    // pay attention to the sign, you most likely want a
    // top-down pixel array as it's easier to use
    info.bmiHeader.biHeight = -bmp.bmHeight;
    info.bmiHeader.biPlanes = 1;
    info.bmiHeader.biBitCount = 32;
    info.bmiHeader.biCompression = BI_RGB;

    // the following calculations work for 16/24/32 bits bitmaps
    // but assume a byte pixel array
    size_t pixelSize = info.bmiHeader.biBitCount / 8;
    // the + 3 ) & ~3 part is there to ensure that each
    // scan line is 4 byte aligned
    size_t scanlineSize = (pixelSize * info.bmiHeader.biWidth + 3) & ~3;
    size_t bitmapSize = bmp.bmHeight * scanlineSize;

    pixeldata pixels(bitmapSize);
    GetDIBits(hdcImage, hBitmap, 0, bmp.bmHeight, &pixels[0], &info, DIB_RGB_COLORS);
    bmp.bmHeight = std::abs(bmp.bmHeight);
    return pixels;
}

void SetImageData(HDC hdcDestination, pixeldata pixels)
{
    BITMAP bmp = {0};
    BITMAPINFO Info = {0};
    memset( &bmp, 0, sizeof(BITMAP) );
    HBITMAP hBitmap =(HBITMAP) GetCurrentObject(hdcDestination, OBJ_BITMAP);
    GetObject(hBitmap, sizeof(BITMAP), &bmp);
    BITMAPINFO info { };
    info.bmiHeader.biSize = sizeof(info.bmiHeader);
    info.bmiHeader.biWidth = bmp.bmWidth;
    // pay attention to the sign, you most likely want a
    // top-down pixel array as it's easier to use
    info.bmiHeader.biHeight = -bmp.bmHeight;
    info.bmiHeader.biPlanes = 1;
    info.bmiHeader.biBitCount = 32;
    info.bmiHeader.biCompression = BI_RGB;

    SetDIBits(hdcDestination, hBitmap, 0, bmp.bmHeight, &pixels[0], &info, DIB_RGB_COLORS);
}
//how use it
/*pixeldata pixels=GetImagePixel(imgImage);

size_t pixelSize = bm.bmBitsPixel / 8;
size_t scanlineSize = (pixelSize * bm.bmWidth + 3) & ~3;

int x=0, y=0;
for(y=0; y<imgImage.height(); y++)
{
    for(x=0; x<imgImage.width(); x++)
    {
        size_t pixelOffset = y * scanlineSize + x * pixelSize;

        COLORREF clrActualColor=RGB(pixels[pixelOffset+2],pixels[pixelOffset+1],pixels[pixelOffset+ 0]);
        if(clrActualColor ==RGB(0,0,0))
        {
            pixels[pixelOffset+2]=GetRValue(GetSysColor(COLOR_MENU));
            pixels[pixelOffset+1]=GetGValue(GetSysColor(COLOR_MENU));
            pixels[pixelOffset+0]=GetBValue(GetSysColor(COLOR_MENU));
        }
    }
}
SetImageData(hMemDC,pixels);*/

from these functions, i did my own shadow effect:

void Shadow(int PosX=0, int PosY=0)
    {
        pixeldata pixels=GetImagePixel(HBitmap);

        size_t pixelSize = HBitmap.bitperpixel() / 8;
        size_t scanlineSize = (pixelSize * HBitmap.Width() + 3) & ~3;

        int x=0, y=0;
        COLORREF BackColor;
        for(y=0; y<HBitmap.Height(); y++)
        {
            for(x=0; x<HBitmap.Width(); x++)
            {
                //getting pixel and drawed pixel positions:
                size_t pixelOffset = y * scanlineSize + x * pixelSize;//actual pixel position
                size_t pixelOffset2 = (y+PosY) * scanlineSize + (x+PosX) * pixelSize; //the position where the shadow pixel is drawed

                //gettin backcolor:
                if(x==0 && y==0)
                    BackColor=RGB(pixels[pixelOffset+2],pixels[pixelOffset+1],pixels[pixelOffset+ 0]);

                //getting actual color:
                COLORREF clrActualColor=RGB(pixels[pixelOffset+2],pixels[pixelOffset+1],pixels[pixelOffset+ 0]);
                if(clrActualColor !=BackColor)//if the actual color is diferent of backcolor then:
                {
                    //if the drawed pixel position is backcolor pixel, then draw it:
                    if(RGB(pixels[pixelOffset2+2],pixels[pixelOffset2+1],pixels[pixelOffset2+0])==BackColor && RGB(pixels[pixelOffset2+2],pixels[pixelOffset2+1],pixels[pixelOffset2+0])!=CLR_INVALID)
                    {
                        pixels[pixelOffset2+2]=GetRValue(0);
                        pixels[pixelOffset2+1]=GetGValue(0);
                        pixels[pixelOffset2+0]=GetBValue(0);
                    }

                }
            }
        }
        SetImageData(HBitmap,pixels);
    }

(objective: these function just add some black pixels to the image, for do a shadow effect)
but or i miss understood how can i calculate the next pixel position(depending on PosX and PosY), or i don't know(the pixelOffset2):(
the image show us the results :(
shadow_problem2.png

after several tests, i fixed the function:

void Shadow(int PosX=0, int PosY=0, COLORREF ShadowColor=RGB(0,0,0))
    {
        pixeldata pixels=GetImagePixel(HBitmap);

        size_t pixelSize = HBitmap.bitperpixel() / 8;
        size_t scanlineSize = (pixelSize * HBitmap.Width() + 3) & ~3;

        int x=0, y=0;
        COLORREF BackColor;
        for(y=0; y<HBitmap.Height(); y++)
        {
            for(x=0; x<HBitmap.Width(); x++)
            {
                if((y+PosY)>=HBitmap.Height() || (x+PosX)>=HBitmap.Width())
                    continue;
                //getting pixel and drawed pixel positions:
                size_t pixelOffset = y * scanlineSize + x * pixelSize;//actual pixel position
                size_t pixelOffset2 =(y+PosY) * scanlineSize + (x+PosX) * pixelSize; //the position where the shadow pixel is drawed

                //gettin backcolor:
                if(x==0 && y==0)
                {
                   BackColor=RGB(pixels[pixelOffset+2],pixels[pixelOffset+1],pixels[pixelOffset+ 0]);
                }


                //getting actual color:
                COLORREF clrActualColor=RGB(pixels[pixelOffset+2],pixels[pixelOffset+1],pixels[pixelOffset+ 0]);
                COLORREF clrActualColor2=RGB(pixels[pixelOffset2+2],pixels[pixelOffset2+1],pixels[pixelOffset2+ 0]);
                if((clrActualColor!=BackColor && clrActualColor!=ShadowColor)&& clrActualColor2==BackColor)//if the actual color is diferent of backcolor then:
                {
                    pixels[pixelOffset2+2]=GetRValue(ShadowColor);
                    pixels[pixelOffset2+1]=GetGValue(ShadowColor);
                    pixels[pixelOffset2+0]=GetBValue(ShadowColor);
                }
            }
        }
        SetImageData(HBitmap,pixels);
    }

i did several mistakes:
1 - i didn't tested the x+PosX and y+PosY limits;
2 - i was not testing, correctly, the clrActualColor.
i hope these topic make the readers thinking where i did the mistakes and why ;)
shadow_effect.png

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.