Visual Basic Foro
Programación => Visual Basic 6 => Mensaje iniciado por: LeandroA en Octubre 22, 2010, 01:33:22 am
-
Hi, tengo un problema, que me voló la cabeza seguro que es una boludes mas grande que una casa pero se me quemaron las neuronas, es medio complicado explicarlo pero voy a intentarlo.
supongamos una imagen, esta tiene unas dimensiones de 16 x 16px por cada pixel de esa imagen tenemos 3 bytes esto da como resultado un array de 768 bytes
16 x 16 x 3 = 768
otro ejemplo
32 * 16 * 3 = 1536
bien haciendo esa ecuación puedo saber la cantidad de bytes que ocupara la imagen, ahora supongamos que yo quiero ingresar la cantidad de bytes y deseo que la imagen sea lo mas cuadrada posible que ecuación tengo que hacer???
yo puedo poner (tomando el primer ejemplo)
Ancho = Sqr(768 / 3)
Alto = Ancho
pero que pasa si el array que ingreso es de 769 bytes tengo un resultado erróneo de 16,0104.. y esto no es una medida valida para una imagen ya que no puede tener decimales.
entonces puede que tenga que adicionar uno/s bytes extra al array para que sea un valor "par" así poder obtener un resultado correcto, no importa que sea una imagen 100% cuadrada, pero que sea lo mas aproximado.
Se entiende??, Gracias
-
Por que no redondeas el valor final con round o int
-
Función Round
La función Round se utiliza para redondear un número decimal, devolviendo un número entero.
Ejemplo:
Dim Mimumero As Long
Minumero = Round(245.8) '(La función devuelve 246)
Minumero = Round(245.3) '(La función devuelve 245)
Minumero = Round(245.5) '(La función devuelve 245)
Round posee un parámetro opcional por si queremos incluir los dígitos decimales.
2.2 - Rnd y Randomize - Números aleatorios
Para generar números aleatorios, Visual Basic incluye 2 funciones: Rnd y Randomize.
La función Rnd devuelve un número aleatorio, y esta posee un solo parámetro.
Ejemplo :
Rnd (número)
Pero para poder generar dichos números aleatorios, debemos utilizar previamente la función Randomize con la siguiente fórmula:
Dim LimiteInferior As Integer
Dim LimiteSuperior As Integer
LimiteInferior = 20
LimiteSuperior = 40
MsgBox Int((LimiteInferior - LimiteSuperior + 1) * Rnd + LimiteInferior)
En el ejemplo anterior, se generarán números aleatorios comprendidos entre el 20 y el 40
Nota: en este enlace podés ver un ejemplo que permite generar números aleatorios no repetidos
Funciones matemáticas
Las principales funciones matemáticas provistas por Visual Basic son:
* Abs: Devuelve el valor absoluto de una expresión numérica.
* Atn: Devuelve el arco tangente de un número.
* Cos: Devuelve el coseno de un ángulo.
* Exp: Devuelve el número "e" elevado a una potencia.
* Log: Devuelve el logaritmo natural de un número.
* Sgn: Devuelve un valor indicando el signo de un número.
* Sin: Devuelve el seno de un ángulo.
* Sqr: Devuelve la raíz cuadrada de un número.
* Tan: Devuelve la tangente de un ángulo.
Fuente: http://www.recursosvisualbasic.com.ar
-
si el resultado del sqr te da con coma, tenes q sacar el entero (no redondear). despues, podes hacer un random para elegir cual de los dos ejes tendra una linea de pixel mas, algo asi como:
Randomize Timer
If (Rnd * 1) > .5 Then
iAlto = iAlto + 1
Else
iAncho = iAncho + 1
End If
-
Leandro,
Por favor, mire este problema desde otro punto de vista.
Los datos de píxeles en la huella de la imagen en la memoria no es siempre apretados. Debemos distinguir entre la anchura de una "imagen" y la anchura de una "scanline". "Scanline" es una representación de una línea de la imagen en la memoria que en muchos casos tiene que estar lleno de bytes adicionales ("padding") a la cercana frontera de un "WORD" o un "DWORD". Esto depende del formato de la imagen.
Por favor, búsqueda de alineación de los datos de píxeles en el Internet porque mi español es demasiado pobre para describir este problema en detalle.
Tal vez usted también necesitará la siguiente tabla para hacer los cálculos de "padding" más fácil. Está escrito en Fbsl pero usted será capaz de hacerlo aplicable para VB también cambiando "0x" a "&H", "BOr" a "Or" y "BAnd" a "And":
(http://www.fbsl.net/phpbb2/download/file.php?mode=view&id=986)
Saludos
Mike Lobanovsky
-
Hi Mike, i get what I wanted
Public Function ByteAlignOnWord(ByVal BitDepth As Byte, ByVal Width As Long) As Long
' function to align any bit depth on dWord boundaries
ByteAlignOnWord = (((Width * BitDepth) + &H1F&) And Not &H1F&) \ &H8&
End Function
my problem is solved
Private Function CreateDimensions(ByVal lSize As Long, ByRef lWidth As Long, ByRef lHeight As Long) As Long
Dim lRet As Long
Dim i As Long
lHeight = Sqr(lSize / 3) '/ 10
lWidth = 0
Do While lHeight > 32000
lHeight = lHeight / 2
Loop
Do
i = i + 1
lRet = lHeight * ByteAlignOnWord(24, lWidth + i)
If lRet >= lSize Then
lWidth = lWidth + i
CreateDimensions = lRet - lSize
Exit Do
End If
Loop
End Function
It was just an experiment, I wanted to try to compress an array using GDI +, was not as pleasant as expected compression
Thank you very much for your help