0

我一直在尝试解决 .NET(所有版本)本身不支持 TRUE 透明度的古老问题,并且在阅读了数千篇文章、问题/答案、论坛、msdn 文章等之后,除了被能够通过使用整个表单来做到这一点,其中没有可见的控件(请参阅http://www.codeproject.com/Articles/1822/Per-Pixel-Alpha-Blend-in-C

我已经部分放弃了这种搜索,而是决定通过使用 MDIParent/Client 情况来满足,其中每个图形/文本都直接绘制到表单上。

我遇到的问题是,当我保存透明度时,我最终会在任何阴影周围出现一个斑点,我认为(但不确定)是 PNG 正在以较低的分辨率保存或 alpha 通道丢失或者其他东西,MakeTransparent(Insert Color Here),就是不满意。如果你能说明这个过程哪里出错了……请告诉我。

输入图像

在此处输入图像描述

输出图像

在此处输入图像描述

我正在使用的代码如下:

    Imports Graphics

    Public Class PictureForm
        Private Declare Auto Function BitBlt Lib "gdi32.dll" (ByVal _
            hdcDest As IntPtr, ByVal nXDest As Integer, ByVal _
            nYDest As Integer, ByVal nWidth As Integer, ByVal _
            nHeight As Integer, ByVal hdcSrc As IntPtr, ByVal nXSrc _
            As Integer, ByVal nYSrc As Integer, ByVal dwRop As  _
            System.Int32) As Boolean
        Private Const SRCCOPY As Integer = &HCC0020

        Public Graphic As Drawing.Graphics
        Private Sub PictureForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.Show()
            Graphic = Me.CreateGraphics
            Graphic.CompositingQuality = Drawing2D.CompositingQuality.HighQuality

            Graphic.DrawImage(Image.FromFile("C:\Users\Daniel\Downloads\PNG-icon.png"), 35, 22)

            Dim bmp As Bitmap = GetFormImage()
            bmp.MakeTransparent(Color.White)
            bmp.Save("test.png", System.Drawing.Imaging.ImageFormat.Png)
            bmp.Dispose()       

        End Sub

        Public Function GetFormImage() As Bitmap
            ' Get this form's Graphics object.
            Dim me_gr As Drawing.Graphics = Me.CreateGraphics

            ' Make a Bitmap to hold the image.
            Dim bm As New Bitmap(Me.ClientSize.Width, Me.ClientSize.Height, me_gr)
            Dim bm_gr As Drawing.Graphics = Drawing.Graphics.FromImage(bm)
            Dim bm_hdc As IntPtr = bm_gr.GetHdc

            ' Get the form's hDC. We must do this after 
            ' creating the new Bitmap, which uses me_gr.
            Dim me_hdc As IntPtr = me_gr.GetHdc

            ' BitBlt the form's image onto the Bitmap.
            BitBlt(bm_hdc, 0, 0, Me.ClientSize.Width, _
                Me.ClientSize.Height, _
                me_hdc, 0, 0, SRCCOPY)
            me_gr.ReleaseHdc(me_hdc)
            bm_gr.ReleaseHdc(bm_hdc)

            ' Return the result.
            Return bm
        End Function

    End Class

此外,您会注意到第一张图像中的字母在输出中没有被渲染为透明。

4

1 回答 1

0

The problem is that you are "storing" your graphics on the form - where no alpha exists.

You can easily fix this by keeping an off-screen bitmap which you do all your painting to and when you modify it, you also draw it to the form.

Then you won't need the GetFormImage method at all anymore - you just save your off-screen bitmap directly (which carries alpha information).

PS. You are missing several .Dispose() calls.

于 2014-07-28T18:50:48.190 回答