11

When I tried from with transparent background, it's not completely transparent. I tried two code blocks for this issue. First i tried like this code:

 public Form1()
    {
        InitializeComponent();
        SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        this.BackColor = Color.Transparent;
        this.FormBorderStyle = FormBorderStyle.None;
        //this.WindowState = System.Windows.Forms.FormWindowState.Maximized;

    }

it look like this picture;

enter image description here

Then i found some different codes and tried ike this;

 public Form1()
    {
        InitializeComponent();
        this.TransparencyKey = Color.White;
        this.BackColor = Color.White;
        this.FormBorderStyle = FormBorderStyle.None;
        this.WindowState = System.Windows.Forms.FormWindowState.Maximized;

    }

And this looks like this picture;

enter image description here

You can see logo with a white border. I want to show only .png Logo completely transparent. What should i do? How can do this?

Here is my Logo image as .png;

enter image description here

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
CoderWho
  • 210
  • 1
  • 5
  • 20

2 Answers2

20

You can use Layered Windows:

Using a layered window can significantly improve performance and visual effects for a window that has a complex shape, animates its shape, or wishes to use alpha blending effects. The system automatically composes and repaints layered windows and the windows of underlying applications. As a result, layered windows are rendered smoothly, without the flickering typical of complex window regions. In addition, layered windows can be partially translucent, that is, alpha-blended.

Create layered window in Windows Forms

Here is some code from msdn code gallery which demonstrates creating Layered Windows in Windows Forms. It allows you to create a shaped splash screen and let you to move it by mouse.

Add PerPixelAlphaForm to the project and then it's enough to inherit from this form and call its SelectBitmap and pass your png to the method to create a layered window.

enter image description here

PerPixelAlphaForm.cs

#region Using directives
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
#endregion
namespace CSWinFormLayeredWindow
{
    public partial class PerPixelAlphaForm : Form
    {
        public PerPixelAlphaForm()
        {
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            this.ShowInTaskbar = false;
            this.StartPosition = FormStartPosition.CenterScreen;
            this.Load += PerPixelAlphaForm_Load;
        }

