Autor
|
Tema: Error Genérico en GDI+ (Leído 5,332 veces)
|
bybaal
Desconectado
Mensajes: 52
|
Hola tengo esta función para convertir un bitmap a icono y en algunas ocasiones ocurre la excepción 'Error Genérico en GDI+' en la última línea, alguna idea de que pueda estar pasando Public Function ToIcon(Image As Image, Width As Integer, Height As Integer, Optional MakeTransparent As Boolean = False, Optional Transparent As Color = Nothing) As Icon ToIcon = Nothing If IsNothing(Transparent) Then Transparent = Color.White Dim thumb As Bitmap = CType(Image.GetThumbnailImage(Width, Height, Nothing, IntPtr.Zero), Bitmap) If MakeTransparent Then thumb.MakeTransparent(Transparent) ToIcon = Icon.FromHandle(thumb.GetHicon()) End Function
|
|
|
En línea
|
|
|
|
LlopoRobot
Desconectado
Mensajes: 116
Un instante, una mente al unísono
|
La excepción 'Error Genérico en GDI+' suele ocurrir cuando hay un problema con los recursos de GDI+ del sistema. Es posible que se esté produciendo una fuga de memoria o que se esté utilizando demasiada memoria. Para solucionar este problema, puedes intentar liberar los recursos de memoria de GDI+ llamando al método Dispose en la imagen de vista previa y en el objeto Bitmap, así: Public Function ToIcon(Image As Image, Width As Integer, Height As Integer, Optional MakeTransparent As Boolean = False, Optional Transparent As Color = Nothing) As Icon ToIcon = Nothing If IsNothing(Transparent) Then Transparent = Color.White Dim thumb As Bitmap = CType(Image.GetThumbnailImage(Width, Height, Nothing, IntPtr.Zero), Bitmap) If MakeTransparent Then thumb.MakeTransparent(Transparent) ToIcon = Icon.FromHandle(thumb.GetHicon()) thumb.Dispose() Image.Dispose() End Function
Además, asegúrate de que la imagen y el objeto Bitmap se estén utilizando dentro de un bloque Using o se estén liberando adecuadamente en otro lugar del código.
|
|
|
En línea
|
I'm woman baby. Can't you tell?
|
|
|
bybaal
Desconectado
Mensajes: 52
|
Ya lo agregué, pero sigue el problema, por eso aquí comparto todo el código para que se vea mejor cual puede ser el problema Public Class Form1 Private WithEvents tmrRefresh As New Timer With {.Enabled = True, .Interval = 1} Private Sub tmrRefresh_Tick(sender As Object, e As EventArgs) Handles tmrRefresh.Tick Dim gr As Graphics Dim bmp As Bitmap = My.Resources.white Dim br As New SolidBrush(Color.Black) Dim free As String = AutoScaleSize(My.Computer.Info.AvailablePhysicalMemory, 2, False) Dim x() As String Dim por As Integer Dim colBar As Color Text = free x = Split(free) free = x(0) x = Split(free, ",") If Len(x(0)) = 1 Then x(0) = $"0{x(0)}" If Len(x(1)) = 1 Then x(1) = $"0{x(1)}" gr = Graphics.FromImage(bmp) gr.DrawString($"{x(0)},", New Font("Arial", 12, FontStyle.Bold), br, New PointF(0, 0)) gr.DrawString(x(1), New Font("Arial", 12, FontStyle.Bold), br, New PointF(0, 14)) por = Porciento(My.Computer.Info.AvailablePhysicalMemory, My.Computer.Info.TotalPhysicalMemory) Select Case por Case Is >= 75 : colBar = Color.Green Case Is >= 50 : colBar = Color.Yellow Case Is >= 25 : colBar = Color.Orange Case Is >= 0 : colBar = Color.Red End Select gr.DrawLine(New Pen(colBar, 5), 28, 2, 28, 30) Icon = ToIcon(bmp, 32, 32) bmp.Dispose() gr.Dispose() br.Dispose() End Sub End Class Module modExtras Public Function Porciento(Parte As ULong, Total As ULong, Optional Round As Boolean = False, Optional Decimals As Integer = 0) As Double Porciento = 0 Try Porciento = Parte * 100 / Total If Round Then Porciento = Math.Round(Porciento, Decimals) Catch ex As Exception End Try End Function Public Function ToIcon(Image As Image, Width As Integer, Height As Integer, Optional MakeTransparent As Boolean = False, Optional Transparent As Color = Nothing) As Icon ToIcon = Nothing 'Try If IsNothing(Transparent) Then Transparent = Color.White Dim thumb As Bitmap = CType(Image.GetThumbnailImage(Width, Height, Nothing, IntPtr.Zero), Bitmap) If MakeTransparent Then thumb.MakeTransparent(Transparent) ToIcon = Icon.FromHandle(thumb.GetHicon()) thumb.Dispose() Image.Dispose() 'Catch ex As Exception 'End Try End Function Public Function AutoScaleSize(Bytes As Decimal, Optional Decimals As Integer = 2, Optional FullName As Boolean = False, Optional BaseMil As Boolean = False) As String AutoScaleSize = "" Try Dim C As Integer Dim b As Decimal = Bytes Dim Div As Integer If BaseMil Then Div = 1000 Else Div = 1024 Do While b >= Div b /= Div C += 1 Loop b = Math.Round(b, Decimals) Select Case C Case 0 : If FullName Then Return b & " Bytes" Else Return b & " B" Case 1 : If FullName Then Return b & " KiloBytes" Else Return b & " KB" Case 2 : If FullName Then Return b & " MegaBytes" Else Return b & " MB" Case 3 : If FullName Then Return b & " GigaBytes" Else Return b & " GB" Case 4 : If FullName Then Return b & " TeraBytes" Else Return b & " TB" Case 5 : If FullName Then Return b & " PetaBytes" Else Return b & " PB" Case 6 : If FullName Then Return b & " ExaBytes" Else Return b & " EB" Case 7 : If FullName Then Return b & " ZettaBytes" Else Return b & " ZB" Case 8 : If FullName Then Return b & " YottaBytes" Else Return b & " YB" Case Else : If FullName Then Return Bytes & " Bytes" Else Return Bytes & " B" End Select Catch ex As Exception End Try End Function End Module
|
|
« Última modificación: 10 Abril 2023, 20:36 pm por bybaal »
|
En línea
|
|
|
|
Elektro Enjuto
|
El tamaño y las características de la imagen de recurso "white" son desconocidos, así que no soy capaz de reproducir el problema que describes. De todas formas, estás añadiendo una carga altísima y totalmente innecesaria al utilizar procedimientos de dibujado manual, generando una lentitud de respuesta en tu aplicación, y por culpa de un intervalo de temporizador tan reducido, todo para hacer cosas que son facilmente accesibles mediante las propiedades del Form... Primeramente, ¿por qué asignas la imagen de icono más de una única vez?. En cada iteración del temporizador vuelves a pasar por todo el procedimiento de copia de imagen y resscalado solo para volver a reasignar la misma imagen una y otra vez, sin descanso. Lo mismo haces al dibujar texto en la barra de título del form, cosa que puedes asignar mediante la propiedad Form.Text, y eso siempre estará mucho más optimizado que cualquier procedimiento casero de dibujado como el que estás utilizando. Por último aquí te dejo una versión simplificada de la función ToIcon, sin recurrir a la función GetThumbnailImage para no deteriorar la calidad inicial pre-obtención de icono: <DebuggerStepThrough> Public Function ToIcon(image As Image, size As Size, Optional makeTransparent As Boolean = False, Optional transparentColor As Color = Nothing) As Icon Using clone As New Bitmap(image, size) If makeTransparent AndAlso (transparentColor <> Color.Empty) Then clone.MakeTransparent(transparentColor) End If Return Icon.FromHandle(clone.GetHicon()) End Using End Function
Saludos.
|
|
« Última modificación: 30 Agosto 2023, 19:30 pm por Elektro Enjuto »
|
En línea
|
@%$& #$ %&#$, ¡hay que decirlo más!.
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Hacer un Lanzador Genérico
Programación Visual Basic
|
Rumaca
|
2
|
2,163
|
14 Enero 2007, 13:19 pm
por Gorky
|
|
|
Error genérico en GDI+
.NET (C#, VB.NET, ASP)
|
Crazy.sx
|
4
|
14,779
|
30 Diciembre 2012, 06:03 am
por Crazy.sx
|
|
|
Algoritmo genérico
Programación C/C++
|
pilo312
|
0
|
1,747
|
28 Mayo 2016, 00:24 am
por pilo312
|
|
|
Monitor genérico que no es PnP
Windows
|
apok26
|
1
|
2,708
|
15 Septiembre 2016, 03:47 am
por KenshiroOne
|
|
|
soap generico
Programación Visual Basic
|
adla
|
2
|
2,250
|
19 Diciembre 2020, 08:24 am
por BlackZeroX
|
|