Trying to use Graphics.DrawImage to make transparent image...

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Samishii23
    New Member
    • Sep 2009
    • 246

    Trying to use Graphics.DrawImage to make transparent image...

    Code:
    public void FadeForm() {
    	Bitmap FadeBmp = new Bitmap(Settings[0] + "fade.jpg");
    	ColorMatrix CMFade = new ColorMatrix();
    	ImageAttributes AFade = new ImageAttributes();
    												
    	FadeBox = new PictureBox();
    	FadeBox.Location = new Point(0,0);
    	FadeBox.Size = new Size(this.Width,this.Height);
    	FadeBox.Visible = false;
    	this.Controls.Add(FadeBox);
    
    	CMFade.Matrix33 = 0.4f;
    	AFade.SetColorMatrix(CMFade, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
    	Graphics g = Graphics.FromImage(FadeBmp);
    	
    	g.DrawImage((Image)FadeBmp,
    		new Rectangle(1,1,800,650),
    		0,0,
    		800,650,
    		GraphicsUnit.Pixel,
    		AFade);
    
    	//g.Dispose();
    	FadeBox.Image = FadeBmp;
    	FadeBox.Visible = true;
    	FadeBox.BringToFront();
    	}
    Trying to make a transparent image using ColorMatrix, and redrawing the image (fade.jpg), which is just a black image sized at 800,650. When I run the method, nothing happens. No error, or sign that the picture box was even showed.

    I was using the tutorial found here.

    Anyone know if I'm doing something wrong in the code? Or if I'm missing something. Its my first time doing something like this with System.Drawing.
  • GaryTexmo
    Recognized Expert Top Contributor
    • Jul 2009
    • 1501

    #2
    All right, I think I know what the problem is here...

    When you draw your image, you're drawing it to the source image. If you draw a transparent copy of your source image on your source image, you're not going to see any change.

    What you need to do is to create a new, blank image, then draw to that. They actually have this in the example you linked, but it's tough to spot (caught me too!) so it's not surprising you missed it.

    (From that page...)
    Code:
    Graphics g = Graphics.FromImage([B]img[/B]);
    
    g.DrawImage((Image)[B]bmp[/B],
                 new Rectangle(1, 1, pictureBox1.Width - 2, pictureBox1.Height - 2),
                 0, 0,
                 pictureBox1.Width, pictureBox1.Height,
                 GraphicsUnit.Pixel,
                 attributes);
    Notice the bolded? Put this in your code before the graphics line...

    Code:
    Image img = new Bitmap(FadeBmp.Width, FadeBmp.Height);
    ... and update your g.DrawImage line and you should be golden :)

    Comment

    • Samishii23
      New Member
      • Sep 2009
      • 246

      #3
      Edit:
      Ok I get the thing to display... Now the problem is, is the transparency isn't working lol.
      Heres my updated function...
      Code:
      public void FadeForm() {
      	ColorMatrix CMFade = new ColorMatrix();
      	ImageAttributes AFade = new ImageAttributes();
      
      	FadeBox = new PictureBox();
      	FadeBox.Location = new Point(0,0);
      	FadeBox.Size = new Size(this.Width, (this.Height - MenuBar.Height));
      	FadeBox.Visible = false;
      	this.Controls.Add(FadeBox);
      
      	CMFade.Matrix33 = 0.4f;
      	AFade.SetColorMatrix(CMFade, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
      	Bitmap img = new Bitmap(this.Width,this.Height);
      	Graphics g = Graphics.FromImage(img);
      	g.DrawImage((Image)img,
      		new Rectangle(1, 1, 800, (this.Height - MenuBar.Height)),
      		0,0,
      		800,(this.Height - MenuBar.Height),
      		GraphicsUnit.Pixel,
      		AFade);
      
      	//g.Dispose();
      	FadeBox.Image = img;
      	FadeBox.Visible = true;
      	FadeBox.BringToFront();
      	}
      I added (this.Height - MenuBar.Height) because I have my menu bar at the bottom of the form, and in the hopes of making the transparent image over everything besides the menu, though when I run it, it still covers the MenuBar, which is a StatusStrip element btw...

      Also the whole form just blacks out. I removed the fade.jpg. Does transparency even work in general?

      Comment

      • GaryTexmo
        Recognized Expert Top Contributor
        • Jul 2009
        • 1501

        #4
        In this example, bmp is the source image. In your code, this would be FadeBmp. You need to pass the destination (the one you used to create the graphics object) to the PictureBox.

        Read the doc for the Graphics.DrawIm age method to see what that first parameter actually means, that should help clarify things for you :)

        Comment

        • Samishii23
          New Member
          • Sep 2009
          • 246

          #5
          Updated above post before noticing you had replied to the old one. Sorry.
          Just going to use BringToFront() for the Menu until I can work around the image height thing. =\

          Comment

          • GaryTexmo
            Recognized Expert Top Contributor
            • Jul 2009
            • 1501

            #6
            You've eliminated your source image now. Like I said, check the doc... you need two Image objects. One is a destination (what you copy to) and the other is a source (one you copy from). Your code only has one image... big hint: lines 14 and 15).

            As for the menu part, again, read the doc on what those parameters actually mean. Again, one is a source location and the other is a destination location.

            Another option may be to just change the location/size of your picturebox so it doesn't overlap with your menu.

            (http://msdn.microsoft.com/en-us/libr...drawimage.aspx)

            Comment

            • Samishii23
              New Member
              • Sep 2009
              • 246

              #7
              Unfortunally, after reading the MSDN articles. I still don't see what I'm missing.

              I've put the Source image back in. But no transparency...
              Code:
              public void FadeForm() {
              	ColorMatrix CMFade = new ColorMatrix();
              	ImageAttributes AFade = new ImageAttributes();
              	Bitmap FadeBmp = new Bitmap(Settings[0] + "fade.jpg");
              												
              	FadeBox = new PictureBox();
              	FadeBox.Location = new Point(0,0);
              	FadeBox.Size = new Size(this.Width, (this.Height - MenuBar.Height));
              	FadeBox.Visible = false;
              	this.Controls.Add(FadeBox);
              
              	CMFade.Matrix33 = 0.5f;
              	AFade.SetColorMatrix(CMFade, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
              	Bitmap img = new Bitmap(FadeBox.Width, FadeBox.Height);
              	Graphics g = Graphics.FromImage(FadeBmp);
              	g.DrawImage((Image)img,
              		new Rectangle(1, 1, img.Width, img.Height),
              		0,0,
              		FadeBox.Width,FadeBox.Width,
              		GraphicsUnit.Pixel,
              		AFade);
              	//g.Dispose();
              
              	FadeBox.Image = img;
              	FadeBox.Visible = true;
              	FadeBox.BringToFront();
              	MenuBar.BringToFront();
              	}
              I just don't see the problem. *sigh*

              Comment

              • GaryTexmo
                Recognized Expert Top Contributor
                • Jul 2009
                • 1501

                #8
                Lines 15 and 16 look like this..

                Code:
                     Graphics g = Graphics.FromImage(FadeBmp);
                     g.DrawImage((Image)img,
                They need to look like this...

                Code:
                     Graphics g = Graphics.FromImage(img);
                     g.DrawImage((Image)FadeBmp,
                img is where you're drawing to, so you create the graphics on that image. FadeBmp is what you want to draw, so you use that in your draw image method. Graphics.DrawIm age will draw the supplied image to the target graphics (which was created as the handle to img).

                Thus, the semi-opaque copy of FadeBmp is drawn onto the blank img object.

                Note, Bitmap doesn't support transparency by normally... I think it's an indexing thing, so you might need to change the object type to Image, but still create a new Bitmap. I know, it's weird, but if you're not getting good results, that's the first thing to try.

                I had this working in a test project that I deleted, but I'm pretty sure you're really close. Give that a try and let me know.

                *Edit: I just tested using Bitmap and it's fine, should still work for ya.

                Comment

                • Samishii23
                  New Member
                  • Sep 2009
                  • 246

                  #9
                  Ok. I changed the two lines. Same thing. Still looks like a black canvas. There is no transparency. I even tried making them Images, not Bitmap...
                  I kinda feel like a jerk saying this over and over again... I don't know why your side always works and mine doesn't. =\

                  Comment

                  • GaryTexmo
                    Recognized Expert Top Contributor
                    • Jul 2009
                    • 1501

                    #10
                    Hmm, that's very confusing. Are you sure you're not assigning the black image to the panel anywhere somehow? Here's the code for what I have... it's basically exactly the same as yours, but maybe there's a difference I'm not seeing.

                    Code:
                            public Form1()
                            {
                                InitializeComponent();
                    
                                Bitmap sourceImg = new Bitmap(@"c:\temp\test.bmp");
                    
                                ColorMatrix matrix = new ColorMatrix();
                                matrix.Matrix33 = 0.1f;
                    
                                ImageAttributes attributes = new ImageAttributes();
                                attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
                    
                                Bitmap destImg = new Bitmap(sourceImg.Width, sourceImg.Height);
                                Graphics g = Graphics.FromImage(destImg);
                                g.DrawImage(
                                    (Image)sourceImg,
                                    new Rectangle(0, 0, destImg.Width, destImg.Height),
                                    0, 0,
                                    sourceImg.Width, sourceImg.Height,
                                    GraphicsUnit.Pixel,
                                    attributes);
                    
                                pictureBox1.Image = destImg;
                            }
                    Created a new project and put a picture box on it, then had this code for my constructor. When I run, I have a light gray box... my source picture is just a 100x100 bitmap that's all black.

                    Comment

                    • Samishii23
                      New Member
                      • Sep 2009
                      • 246

                      #11
                      I copied and pasted my Function into a test project... Woo, it worked.......
                      Great. Now I don't know why it won't work on my project... ...

                      Now if I can only figure out what the difference is...

                      Comment

                      • Samishii23
                        New Member
                        • Sep 2009
                        • 246

                        #12
                        Ugh. Seriously. Found out the problem...

                        The PictureBox control was inheriting the Windows background color. Which was set to Black... Seriously. Only had to set the BackColor property to Transparent.

                        This feels like something I should have known to do from the start... Yet it evaded my notice... Bah!

                        Thank you for the help yet again Gary!

                        Comment

                        Working...