Sin leer más que el post principal, te respondo algunas cosas que no se si ya te habrán respondido:
Para volver transparente el color de una imagen no necesitas nada más que utilizar el método Bitmap.MakeTransparent...
Ejemplo:
Una forma sofisticada sería utilizando la clase Region. De este modo crearías a tu antojo la región visible del control, y la que no sería visible (es decir, la parte transparente de tu PictureBox).
Para crear la región de forma óptima, me refiero, para determinar que debe ser visible y que no, probablemente deberías analizar los píxeles de la imagen, cosa que puedes hacer mediante el método Bitmap.LockBits / Bitmap.UnlockBits y un búcle for. Hay muchos ejemplos en Internet. Para aplicar la región utilizarías la propiedad PictureBox.Region del control...
Una forma más rudimentaria pero igualmente eficaz dependiendo de tus requisitos, sería asignarle un control padre a los controles que quieres superponer a ese PictureBox. Simplemente utiliza la propiedad Control.Parent...
Ejemplo:
Doy por hecho que estás trabajando bajo la tecnología Windows Forms, pero nada te impide agregar una referencia a los ensamblados principales de la tecnología WPF (PresentationCore.dll, PresentationFramework.dll y WindowsBase.dll) para poder acceder al espacio de nombres System.Windows.Media y usar los miembros que provee.
De todas formas, para hacer eso, mejor sería que directamente lo hagas en WPF ya que te beneficiarás en lo que respecta a "transprencia real".
Las definiciones de esas funciones son incorrectas. Carece de sentido que asignes como punto de entrada la versión ANSI de una función, y luego le asignes el set de caracteres Unicode al marshaler. No es un problema en este caso, pero en funciones que manejen strings te daría problemas de codificación de texto al enviar o recibir argumentos, o directamente error al intentar llamar a la función. No hagas eso. Si no sabes muy bien como funcionan estas cosas entonces deberías informarte sobre la correcta utilización de los servicios de invocación de plataforma en .NET (Platform Invoke o P/Invoke en Inglés)...
Aparte, esas funciones en teoría solo te funcionarán correctamente bajo un proceso en modo de 32 bits. En su lugar deberías usar las funciones GetWindowLongPtr y SetWindowLongPtr para compatibilizar tu código bajo un proceso en modo 64 bits o neutral (AnyCPU), mientras que en 32 bits te seguiría funcionando igual...
Un saludo.
Cita de: FJDA en 21 Abril 2019, 22:03 PM
estoy intentado substraer el color de una imagen.
Para volver transparente el color de una imagen no necesitas nada más que utilizar el método Bitmap.MakeTransparent...
Ejemplo:
Código (vbnet) [Seleccionar]
Dim bmp As Bitmap = DirectCast(Bitmap.FromFile("C:\image.png"), Bitmap)
Dim clrs As Color() = { ' Colores específicos a substraer.
Color.FromArgb(255, 0, 0, 0),
Color.FromArgb(255, 255, 255, 255)
}
For Each clr As Color In clrs
bmp.MakeTransparent(clr)
Next
Me.PictureBox1.Image = bmp
Cita de: FJDA en 21 Abril 2019, 22:03 PM
El objetivo es superponer un objeto PictureBox y hacer transparentar una parte de color verde de modo que se puedan ver objetos que hay debajo del PictureBox.
Una forma sofisticada sería utilizando la clase Region. De este modo crearías a tu antojo la región visible del control, y la que no sería visible (es decir, la parte transparente de tu PictureBox).
Para crear la región de forma óptima, me refiero, para determinar que debe ser visible y que no, probablemente deberías analizar los píxeles de la imagen, cosa que puedes hacer mediante el método Bitmap.LockBits / Bitmap.UnlockBits y un búcle for. Hay muchos ejemplos en Internet. Para aplicar la región utilizarías la propiedad PictureBox.Region del control...
- Control.Region Property (System.Windows.Forms) | Microsoft Docs
- Region Class (System.Drawing) | Microsoft Docs
Una forma más rudimentaria pero igualmente eficaz dependiendo de tus requisitos, sería asignarle un control padre a los controles que quieres superponer a ese PictureBox. Simplemente utiliza la propiedad Control.Parent...
Ejemplo:
Código (vbnet) [Seleccionar]
Button1.Parent = PictureBox1
Button1.Location = New Point(0, 0)
Cita de: FJDA en 21 Abril 2019, 22:03 PM
Mi Net no tiene la System.Windows.Media que creo serviría para esto.
Doy por hecho que estás trabajando bajo la tecnología Windows Forms, pero nada te impide agregar una referencia a los ensamblados principales de la tecnología WPF (PresentationCore.dll, PresentationFramework.dll y WindowsBase.dll) para poder acceder al espacio de nombres System.Windows.Media y usar los miembros que provee.
De todas formas, para hacer eso, mejor sería que directamente lo hagas en WPF ya que te beneficiarás en lo que respecta a "transprencia real".
Cita de: FJDA en 21 Abril 2019, 22:03 PMCódigo (vbnet) [Seleccionar]<DllImport("User32.dll", EntryPoint:="GetWindowLongA", CharSet:=CharSet.Unicode), SuppressUnmanagedCodeSecurityAttribute>
Private Shared Function GetWindowLong(ByVal HWND As IntPtr, ByVal nIndex As Integer) As Integer
End Function
<DllImport("User32.dll", EntryPoint:="SetWindowLongA", CharSet:=CharSet.Unicode), SuppressUnmanagedCodeSecurityAttribute>
Private Shared Function SetWindowLong(ByVal HWND As IntPtr, ByVal nIndex As Integer, ByVal dwNewLong As Integer) As Integer
End Function
Las definiciones de esas funciones son incorrectas. Carece de sentido que asignes como punto de entrada la versión ANSI de una función, y luego le asignes el set de caracteres Unicode al marshaler. No es un problema en este caso, pero en funciones que manejen strings te daría problemas de codificación de texto al enviar o recibir argumentos, o directamente error al intentar llamar a la función. No hagas eso. Si no sabes muy bien como funcionan estas cosas entonces deberías informarte sobre la correcta utilización de los servicios de invocación de plataforma en .NET (Platform Invoke o P/Invoke en Inglés)...
Aparte, esas funciones en teoría solo te funcionarán correctamente bajo un proceso en modo de 32 bits. En su lugar deberías usar las funciones GetWindowLongPtr y SetWindowLongPtr para compatibilizar tu código bajo un proceso en modo 64 bits o neutral (AnyCPU), mientras que en 32 bits te seguiría funcionando igual...
Un saludo.