Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Bitmap alpha pixels odd behaviour [SOLVED]

    SDK Help
    0
    5
    525
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      On 26/08/2014 at 04:45, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   R14 
      Platform:   Windows  ;   
      Language(s) :     C++  ;

      ---------
         Hi folks,

      I've been running some experiments with bitmaps and have come across some odd behaviour during a custom 'copy-pixel' loop. The following is for all intents and purposes a full function that is called via a button command press:

        
      // Note: the MyStruct.Str_Bitmap used in the loop is   
      //       valid and does display in the picture viewer   
        
      BaseBitmap *Copied_BMP = BaseBitmap::Alloc();   
      BaseBitmap *Alpha = NULL;   
      Alpha = Copied_BMP->GetInternalChannel();   
      Alpha = Copied_BMP->AddChannel(TRUE,TRUE);   
      Copied_BMP->Init(100,100,32,INITBITMAPFLAGS_0);   
        
      LONG rr,gg,bb,aa;   
      UWORD Ru,Gu,Bu,Au;   
        
      for(int h = 0; h <= Copied_BMP->GetBh()-1;)   
      {   
          for(int w = 0; w <= Copied_BMP->GetBw()-1;)   
          {   
              MyStruct.Str_Bitmap->GetPixel(w,h,&Ru;,&Gu;,&Bu;);   
              MyStruct.Str_Bitmap->GetAlphaPixel(MyStruct.Str_Bitmap_Alpha,w,h,&Au;);   
        
              if(h == 23 && w == 14)   
              {   
                  GePrint("In-loop 14x23 alpha pixel = " + LongToString(Au)); // correct   
              }   
        
              rr = Ru;   
              gg = Gu;   
              bb = Bu;   
              aa = Au;   
                             
              if(h == 23 && w == 14)   
              {   
                  GePrint("In-loop 14x23 alpha pixel = " + LongToString(aa)); // correct   
              }   
        
              Copied_BMP->SetPixel(w,h,rr,gg,bb);   
              Copied_BMP->SetAlphaPixel(Alpha,w,h,aa);   
        
        
              if(h == 22 && w == 13) // previous pixel test   
              {   
                  Copied_BMP->GetAlphaPixel(Alpha,12,21,&Au;);   
                  aa = Au;   
                  GePrint("Post-set: 12x21 alpha LONG = " + LongToString(aa)); // wrong   
                  GePrint("Post-set: 12x21 alpha UWORD = " + LongToString(Au)); // wrong   
              }   
              else if(h == 23 && w == 14)   
              {   
                  Copied_BMP->GetAlphaPixel(Alpha,14,23,&Au;);   
                  aa = Au;   
                  GePrint("Post-set: 14x23 alpha LONG = " + LongToString(aa)); // correct   
                  GePrint("Post-set: 14x23 alpha UWORD = " + LongToString(Au)); // correct   
              }   
              else if(h == 26 && w == 4)   
              {   
                  Copied_BMP->GetAlphaPixel(Alpha,4,26,&Au;);   
                  aa = Au;   
                  GePrint("Post-set: 4x26 alpha LONG = " + LongToString(aa)); // correct   
                  GePrint("Post-set: 4x26 alpha UWORD = " + LongToString(Au)); // correct   
              }   
        
              w++;   
          }   
        
          h++;   
      }   
        
      // Now test pixel value at 14x23 again   
      Copied_BMP->GetAlphaPixel(Alpha,14,23,&Au;);   
      aa = Au;   
      GePrint("Post-loop: 14x23 alpha LONG = " + LongToString(aa)); // wrong   
      GePrint("Post-loop: 14x23 alpha UWORD = " + LongToString(Au)); // wrong   
        
      //... I hope the above is all correct, from here the   
      //    code is mainly changing some pixel colours and   
      //    freeing bitmaps etc.   
      

      The issue is that the printed values after the for loop are all null, but the printed values inside the loop are correct (once the alpha value is set). The only time one of the prints in the loop doesn't print correct values is when trying to print a previous pixels value (so if h=10 and w=10, printing h=9 and w=9 values are also null). It's like the alpha data is erased as soon as the loops' skopes are left.

      I've tested the above in both a dialog and object plugin, and both are running into the same problem. Sending either pictures to the picture viewer also seems to ignore the alpha data (including the original image!), but the colour data in both seems fine. Images are all in 32-bit form.

      Is anyone with a beady eye able to spot what I'm doing wrong here? Or has anyone else come across this behaviour before?

      WP.

      P.s. just for note's sake, I'm aware of the bitmap->CopyTo() and bitmap->SetPixelCnt(), but I can't use these in the above because the routine will be expanded on and the operation will need to be on a per-pixel basis.

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 27/08/2014 at 10:03, xxxxxxxx wrote:

        Here's an example of copying image data that also works outside of the for() loop for me:

        //This code creates a bitmap copy of an image by manually copying the alpha and color values from an image line-by-line  
          
          //The source image that contains an alpha channel   
          Filename fn = GeGetC4DPath(C4D_PATH_DESKTOP) + "source.psd";  
          AutoAlloc<BaseBitmap> sourceImg;  
          if(IMAGERESULT_OK != sourceImg->Init(fn)) return FALSE;  
          BaseBitmap *sourceImg_Alpha = sourceImg->GetInternalChannel();  
          
          //Create a copy      
          AutoAlloc<BaseBitmap> copied_BMP;  
          if(!copied_BMP) return FALSE;  
          copied_BMP->Init(sourceImg->GetBw(), sourceImg->GetBh(), 32);  
          copied_BMP->AddChannel(TRUE, FALSE);  
          BaseBitmap *copied_Alpha = copied_BMP->GetInternalChannel();  
          
          UWORD r,g,b,a;  
          INT h,w;  
          
          //Loop through the source image and copy the data to the other bitmap  
          for(h=0; h <= copied_BMP->GetBh()-1; h++)  
          {  
              for(w=0; w <= copied_BMP->GetBw()-1; w++)  
              {  
                  //Copy the alpha & color values from the source to the copy  
                  sourceImg->GetPixel(w,h,&r,&g,&b);  
                  sourceImg->GetAlphaPixel(sourceImg_Alpha,w,h,&a);              
                  copied_BMP->SetPixel(w,h,r,g,b);  
                  copied_BMP->SetAlphaPixel(copied_Alpha,w,h,a);  
          
                  //Check the alpha and color values in the copy at a specific location  
                  if(h == 100 && w == 100)   
                  {  
                      GePrint("Alpha = " + LongToString(a));  
                      GePrint("color = " + LongToString(r) + " " + LongToString(g) + " " + LongToString(b));   
                  }    
              }  
          }  
          
            
          //Check the alpha and color values in the copy again...This time outside of the loop  
          copied_BMP->GetPixel(100,100,&r,&g,&b);  
          copied_BMP->GetAlphaPixel(copied_Alpha,100,100,&a);  
          GePrint("Post-loop Alpha = " + LongToString(a));  
          GePrint("Post-loop color = " + LongToString(r) + " " + LongToString(g) + " " + LongToString(b));
        

        -ScottA

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 27/08/2014 at 18:30, xxxxxxxx wrote:

          Interesting, I found where the problem is Scott. I had the same problem with your code which was copied and pasted all except for the initialising of the bitmaps. And I found that it was the way I was setting up the bitmaps pre-loop that was causing the alpha channel to be wiped. So, instead of:

            
          BaseBitmap *bmp = BaseBitmap::Alloc();   
          BaseBitmap alpha = NULL;   
          alpha = bmp->GetInternalChannel();   
          alpha = bmp->AddChannel(TRUE,TRUE);   
          bmp->Init(100,100,32,INITBITMAPFLAGS_0);   
          

          it appears we should be applying the alpha channels after the init'ing, like:

            
          BaseBitmap *bmp = BaseBitmap::Alloc();   
          BaseBitmap alpha = NULL;   
          bmp->Init(100,100,32,INITBITMAPFLAGS_0);   
          alpha = bmp->GetInternalChannel();   
          alpha = bmp->AddChannel(TRUE,TRUE);   
            
          // or   
            
          BaseBitmap *bmp = BaseBitmap::Alloc();   
          bmp->Init(100,100,32,INITBITMAPFLAGS_0);   
          BaseBitmap alpha = NULL;   
          alpha = bmp->GetInternalChannel();   
          alpha = bmp->AddChannel(TRUE,TRUE);   
          

          If someone could confirm this outside of my programming that would be great, otherwise it might be one for the notes Scott! Thanks for your input as always,

          WP.

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 27/08/2014 at 21:27, xxxxxxxx wrote:

            Correct.
            Allocated Bitmaps do not contain an Alpha channel by default. We have to add them by hand.
            And we can't add them until we Init() the bitmap first.

            And it probably goes without saying that we cant "Get" the Alpha channel until after we add it.

            -ScottA

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              On 28/08/2014 at 06:28, xxxxxxxx wrote:

              Doh!  I read over this a few times and couldn`t figure it out..  Will commit this to memory.

              1 Reply Last reply Reply Quote 0
              • First post
                Last post