2014-12-30 2 views
1

Я пытаюсь создать заставку для моего приложения. У меня есть изображение .PNG, которое имеет некоторые частично прозрачные части.Частично прозрачный заставку в C#

Я сделал форму без полей и отключил контрольную панель. Однако цвет фона вызывает проблемы.

Сначала я разместил изображение на картинке. Затем я сделал вид фона прозрачным таким образом:

this.BackColor = Color.Magenta; 
this.TransparencyKey = Color.Magenta; 

Это вроде как работало. Полностью прозрачные части экрана прозрачны, но пурпурный цвет можно увидеть в частично прозрачных деталях.

Затем я попытался поместить изображение в качестве фонового изображения формы. Я пробовал использовать этот код, чтобы сделать фон формы прозрачным:

private void Form1_Load(object sender, EventArgs e) 
{ 
    this.SetStyle(System.Windows.Forms.ControlStyles.SupportsTransparentBackColor, true); 
    this.BackColor = System.Drawing.Color.Transparent; 
} 

Это тоже не сработало. Фон все еще не прозрачен. Что мне делать?

+0

'this.BackColor = Color.Transparent;'? – geedubb

+0

Не работает. Фон теперь светло-серый. – Kestis

+0

Вы видели http://www.codeproject.com/Articles/6511/Transparent-Splash-Screen - может помочь вам – geedubb

ответ

3

Почему пурпурный? Попробуйте использовать Белый. Я установил задний цвет Белый и прозрачный ключ Белый. На изображении ниже случайным полем с изображением является мой всплеск.

Results

+0

Это не сработает, так как частично прозрачная часть - это тень. – Kestis

+0

Можете ли вы разместить изображение или изображение? – Baddack

+0

Я решил использовать этот метод. Я удалил тень из всплеска, так что останется только полная или отсутствующая прозрачность. Не частичная прозрачность. – Kestis

2

TransparencyKey установит форму, чтобы быть полностью непрозрачным, за исключением пикселей точного цвета указанного. AFAIK он делает это, фактически определяя форму окна WindowRegion, то есть на основе пикселей, соответствующих цвету - эти пиксели больше не являются частью вашего окна и могут быть нажаты.

Похоже, что ваш PNG имеет альфа-слой, т.е. уровни прозрачности 0..255, которые смешиваются с цветом фона (пурпурный), и после этого только прозрачные пурпурные пиксели становятся прозрачными.

Вы можете попробовать:

  • Выберите цвет, например, Magenta не используется в всплеске и положить, что в вашем всплеске PNG вместо полностью прозрачных областей в непрозрачных пикселях
  • Захвата копии рабочего стола растрового изображения под окном, прежде чем он показывает, и поставить это в PictureBox под вашим всплеск.

Частично прозрачные области брызг затем будут смешиваться с фоновым изображением, полностью прозрачные области будут соответствовать TransparencyKey и быть прозрачными.

Но вы получите визуальные артефакты, если остальная часть рабочего стола изменится, пока отображается всплеск, если ваш экран заставки перемещается и т. Д.

редактировать: Кажется, есть простое решение here без использования TransparencyKey

1

Вы можете сделать это с layered windows и UpdateLayeredWindow() Api:

protected override CreateParams CreateParams 
{ 
    get 
    { 
     // Add the layered extended style (WS_EX_LAYERED) to this window 
     CreateParams createParam = base.CreateParams; 
     createParam.ExStyle = (createParam.ExStyle | APIHelp.WS_EX_LAYERED); 
     return createParam; 
    } 
} 

И в вашей форме load event:

IntPtr memDc, hBmp, hOldBmp; 

private void Form1_Load(object sender, EventArgs e) 
{ 
    APIHelp.BLENDFUNCTION blend; 

    //Only works with a 32bpp bitmap 
    blend.BlendOp = APIHelp.AC_SRC_OVER; 
    //Always 0 
    blend.BlendFlags = 0; 
    //Set to 255 for per-pixel alpha values 
    blend.SourceConstantAlpha = 255; 
    //Only works when the bitmap contains an alpha channel 
    blend.AlphaFormat = APIHelp.AC_SRC_ALPHA; 

    IntPtr screenDc; 

    screenDc = APIHelp.GetDC(IntPtr.Zero); 

    Bitmap bmp; 

    using (bmp = (Bitmap)Bitmap.FromFile(@"C:\.......png")) //the image must be the same size as your form 
    { 
     memDc = APIHelp.CreateCompatibleDC(screenDc); 
     hBmp = bmp.GetHbitmap(Color.FromArgb(0)); 
     hOldBmp = APIHelp.SelectObject(memDc, hBmp); //memDc is a device context that contains our image 
    } 

    APIHelp.DeleteDC(screenDc); 

    APIHelp.Size newSize; 
    APIHelp.Point newLocation; 
    APIHelp.Point sourceLocation; 

    newLocation.x = this.Location.X; 
    newLocation.y = this.Location.Y; 

    sourceLocation.x = 0; 
    sourceLocation.y = 0; 

    newSize.cx = this.Width; 
    newSize.cy = this.Height; 

    APIHelp.UpdateLayeredWindow(Handle, IntPtr.Zero, ref newLocation, ref newSize, memDc, ref sourceLocation, 
      0, ref blend, APIHelp.ULW_ALPHA); 
} 

класса API-справочник:

class APIHelp 
{ 
    public const Int32 WS_EX_LAYERED = 524288; 
    public const Int32 ULW_ALPHA = 2; 
    public const byte AC_SRC_OVER = 0; 
    public const byte AC_SRC_ALPHA = 1; 

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

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

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

    [StructLayout(LayoutKind.Sequential)] 
    public struct BLENDFUNCTION 
    { 
     public Byte BlendOp; 
     public Byte BlendFlags; 
     public Byte SourceConstantAlpha; 
     public Byte AlphaFormat; 
    } 

    [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)] 
    public static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, 
     ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pptSrc, uint crKey, 
     [In] ref BLENDFUNCTION pblend, uint dwFlags); 


    [DllImport("gdi32.dll", EntryPoint = "CreateCompatibleDC", SetLastError = true)] 
    public static extern IntPtr CreateCompatibleDC([In] IntPtr hdc); 

    [DllImport("gdi32.dll", EntryPoint = "SelectObject")] 
    public static extern IntPtr SelectObject([In] IntPtr hdc, [In] IntPtr hgdiobj); 

    [DllImport("user32.dll")] 
    public static extern IntPtr GetDC(IntPtr hWnd); 

    [DllImport("gdi32.dll", EntryPoint = "DeleteDC")] 
    public static extern bool DeleteDC([In] IntPtr hdc); 

    [DllImport("gdi32.dll", EntryPoint = "DeleteObject")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    public static extern bool DeleteObject([In] IntPtr hObject); 
} 

Когда форма закрывается освободить ресурсы:

APIHelp.SelectObject(memDc, hOldBmp); 
APIHelp.DeleteObject(hBmp); 
APIHelp.DeleteDC(memDc); 
Смежные вопросы