TImage->Canvas->Pixels is very slow...

TImage->Canvas->Pixels is very slow...

Post by Thierry Verrecchi » Thu, 05 Mar 1998 04:00:00



Hi,

I would like to change the RGB value of the pixels of a TCanvas.
Here's my code:

int n = (50 + (50<<8) + (50 <<16));
for (int y = 1; y < 70;y++)
  for (int x = 1;x < 500; x++)
    Image1->Canvas->Pixels[x][y] = Image1->Canvas->Pixels[x][y]-n;

And it's very slow..
Does anyone have another way to do it?

Thanks in advance.

--
Thierry Verrecchia, VP R&D

 
 
 

TImage->Canvas->Pixels is very slow...

Post by Jonathan Arnol » Thu, 05 Mar 1998 04:00:00


Quote:> for (int y = 1; y < 70;y++)
>   for (int x = 1;x < 500; x++)
>     Image1->Canvas->Pixels[x][y] = Image1->Canvas->Pixels[x][y]-n;
> And it's very slow..
> Does anyone have another way to do it?

Yes, it is slow because it use Get/SetPixel call on each pixel, which
is slow.  The fastest way to do it would be to use the Win32 API
GetDIBits, which will set up a DIB.  Then you can go thru the pixels
just like you'd want to, as a simple memory array.

+===================================================+

| Programmer                Roger Wagner Publishing |
| http://world.std.com/~jdarnold                    |
+===================================================+

 
 
 

TImage->Canvas->Pixels is very slow...

Post by darren dwye » Sun, 15 Mar 1998 04:00:00


Yes you can use GetDIBBits (there was an article in this forum somewhere
about it - try borland.public.cppbuilder.winapi ) as the VCL objects supply
relevant windows api "Handle"s. (eg. Canvas->Handle, Form->Handle, etc.)

the Win32 API documentation is found in the file :-
    \borland\cbuilder\help\mshelp\Win32.Hlp

- darren


> >Yes, it is slow because it use Get/SetPixel call on each pixel, which
> >is slow.  The fastest way to do it would be to use the Win32 API
> >GetDIBits, which will set up a DIB.  Then you can go thru the pixels
> >just like you'd want to, as a simple memory array.

> >+===================================================+

> >| Programmer                Roger Wagner Publishing |
> >| http://world.std.com/~jdarnold                    |
> >+===================================================+

> Can I use the GetDIBits with BCB or I need other program? Why do you say
> that is a Win32 API? I am working with pixels and I didn't find the
> GetDIBits function or wherever on BCB to work with!

> Any comment is welcome!

> Fausto Tapia


--
-----------------------------------------------------------------------
to contact me, please send email to the following addresses..




-----------------------------------------------------------------------

 
 
 

TImage->Canvas->Pixels is very slow...

Post by Excepti » Sun, 15 Mar 1998 04:00:00


*  Jonathan Arnold wrote
*  >Yes, it is slow because it use Get/SetPixel call on each pixel, which
*  >is slow.  The fastest way to do it would be to use the Win32 API
*  >GetDIBits, which will set up a DIB.  Then you can go thru the pixels
*  >just like you'd want to, as a simple memory array.
*
*  Can I use the GetDIBits with BCB or I need other program? Why do you say
*  that is a Win32 API? I am working with pixels and I didn't find the
*  GetDIBits function or wherever on BCB to work with!

Typically, for fast pixel painting, you'll request a 'Dib section' from windows,
which is a standard surface on with you can directly place pixel values.
'Dib' stands for 'device independent bitmap'.

The functions you're looking for are CreateDIBSection() and SetDIBitsToDevice().

I've included some sample code to show you how to do this.
Drop a TImage on a form and run:

void __fastcall TForm1::FormShow(TObject *Sender)
{
// Request a surface to draw on
BITMAPINFO Bmi;
ZeroMemory(&Bmi.bmiHeader,sizeof(Bmi.bmiHeader));
Bmi.bmiHeader.biSize=sizeof(Bmi.bmiHeader);
Bmi.bmiHeader.biWidth=200;
Bmi.bmiHeader.biHeight=-200; // Negative: top-down bitmap
Bmi.bmiHeader.biPlanes=1;
Bmi.bmiHeader.biBitCount=24; // R,G,B triplets
Bmi.bmiHeader.biCompression=BI_RGB;
BYTE *Pix;
CreateDIBSection(0,&Bmi,DIB_RGB_COLORS,(void **)&Pix,0,0);
GdiFlush();

// Paint an interesting pattern, directly in the pixel buffer
BYTE *p=Pix;
BYTE r,g,b;
for (int x=0;x<200;x++)
        for (int y=0; y<200;y++) {
                r=128.0+127.0*sin(0.1*x);
                g=128.0+127.0*cos(0.1*y);
                b=sqrt(x*x+y*y);
                *p++=b;
                *p++=g;
                *p++=r;
                }

// Show it in an TImage component on the form
Image1->Picture->Bitmap->Width=200;
Image1->Picture->Bitmap->Height=200;
SetDIBitsToDevice(Image1->Picture->Bitmap->Canvas->Handle,0,0, 200,200,
                     0,0, 0,200, Pix,&Bmi,DIB_RGB_COLORS);

// Resize container to fit
Form1->ClientWidth=200;
Form1->ClientHeight=200;
Image1->Top=0;
Image1->Left=0;
Image1->Width=200;
Image1->Height=200;

Quote:}

---
Design your Exception class hierarchy well...

       VCL+MFC+API+OCX == new *Modern_Developer;

 
 
 

TImage->Canvas->Pixels is very slow...

Post by Jeff Cottingha » Tue, 17 Mar 1998 04:00:00




> *  Jonathan Arnold wrote
> *  >Yes, it is slow because it use Get/SetPixel call on each pixel,
> which
> *  >is slow.  The fastest way to do it would be to use the Win32 API
> *  >GetDIBits, which will set up a DIB.  Then you can go thru the
> pixels
> *  >just like you'd want to, as a simple memory array.
> *
> *  Can I use the GetDIBits with BCB or I need other program? Why do
> you say
> *  that is a Win32 API? I am working with pixels and I didn't find the

> *  GetDIBits function or wherever on BCB to work with!

> Typically, for fast pixel painting, you'll request a 'Dib section'
> from windows,
> which is a standard surface on with you can directly place pixel
> values.
> 'Dib' stands for 'device independent bitmap'.

> The functions you're looking for are CreateDIBSection() and
> SetDIBitsToDevice().

> I've included some sample code to show you how to do this.
> Drop a TImage on a form and run:

> void __fastcall TForm1::FormShow(TObject *Sender)
> {
> // Request a surface to draw on
> BITMAPINFO Bmi;
> ZeroMemory(&Bmi.bmiHeader,sizeof(Bmi.bmiHeader));
> Bmi.bmiHeader.biSize=sizeof(Bmi.bmiHeader);
> Bmi.bmiHeader.biWidth=200;
> Bmi.bmiHeader.biHeight=-200; // Negative: top-down bitmap
> Bmi.bmiHeader.biPlanes=1;
> Bmi.bmiHeader.biBitCount=24; // R,G,B triplets
> Bmi.bmiHeader.biCompression=BI_RGB;
> BYTE *Pix;
> CreateDIBSection(0,&Bmi,DIB_RGB_COLORS,(void **)&Pix,0,0);
> GdiFlush();

> // Paint an interesting pattern, directly in the pixel buffer
> BYTE *p=Pix;
> BYTE r,g,b;
> for (int x=0;x<200;x++)
>         for (int y=0; y<200;y++) {
>                 r=128.0+127.0*sin(0.1*x);
>                 g=128.0+127.0*cos(0.1*y);
>                 b=sqrt(x*x+y*y);
>                 *p++=b;
>                 *p++=g;
>                 *p++=r;
>                 }

> // Show it in an TImage component on the form
> Image1->Picture->Bitmap->Width=200;
> Image1->Picture->Bitmap->Height=200;
> SetDIBitsToDevice(Image1->Picture->Bitmap->Canvas->Handle,0,0,
> 200,200,
>                      0,0, 0,200, Pix,&Bmi,DIB_RGB_COLORS);

> // Resize container to fit
> Form1->ClientWidth=200;
> Form1->ClientHeight=200;
> Image1->Top=0;
> Image1->Left=0;
> Image1->Width=200;
> Image1->Height=200;
> }

> ---
> Design your Exception class hierarchy well...

>        VCL+MFC+API+OCX == new *Modern_Developer;

  BCB 3 lets you do this through the scanline property.<vbg>