        void PerPixelAlphaForm_Load(object sender, EventArgs e)
        {
            this.TopMost = true;
        }
        protected override CreateParams CreateParams
        {
            get
            {
                // Add the layered extended style (WS_EX_LAYERED) to this window.
                CreateParams createParams = base.CreateParams;
                if(!DesignMode)
                    createParams.ExStyle |= WS_EX_LAYERED;
                return createParams;
            }
        }
        /// <summary>
        /// Let Windows drag this window for us (thinks its hitting the title 
        /// bar of the window)
        /// </summary>
        /// <param name="message"></param>
        protected override void WndProc(ref Message message)
        {
            if (message.Msg == WM_NCHITTEST)
            {
                // Tell Windows that the user is on the title bar (caption)
                message.Result = (IntPtr)HTCAPTION;
            }
            else
            {
                base.WndProc(ref message);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="bitmap"></param>
        public void SelectBitmap(Bitmap bitmap)
        {
            SelectBitmap(bitmap, 255);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="bitmap">
        /// 
        /// </param>
        /// <param name="opacity">
        /// Specifies an alpha transparency value to be used on the entire source 
        /// bitmap. The SourceConstantAlpha value is combined with any per-pixel 
        /// alpha values in the source bitmap. The value ranges from 0 to 255. If 
        /// you set SourceConstantAlpha to 0, it is assumed that your image is 
        /// transparent. When you only want to use per-pixel alpha values, set 
        /// the SourceConstantAlpha value to 255 (opaque).
        /// </param>
        public void SelectBitmap(Bitmap bitmap, int opacity)
        {
            // Does this bitmap contain an alpha channel?
            if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
            {
                throw new ApplicationException("The bitmap must be 32bpp with alpha-channel.");
            }

            // Get device contexts
            IntPtr screenDc = GetDC(IntPtr.Zero);
            IntPtr memDc = CreateCompatibleDC(screenDc);
            IntPtr hBitmap = IntPtr.Zero;
            IntPtr hOldBitmap = IntPtr.Zero;

            try
            {
                // Get handle to the new bitmap and select it into the current 
                // device context.
                hBitmap = bitmap.GetHbitmap(Color.FromArgb(0));
                hOldBitmap = SelectObject(memDc, hBitmap);

                // Set parameters for layered window update.
                Size newSize = new Size(bitmap.Width, bitmap.Height);
                Point sourceLocation = new Point(0, 0);
                Point newLocation = new Point(this.Left, this.Top);
                BLENDFUNCTION blend = new BLENDFUNCTION();
                blend.BlendOp = AC_SRC_OVER;
                blend.BlendFlags = 0;
                blend.SourceConstantAlpha = (byte)opacity;
                blend.AlphaFormat = AC_SRC_ALPHA;

                // Update the window.
                UpdateLayeredWindow(
                    this.Handle,     // Handle to the layered window
                    screenDc,        // Handle to the screen DC
                    ref newLocation, // New screen position of the layered window
                    ref newSize,     // New size of the layered window
                    memDc,           // Handle to the layered window surface DC
                    ref sourceLocation, // Location of the layer in the DC
                    0,               // Color key of the layered window
                    ref blend,       // Transparency of the layered window
                    ULW_ALPHA        // Use blend as the blend function
                    );
            }
            finally
            {
                // Release device context.
                ReleaseDC(IntPtr.Zero, screenDc);
                if (hBitmap != IntPtr.Zero)
                {
                    SelectObject(memDc, hOldBitmap);
                    DeleteObject(hBitmap);
                }
                DeleteDC(memDc);
            }
        }
        #region Native Methods and Structures

        const Int32 WS_EX_LAYERED = 0x80000;
        const Int32 HTCAPTION = 0x02;
        const Int32 WM_NCHITTEST = 0x84;
        const Int32 ULW_ALPHA = 0x02;
        const byte AC_SRC_OVER = 0x00;
        const byte AC_SRC_ALPHA = 0x01;

        [StructLayout(LayoutKind.Sequential)]
        struct Point
        {
            public Int32 x;
            public Int32 y;

            public Point(Int32 x, Int32 y)
            { this.x = x; this.y = y; }
        }

        [StructLayout(LayoutKind.Sequential)]
        struct Size
        {
            public Int32 cx;
            public Int32 cy;

            public Size(Int32 cx, Int32 cy)
            { this.cx = cx; this.cy = cy; }
        }

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        struct ARGB
        {
            public byte Blue;
            public byte Green;
            public byte Red;
            public byte Alpha;
        }

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        struct BLENDFUNCTION
        {
            public byte BlendOp;
            public byte BlendFlags;
            public byte SourceConstantAlpha;
            public byte AlphaFormat;
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst,
            ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc,
            Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);

        [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern IntPtr CreateCompatibleDC(IntPtr hDC);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern IntPtr GetDC(IntPtr hWnd);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

        [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool DeleteDC(IntPtr hdc);

        [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);

        [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool DeleteObject(IntPtr hObject);

        #endregion
    }
}

SplashScreen.cs

public partial class Form4 : CSWinFormLayeredWindow.PerPixelAlphaForm
{
    public Form4()
    {
        InitializeComponent();
        this.SelectBitmap(Properties.Resources.splash);
    }
}

Note

The original answer was based on turning double buffer off and overriding OnPaintBackground and drawing the image without calling base method. The answer had a known issue; while the form was moveless it was working well but if form was moving or the window behind the form was changed the window was not updating. You can see previous code in revisions. The current edit which is completely based on an MSDN code doesn't have any known issue.

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • But there is a problem :S When i tried this. It show like this : http://i66.tinypic.com/9knl9d.png – CoderWho Nov 04 '15 at 20:34
  • As I see in image, you did `InitializeComponent();` after `SetStyle`. You should `SetStyle` after `InitializeComponent();` – Reza Aghaei Nov 04 '15 at 20:38
  • Here is all that I performed. I think it's better to test the solution in a new clean form in your project. – Reza Aghaei Nov 04 '15 at 20:49
  • Thank you so much. As i see in your upoaded image it's working. You'r right it's about my solution. Thank you agian – CoderWho Nov 04 '15 at 20:57
  • In your example, the logo is in picturebox too right? – CoderWho Nov 04 '15 at 20:58
  • 1
    No, it is background image of form. and there is no picturebox. I think I should say it in answer. – Reza Aghaei Nov 04 '15 at 20:59
  • Hmm ok. I was using picturebox :) It's ok :) Thanks again – CoderWho Nov 04 '15 at 21:06
  • You are welcome, please see the update and known issue. – Reza Aghaei Nov 04 '15 at 21:08
  • As far as I remember, the form in this case cannot show controls. – Reza Aghaei Jan 17 '18 at 14:00
  • I assigned this to a pictureBox image. Could a .gif ever play its animation in a pictureBox, when I use it with WS_EX_LAYERED style? – taraz Nov 17 '19 at 15:07
  • @taraz see sample code 2 in [this post](https://stackoverflow.com/a/37473192/3110834). – Reza Aghaei Nov 17 '19 at 15:07
  • @Reza apologies for the necropost, but this works perfectly for me except when I have more than 1 layered window present. If there are 2, they show up at 100% opacity just fine. However in my case if I start to fade them at the same time it doesn't work well. Any thoughts? – Exergist Jul 27 '20 at 06:14
  • @Exergist I don't have any guess about the possible problem at the moment, but you may want to take a look at [this post](https://stackoverflow.com/a/51018033/3110834). Probably using WPF option for this purpose is the easiest. – Reza Aghaei Jul 27 '20 at 12:42
  • Thanks for the input @Reze. Here is link to a video showing the behavior in case there are any more insights you might provide (https://imgur.com/VhHusNF). – Exergist Jul 27 '20 at 14:00
  • @Reza nevermind I figured it out! I needed to update the code to properly modify the attributes of each layered window since my implementation wasn't separating the instances properly. For the record, your explanation and example are AWESOME. – Exergist Jul 27 '20 at 15:22
0

You can choose the level of transparency for an image via changing the alpha coefficient which is between 0 and 255. An image can be a backgrounf image too,no prob

private static Image ToGrayscale(Image s,int alpha)
        {
            Bitmap tImage = new Bitmap(s);

            for (int x = 0; x < tImage.Width; x++)
            {
                for (int y = 0; y < tImage.Height; y++)
                {
                    Color tCol = tImage.GetPixel(x, y);
                    Color newColor = Color.FromArgb(alpha, tCol.R, tCol.G, tCol.B);
                  tImage.SetPixel(x, y, newColor);
                }
            }
            return tImage;

        }
Rati Sharabidze
  • 69
  • 1
  • 12