Board index » cppbuilder » Fade In / Out A BMP

Fade In / Out A BMP

Hi,

I've just recently started looking at graphics in Builder 3.  Not getting on
too bad except that everything I do is simply too slow.  The prob I have is
i need to fade in / out a 24bit 640x480 BMP.  I can do the fading ok its
just thats its very slow.

Basically I have a TImage and traverse the bitmap data with two loops, one
for the row's and one for the cols.  I use ScanLine to get the actual bitmap
data and simply increase the RGB values in various steps.  Nothing too
exciting.

I would be very grateful if someone could advise me if there is a faster way
to process the bits in a bitmap.  I'm thinking of droping down to assembler
unless someone can advise me otherwise.

While I'm here any one got any assembler routines for graphic manipulation.

Thanks in advance.

Sam

 

Re:Fade In / Out A BMP


Show us your code!

Re:Fade In / Out A BMP


Hi Sam,

Quote
> I would be very grateful if someone could advise me if there is a faster way
> to process the bits in a bitmap.  I'm thinking of droping down to assembler
> unless someone can advise me otherwise.

Here's an example of a DIB approach, however, this too may be too slow for your
needs...

//in header...
    float factor;
    Graphics::TBitmap *Bitmap;
    HBITMAP HBitmap, HOldBitmap;
    HDC HBitmapDC;
    BITMAPINFO bmi;
    unsigned char *bits;
    unsigned char *alteredbits;

//in source...

#define CLIPMAX(x) \
        x > 255 ? 255 : x

#define CLIPMIN(x) \
        x < 0 ? 0 : x

bool BMInfoFromHandle(HBITMAP Hbm, LPBITMAPINFO lpbi);
int BitsFromHandle(HBITMAP Hbm, LPBITMAPINFO lpbi, unsigned char *bits);
void RenderBits(HBITMAP Hbm, LPBITMAPINFO lpbi, unsigned char *bits);

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    Bitmap = Image1->Picture->Bitmap;
    HBitmap = Bitmap->ReleaseHandle();

    HDC Hdc = GetDC(0);
    HBitmapDC = CreateCompatibleDC(Hdc);
    ReleaseDC(0, Hdc);

    HOldBitmap = SelectObject(HBitmapDC, HBitmap);

    bits = NULL;
    alteredbits = NULL;
    if (BMInfoFromHandle(HBitmap, &bmi))
    {
        bits = new unsigned char[bmi.bmiHeader.biSizeImage];
        alteredbits = new unsigned char[bmi.bmiHeader.biSizeImage];
        BitsFromHandle(HBitmap, &bmi, bits);
    }

Quote
}

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
    Bitmap->Handle = HBitmap;
    SelectObject(HBitmapDC, HOldBitmap);
    DeleteDC(HBitmapDC);

    if (alteredbits) delete [] alteredbits;
    if (bits) delete [] bits;

Quote
}

bool BMInfoFromHandle(HBITMAP Hbm, LPBITMAPINFO lpbi)
{
    // Get the diemnsions of the bitmap
    BITMAP bmp;
    GetObject(Hbm, sizeof(BITMAP), &bmp);

    // Initialize some of the BitmapInfo structure
    lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    lpbi->bmiHeader.biWidth = bmp.bmWidth;
    lpbi->bmiHeader.biHeight = bmp.bmHeight;
    lpbi->bmiHeader.biPlanes = 1;
    lpbi->bmiHeader.biBitCount = 24;
    lpbi->bmiHeader.biCompression = BI_RGB;

    // use screen's DC for the call to GetDIBits
    HDC ScreenDC = GetDC(NULL);

    // Call GetDiBits first with a NULL lpBits
    // parameter so the device driver
    // will calculate the biSizeImage field to
    // tell us how much memory to allocate
    // for the Bits
    GetDIBits(ScreenDC, Hbm, 0,
              lpbi->bmiHeader.biHeight,
              NULL, lpbi, DIB_RGB_COLORS);

    // if the driver didn't calculate the size
    // lets estimate it ourselves
    if (lpbi->bmiHeader.biSizeImage == 0)
    {
        lpbi->bmiHeader.biSizeImage =
            ((((bmp.bmWidth * 24) + 31) & ~31) / 8) *
            bmp.bmHeight;
    }

    return lpbi->bmiHeader.biSizeImage;

Quote
}

int BitsFromHandle(HBITMAP Hbm, LPBITMAPINFO lpbi, unsigned char *bits)
{
    HDC Hdc = GetDC(NULL);

    int result = GetDIBits(Hdc, Hbm, 0,
                           lpbi->bmiHeader.biHeight,
                           bits, lpbi, DIB_RGB_COLORS);
    ReleaseDC(0, Hdc);
    return result;

Quote
}

void RenderBits(HBITMAP Hbm, LPBITMAPINFO lpbi, unsigned char *bits)
{
    HDC Hdc = GetDC(0);

    // set the bits to the bitmap
    SetDIBits(Hdc, Hbm, 0, lpbi->bmiHeader.biHeight,
              bits, lpbi, DIB_RGB_COLORS);

    ReleaseDC(0, Hdc);

Quote
}

void __fastcall TForm1::FadeBitmap()
{
    int bytesPerLine = bmi.bmiHeader.biWidth *
                       (bmi.bmiHeader.biBitCount / 8);

    for (int y = 0; y < bmi.bmiHeader.biHeight; y++)
    {
        int row = bytesPerLine * y;
        for (int x = 0; x < bytesPerLine; x++)
        {
            *(alteredbits + x + row) =
                CLIPMAX(CLIPMIN(factor * (float)(*(bits + x + row))));
        }
    }

    RenderBits(HBitmap, &bmi, alteredbits);
    BitBlt(Canvas->Handle, 0, 0, bmi.bmiHeader.biWidth,
           bmi.bmiHeader.biHeight, HBitmapDC, 0, 0,
           SRCCOPY);

Quote
}

void __fastcall TForm1::ScrollBar1Change(TObject *Sender)
{
    factor = (float)ScrollBar1->Position / 100.0;
    FadeBitmap();

Quote
}

Good luck.

--------------------------------------
Damon Chandler

http://bcbcaq.freeservers.com
Answers to <Commonly Asked Questions>

Re:Fade In / Out A BMP


Thanks for all your help

Sam

Other Threads