-jc
--
Three frameworks for the elven-kings under the skys,
Seven for the Dwarf-loads in their halls of stone,
Nine for the mortal men doomed to die,
In the land of Mordor where the shadows lie,
One framework to rule them all, One framework to find them,
One framework to bring them all and in darkness bind them,
In the land of Mordor where the shadows lie,
It is written that MFC will die,
In the light, the VCL is born
The new age of freedom is upon us,
Borland sounds its mighty horn,
The evil empire cowers in sudden fear,
As it knows the end is near...............

 
 
 

TImage->Canvas->Pixels is very slow...

Post by Excepti » Wed, 18 Mar 1998 04:00:00


*
*  > CreateDIBSection(0,&Bmi,DIB_RGB_COLORS,(void **)&Pix,0,0);
*  > // Paint an interesting pattern, directly in the pixel buffer
*  > BYTE *p=Pix;
*  > BYTE r,g,b;
*  > for (int x=0;x<200;x++)
*  >         for (int y=0; y<200;y++) {
*  >                 r=128.0+127.0*sin(0.1*x);
*  >                 g=128.0+127.0*cos(0.1*y);
*  
*    BCB 3 lets you do this through the scanline property.<vbg>

And does the scanline property interprets RGB triplets, and does it convert/pack them
into the current device dependent bitmap format before transferring to the screen?

Well, at least I know the DIB from the example above can always be filled with RGB
triplets, independent of current screen settings. The SetDIBitsToDevice() call will
do the RGB->Any-pixel-format conversion for me.

I guess that with the scanline property, you have to write code which handles 16-bit,
256-color palettized, 16 bit, 24 bit and 32 bit screen drawing code. Argh!!

---
Design your Exception class hierarchy well...

       VCL+MFC+API+OCX == new *Modern_Developer;

 
 
 

TImage->Canvas->Pixels is very slow...

Post by Fausto Tapi » Wed, 18 Mar 1998 04:00:00


Quote:>void __fastcall TForm1::FormShow(TObject *Sender)
>{
>// Request a surface to draw on
>BITMAPINFO Bmi;
>ZeroMemory(&Bmi.bmiHeader,sizeof(Bmi.bmiHeader));
>Bmi.bmiHeader.biSize=sizeof(Bmi.bmiHeader);
>Bmi.bmiHeader.biWidth=200;
>Bmi.bmiHeader.biHeight=-200; // Negative: top-down bitmap
>Bmi.bmiHeader.biPlanes=1;
>Bmi.bmiHeader.biBitCount=24; // R,G,B triplets
>Bmi.bmiHeader.biCompression=BI_RGB;
>BYTE *Pix;
>CreateDIBSection(0,&Bmi,DIB_RGB_COLORS,(void **)&Pix,0,0);
>GdiFlush();

>// Paint an interesting pattern, directly in the pixel buffer
>BYTE *p=Pix;
>BYTE r,g,b;
>for (int x=0;x<200;x++)
> for (int y=0; y<200;y++) {
> r=128.0+127.0*sin(0.1*x);
> g=128.0+127.0*cos(0.1*y);
> b=sqrt(x*x+y*y);
> *p++=b;
> *p++=g;
> *p++=r;
> }

>// Show it in an TImage component on the form
>Image1->Picture->Bitmap->Width=200;
>Image1->Picture->Bitmap->Height=200;
>SetDIBitsToDevice(Image1->Picture->Bitmap->Canvas->Handle,0,0, 200,200,
>                     0,0, 0,200, Pix,&Bmi,DIB_RGB_COLORS);

>// Resize container to fit
>Form1->ClientWidth=200;
>Form1->ClientHeight=200;
>Image1->Top=0;
>Image1->Left=0;
>Image1->Width=200;
>Image1->Height=200;
>}

>---
>Design your Exception class hierarchy well...

>       VCL+MFC+API+OCX == new *Modern_Developer;

Hello!
 This above work well, but I didn't understand where did you assing a value
to "Pix" or how does it works?
   I've tried to get the same color image to another array with the
following:

// Get color table from image1
tagRGBQUAD *CBuff;
GetDIBColorTable(Image1->Picture->Bitmap->Canvas->Handle,0,256,CBuff);
// CBuff->rgbRed; get the red intensity of what pixel or is a matriz?

or

// get bits from image1
BYTE *Apun;
GetDIBits(Image1->Picture->Bitmap->Canvas->Handle,
     0,0,972,Apun,&Bmi,DIB_RGB_COLORS);

With GetColorTable I think that I get a pointer  "CBuff" to the beginning of
the matriz of color, but when I try to draw it again, I can't do it, I mean
it draw blank.
   With GetDIBits I think that "Apun" is the pointer in this case but I try
to draw it again with the same code that you give me changing "Pix" with
"Apun" and it doesn't works neither.

   Thank for your help, it is very helpfull for me!
Fausto Tapia

 
 
 

TImage->Canvas->Pixels is very slow...

Post by Dave Weadoc » Sat, 28 Mar 1998 04:00:00


Thank you for the hints, but a few questions remain.

Basically, I need to create a new 512 x 512 x 24 bit bitmap
from 12 bit greyscale data with each WM_MOUSEMOVE,
so I need to minimize creates and destroys. Has anyone
used CreateDIBSection with FileMapping Objects? I
already use them for the original data - I imagine I
could use the same object and specify a value in dwOffset.
I already have working code, but I use a TBitmap and
SetDIBits and TBitmap::Assign, and your method seems
more straight-forward.

Quote:> What clean up do I need to perform for:

1. Pix - Anything?    How long can I use this pointer? Until I delete the HBITMAP?
   Can I still use it after SetDIBits? Will it still refer to the
   same bitmap?

2. What about the HBITMAP that CreateDIBSection returns.
    I imagine DeleteObject() when I'm done. Should I delete
    it right away?TIA,
Signed,

Slightly Unclear on the Concept.

Quote:> The functions you're looking for are CreateDIBSection() and SetDIBitsToDevice().
> void __fastcall TForm1::FormShow(TObject *Sender)
> {
> // Request a surface to draw on
> BITMAPINFO Bmi;
> ZeroMemory(&Bmi.bmiHeader,sizeof(Bmi.bmiHeader));
> Bmi.bmiHeader.biSize=sizeof(Bmi.bmiHeader);
> Bmi.bmiHeader.biWidth=200;
> Bmi.bmiHeader.biHeight=-200; // Negative: top-down bitmap
> Bmi.bmiHeader.biPlanes=1;
> Bmi.bmiHeader.biBitCount=24; // R,G,B triplets
> Bmi.bmiHeader.biCompression=BI_RGB;
> BYTE *Pix;
> CreateDIBSection(0,&Bmi,DIB_RGB_COLORS,(void **)&Pix,0,0);
> GdiFlush();

> // Paint an interesting pattern, directly in the pixel buffer
> BYTE *p=Pix;
> BYTE r,g,b;
> for (int x=0;x<200;x++)
>         for (int y=0; y<200;y++) {
>                 r=128.0+127.0*sin(0.1*x);
>                 g=128.0+127.0*cos(0.1*y);
>                 b=sqrt(x*x+y*y);
>                 *p++=b;
>                 *p++=g;
>                 *p++=r;
>                 }

> // Show it in an TImage component on the form
> Image1->Picture->Bitmap->Width=200;
> Image1->Picture->Bitmap->Height=200;
> SetDIBitsToDevice(Image1->Picture->Bitmap->Canvas->Handle,0,0, 200,200,
>                      0,0, 0,200, Pix,&Bmi,DIB_RGB_COLORS);

> // Resize container to fit
> Form1->ClientWidth=200;
> Form1->ClientHeight=200;
> Image1->Top=0;
> Image1->Left=0;
> Image1->Width=200;
> Image1->Height=200;
> }

> ---
> Design your Exception class hierarchy well...

>        VCL+MFC+API+OCX == new *Modern_Developer;

 
 
 

1. canvas->pixel is slow slow slow...

 hi...there...

   i want to draw a pic thru pixels...
   and i used to adapting canvas->pixel to have it done dot by dot..
  and it's incredibily slow...

   if there any method like 1. to initial a Graphic base viables first and
then put pixels in,
                                            after all, print the graphic out
via the viables...
                                       2. call DIB to handle ...and how?
                                       3. DirectDraw ...???
   thanx for helping~~~

2. No jobs for Lightwave artists?

3. TImage->Canvas->Pixels[i][j]=

4. URT and "tiffio.h"

5. Slow Canvas->Draw and Canvas->CopyRect

6. Raise a little hell .........

7. >>>>>>>>>>>>>>>>>>>>>

8. CGI programming jobs - what are they like

9. picture->canvas to printer->canvas

10. Image->Canvas vs. Bitmap->Canvas Transparency

11. another way of explaining this>>>>>>>>>>>>>>

12. Operating Systems >>>>>>>>>>>>>

13. HELP PLEASE Need AVI >>>>>>>>>>>> FLI