CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 18

Hybrid View

  1. #1
    Join Date
    Mar 2011
    Posts
    27

    [RESOLVED] stacking several PNG files under in a windows forms

    Hi Guys,
    I am doing some project in which i have to implement a spirit level
    (http://en.wikipedia.org/wiki/Spirit_level)

    I have prepared a png file with the spirit levell frame, and parts where liquid is are transparent (but i kept the black lines because they need to be on the top)

    I also prepared the image of the air bubble.

    Now i am trying to stack it all together on the form and the bubble image(pictureBox) is below the png frame(pictureBox, Image PNG, backgroundColor transparent), however it cannot be seen in the transparent parts of the frame, i can only see the background image of the panel (in which are images) there.

    Is there any way to make the image visible?

    I am working in VS2005 under windows forms in c++

    Thanks in advance,
    Smallbit

  2. #2
    Join Date
    Jan 2010
    Posts
    1,133

    Re: stacking several PNG files under in a windows forms

    Create a private Bitmap member variable and load from file (or assign from a resource) the bottom-most png. Then use the Graphics::FromImage(Image^) static method to obtain a Graphics instance that you can use to draw on the original bitmap. I would make it a private member variable, too.
    On Paint event, use the Graphics object to Draw one image over the other - the transparent areas will be blended (you can also override OnPaint(...)). Use one of the DrawImage(...) overloads. These functions also allow you to translate and/or resize the image being drawn, and you can, for example, use RotateTransform(float) to - well, apply rotations.

    Make sure the images all have the same dpi resolution, since this can sometimes cause unexpected results. You can use the Bitmap::SetResolution(float, float) member function to change it, in conjunction with the DpiX and DpiY properties of the Graphics class instance.

    Now, you can assign that image directly to the PictureBox and draw on that, but this could produce some flicker. (... Or maybe you can't? I seem to recall that PictureBox behaves a bit weird when it comes to that. Just use a panel if there are any problems.)
    To avoid flicker, you can use this Bitmap as a back buffer, and create another one to be used on the control. After you've done all the painting, just draw the first bitmap on the other (using a second Graphics object.)
    Another alternative is to use a BufferedGraphics - here's a slightly modified MSDN example:

    Code:
    // Retrieves the BufferedGraphicsContext for the 
             // current application domain.
             context = BufferedGraphicsManager::Current;
    
             // Allocates a graphics buffer
             grafx = context->Allocate( bmpGraphics, Rectangle(0, 0, bmp->Width, bmp->Height) );
    To draw, use grafx->Graphics, assuming that grafx is a BufferedGraphics from the MSDN example. When done, call grafx->Render(), and that's it.

  3. #3
    Join Date
    Mar 2011
    Posts
    27

    Re: stacking several PNG files under in a windows forms

    Thank you for the answer,
    I have resolved it in other way, but your advice about flicker issue was useful in other part i had pending to resolve D

    Cheers

  4. #4
    Join Date
    Jan 2010
    Posts
    1,133

    Re: stacking several PNG files under in a windows forms

    Good.
    Just out of curiosity, how did you do it?
    I forgot to mention that you could have also used the CreateGraphics() function to obtain a Graphics instance that would draw directly on the control.

    BTW, you can mark the thread as resolved by clicking on "Thread Tools" (near the top), and than "Mark Thread Resolved".

  5. #5
    Join Date
    Mar 2011
    Posts
    27

    Re: stacking several PNG files under in a windows forms

    Well, I am ashamed of the way I have chosen, it does not involve any programming tricks.
    Since the bubble is always visible(note that I have the top view for the spirit level) it doesn't need to be below the frame. The only thing is that the black lines (indicators) need to be over the bubble, for this purpose I used the pictureBoxes with black background and very tiny height.

    So I have the JPG with frame on the background(the bubble was removed in PS) on the panel, then PNG image of the bubble (so it will be rounded) and on top of it I have two picture boxes with black lines, then I am dynamically changing the location of the picturebox with the bubble. And it works pretty nice and smooth.

    Maybe soon I will apply your hints to learn something

    Thanks again for help

  6. #6
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: [RESOLVED] stacking several PNG files under in a windows forms

    I started to look for a solution to this problem before Cthulhu did post #2 and wasn't yet finished when I read this post. In the meantime I have finished my toy project, using advice from this very post (thanks ). And now that I have it and spent so many time making it, I insist in finally posting it here...

    In addition to the code posted below I have attached a ZIP file containing the project and a screen shot showing how the toy app looks to this post.

    These are the event handlers doing the actual work:

    Code:
    // Form1.cpp
    
    #include "stdafx.h"
    
    #include "Form1.h"
    
    using namespace LayeredPNGs;
    
    System::Void Form1::trkX_Scroll(System::Object^  sender, System::EventArgs^  e)
    {
      int x = trkX->Value;
      lblX->Text = String::Format("x = {0}", x);
      ptOverlayPos.X = x;
      pbBack->Invalidate();
    }
    
    System::Void Form1::trkY_Scroll(System::Object^  sender, System::EventArgs^  e)
    {
      int y = trkY->Maximum - trkY->Value;
      lblY->Text = String::Format("y = {0}", y);
      ptOverlayPos.Y = y;
      pbBack->Invalidate();
    }
    
    System::Void Form1::pbBack_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e)
    {
      e->Graphics->DrawImage(bmpOverlay, ptOverlayPos);
    }
    Actually, as you can see, the picture box' Paint handler is as short as can be.

    The following is the constructor that sets up the form class:

    Code:
      public:
        Form1(void) : ptOverlayPos(0, 0)
        {
          InitializeComponent();
          //
          //TODO: Konstruktorcode hier hinzufügen.
          //
    
          /*
    
          // The following is meant to set up the Bitmap object from an image resource. Unfortunately
          // it tends to fail regularly (at least for me) due to the "vanishing resource problem".
    
          ComponentResourceManager ^cresm = gcnew ComponentResourceManager(Form1::typeid);
          Object ^objResource = cresm->GetObject("Overlay.png");
          Diagnostics::Trace::Assert(objResource != nullptr, "Overlay bitmap construction from resource failed");
          bmpOverlay = gcnew Bitmap(safe_cast<Drawing::Image ^>(objResource));
    
          */
    
          // This is the alternative way, constructing the Bitmap object from a disk file
          // (wouldn't really like that in a real-life app though):
    
          bmpOverlay = gcnew Bitmap("Overlay.png");
        }
    Much of this code is actually commented out, but I wanted to show it because that's the real way of constructing the bitmap object.

    The "vanishing resource problem" mentioned there means: Whenever I change even the tiniest bit of the form design, all resources I have added manually to Form1.resX vanish instantly. I probably would need to add a resX file to the project that's independent from the form but I have not yet managed to do this. Maybe I'm too dumb to comprehend how to use this managed resource "editor" or it's simply another weird limitation of the Express Edition. Actually, I wouldn't really like either option...
    Attached Images Attached Images  
    Attached Files Attached Files
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  7. #7
    Join Date
    Mar 2011
    Posts
    27

    Re: [RESOLVED] stacking several PNG files under in a windows forms

    Hi Eri,

    What do you mean by "vanishing resource problem" ?


    Anyway, I cannot run your project (its VS2010?) but I've seen the code and screen. In the original problem I meant to display (lets say on your example) two PNG stars one over another, and I wanted them both as well as the background image to be visible all the time.

    Edit: If Anybody is interested : I have uploaded screen of what I have done(post #3), the frame texture is to be replaced once I will get better pictures.
    SpiritLevel.Jpg shows the initial position , and SpiritLevel2.jpg shows the bubbles in different positions.
    Attached Images Attached Images   
    Last edited by smallbit; March 18th, 2011 at 04:38 AM.

  8. #8
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: [RESOLVED] stacking several PNG files under in a windows forms

    Quote Originally Posted by smallbit View Post
    What do you mean by "vanishing resource problem" ?
    Well, that's no technical term; I just invented it for something that has been bugging me for quite some time now. Essentially it means:
    • I add a resource to Form1.resX. -> Everything is fine, compiles and runs ok an arbitrary number of times.
    • I change anything in the design of Form1 (e.g. just move a control by one pixel). -> The resource I added in the step above is gone. Still compiles but loading the resource at runtime naturally fails.

    Clearer now?

    Anyway, I cannot run your project (its VS2010?) but I've seen the code and screen. In the original problem I meant to display (lets say on your example) two PNG stars one over another, and I wanted them both as well as the background image to be visible all the time.
    Yes, it is VS 2010. IIRC you didn't mention which version you're using (and I don't have another one anyway ).

    I understood that you wanted two use more than just two levels of layering but I wanted to simplify the problem. Once you got that working for two layers like in my sample code you can easily extend it to any number of layers.

    Your screen shots look really nice, i.e. realistic. The user won't see that you cheated a bit (as I understood post #5) and in the end it's the result that matters anyway.
    Last edited by Eri523; March 18th, 2011 at 08:06 AM.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  9. #9
    Join Date
    Apr 2011
    Posts
    1

    Re: [RESOLVED] stacking several PNG files under in a windows forms

    Thank you for the answer,
    I have resolved it in other way, but your advice about flicker issue was useful in other part i had pending to resolve D

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured