Author Topic: PCL Bitmap class questions  (Read 5553 times)

Offline zvrastil

  • PixInsight Addict
  • ***
  • Posts: 179
    • Astrophotography
PCL Bitmap class questions
« on: 2011 January 27 23:08:41 »
Hi (or maybe, I should write Hi Juan  8) ),

I have few questions about Bitmap class in PCL.

1) Is there some clever way to multiply alpha value in all pixels with constant (in other words, to apply constant opacity to bitmap, which already has some transparency)? Other than doing it "manually" through ScanLine() method?

2) Is the length of one bitmap line equal to bitmap width? Can I safely use "RGBA* line = bmp.ScanLine(0); line[y*bmp.Width()+x] = value;"?

3) Is it safe to modify bitmap pixels via ScanLine between calls to Graphics::BeginPaint() and EndPaint() on the same bitmap? I'm not asking about parallel processing here.

4) Related to Thread class. If I create new thread using new operator, does it indeed create new thread in the OS? Or does it take thread from some threadpool? In other words, it there a thread creation overhead?

thanks, Zbynek
« Last Edit: 2011 January 27 23:20:38 by zvrastil »

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Re: PCL Bitmap class questions
« Reply #1 on: 2011 January 28 00:45:29 »
Morning Zbynek,

Quote
1) Is there some clever way to multiply alpha value in all pixels with constant (in other words, to apply constant opacity to bitmap, which already has some transparency)? Other than doing it "manually" through ScanLine() method?

These member functions are your friends:

  void Bitmap::SetAlpha( uint8 newAlpha );
   void Bitmap::SetAlpha( const Rect& rect, uint8 newAlpha );


You can operate either on the whole bitmap or on a rectangular region. Unfortunately, arbitrary region selection is still not implemented for bitmaps in the PCL (although this can be implemented easily; let me know if you're interested).

These member functions also may be of your interest:

  void Bitmap::ReplaceColor( RGBA replaceThis, RGBA replaceWith )
   void Bitmap::ReplaceColor( const Rect& rect, RGBA replaceThis, RGBA replaceWith );


They allow you to replace a specific color selectively.

In addition, the full sets of color assignment and bitwise logical operators are also available for the Bitmap class: Copy, Fill, Or, And, Xor, Invert; in several forms that allow you to operate between bitmaps and between bitmaps and constant pixel values. For more information, see the pcl/Bitmap.h standard header or the Bitmap class in PCL documentation.

All of these routines have been implemented as fast direct pixel manipulations. They don't use BeginPaint()...EndPaint(), Graphics, etc.

Quote
2) Is the length of one bitmap line equal to bitmap width? Can I safely use "RGBA* line = bmp.ScanLine(0); line[y*bmp.Width()+x] = value;"?

Yes. Bitmap is a device-independent image in PixInsight/PCL. You can assume that all pixels in a Bitmap are stored as a contiguous data block. Each pixel is a 32-bit unsigned integer in the AARRGGBB format.

Quote
3) Is it safe to modify bitmap pixels via ScanLine between calls to Graphics::BeginPaint() and EndPaint() on the same bitmap? I'm not asking about parallel processing here.

Yes, you can do that. You can also call fast direct pixel manipulation routines such as Fill(), Or(), And(), Invert(), etc.

Quote
4) Related to Thread class. If I create new thread using new operator, does it indeed create new thread in the OS? Or does it take thread from some threadpool? In other words, it there a thread creation overhead?

Thread creation overhead is negligible. A thread is not effectively created as such until you call Thread::Start(). On FreeBSD, Linux and Mac OS X, PI uses the standard pthread library. Each call to Thread::Start() will translate into a call to pthread_create(). On Windows, the Win32 API is used directly so Thread::Start() translates into ::CreateThread().

Before calling Thread::Start() a Thread object is just a managed pcl::UIObject in your module whose server-side counterpart is a very small structure 'waiting' to be 'fired'.

Let me know if you need further info and happy module creation ;)
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline zvrastil

  • PixInsight Addict
  • ***
  • Posts: 179
    • Astrophotography
Re: PCL Bitmap class questions
« Reply #2 on: 2011 January 28 01:02:32 »
Hi Juan,

These member functions are your friends:

  void Bitmap::SetAlpha( uint8 newAlpha );
   void Bitmap::SetAlpha( const Rect& rect, uint8 newAlpha );


I'm aware of these functions, but unfortunately, this is not what I need. These functions replace alpha value of each pixel. My case is different. I have a bitmap with rendered annotation - text and leader line. Most of the bitmap is transparent and edges of the text are semitransparent due to antialiasing. Now, I want to apply extra opacity parameter to the text. For example 128 (0.5) - so I need to multiply each alpha value with 0.5 - not replace all alpha values with 128. Using SetAlpha results in changing transparent pixels to semitransparent.

I assume I have to do it on pixel level using ScanLine() method.

Other questions are clear, thanks a lot.

regards, Zbynek

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Re: PCL Bitmap class questions
« Reply #3 on: 2011 January 28 01:21:55 »
Hi Zbynek,

I see. So what you want to do is changing the opacity just for those pixels whose opacity is not already zero (or any other arbitrary value). You perhaps could do that with a combination of bitwise logical operations, but your best option is writing a direct pixel manipulation routine to multiply your bitmap selectively.

Do you think I should add arithmetic pixel manipulation operations to Bitmap (Bitmap::Add(), Bitmap::Mul(), etc.) ?
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline zvrastil

  • PixInsight Addict
  • ***
  • Posts: 179
    • Astrophotography
Re: PCL Bitmap class questions
« Reply #4 on: 2011 January 28 01:45:57 »
Hi Zbynek,

I see. So what you want to do is changing the opacity just for those pixels whose opacity is not already zero (or any other arbitrary value). You perhaps could do that with a combination of bitwise logical operations, but your best option is writing a direct pixel manipulation routine to multiply your bitmap selectively.

Do you think I should add arithmetic pixel manipulation operations to Bitmap (Bitmap::Add(), Bitmap::Mul(), etc.) ?

Hi Juan, it would be "nice to have", but it's definitely not needed just because this one use case - it is easy to do it manually, I just wanted to be sure I'm not missing some already-prepared, super-optimized method :).

Best regards, Zbynek