Autor
|
Tema: ¿Cómo promediar 2 colores? (Leído 1,700 veces)
|
Tachikomaia
Conectado
Mensajes: 1.245
Superhacker (es broma xD )
|
Si digo CC0000, es decir 204, 0, 0 y CCCCCC, es decir 204, 204, 204 el resultado debe ser 204, 102, 102 Entiendo que debo convertir el hexadecimal a decimal y luego hacer promedios. GPT me dijo que con Action Script 1.0 se puede hacer esto para la conversión: Color1 = "CC0000"; Color2 = "CCCCCC"; Color1Convertido = Number("0x"+Color1); Color2Convertido = Number("0x"+Color2); Para el promedio pensé en tomar los 2 1eros caracteres de cada uno, hacer el promedio, luego tomar otros 2, y así, pero para ahorrar tiempo le dije que lo haga él. Hizo: // Crea un cuadro de diálogo de entrada de texto para ingresar el primer color var color1:String = prompt("Ingrese el primer color en formato hexadecimal:", "CC0000"); // Crea un cuadro de diálogo de entrada de texto para ingresar el segundo color var color2:String = prompt("Ingrese el segundo color en formato hexadecimal:", "CCCCCC"); // Convierte los colores a decimal var decimal1:Number = Number("0x" + color1); var decimal2:Number = Number("0x" + color2); // Calcula el promedio de cada componente RGB var r1:Number = (decimal1 >> 16) & 0xFF; var g1:Number = (decimal1 >> 8) & 0xFF; var b1:Number = decimal1 & 0xFF; var r2:Number = (decimal2 >> 16) & 0xFF; var g2:Number = (decimal2 >> 8) & 0xFF; var b2:Number = decimal2 & 0xFF; var rPromedio:Number = Math.round((r1 + r2) / 2); var gPromedio:Number = Math.round((g1 + g2) / 2); var bPromedio:Number = Math.round((b1 + b2) / 2); // Convierte el color promedio a hexadecimal var colorPromedio:String = decimalToHex((rPromedio << 16) | (gPromedio << 8) | bPromedio); // Muestra el color promedio trace("El color promedio es: #" + colorPromedio); // Función para convertir un número decimal a hexadecimal function decimalToHex(decimal:Number):String { var hex:String = decimal.toString(16); while (hex.length < 6) { hex = "0" + hex; } return hex.toUpperCase(); }
Al intentar ejecutarlo dice: Escena=Escena 1, Capa=Capa 1, Fotograma=1: Line 31: Se espera '{' function decimalToHex(decimal:Number):String {
Escena=Escena 1, Capa=Capa 1, Fotograma=1: Line 37: Se ha detectado un '}' inesperado }
Siempre me costó entender esas pistas, y este código claro que tampoco lo entiendo. ¿Por qué "0x"+ convierte a hexadecimal tan fácil? ¿es como una función (Number, toString, etc)? ¿Qué es esto (decimal1 >> 16) & 0xFF; (decimal1 >> 8) & 0xFF; decimal1 & 0xFF; ? ¿Qué hace esto? function decimalToHex(decimal:Number):String { var hex:String = decimal.toString(16); while (hex.length < 6) { hex = "0" + hex; } return hex.toUpperCase(); }
¿Convierte decimal en string? Según recuerdo lo que se convierte es lo que va entre paréntesis. ¿Qué significaría 16? ¿convierte un número a hexadecimal así nomás? Luego entiendo que agrega 0s si la longitud del hex generado es <6. ¿Y esto qué es? var colorPromedio:String = decimalToHex((rPromedio << 16) | (gPromedio << 8) | bPromedio); Se define a una variable llamando a una función... ¿pero qué es << 16, << 8 y los | ? Por ahí dice: Después, descomponemos cada valor decimal en sus componentes RGB (rojo, verde y azul) utilizando operaciones de desplazamiento y máscaras bit a bit. Calculamos el promedio de cada componente y lo redondeamos utilizando la función Math.round().
Finalmente, convertimos el color promedio de decimal a hexadecimal utilizando la función decimalToHex(), que toma el valor decimal y lo convierte a una cadena hexadecimal de 6 dígitos, agregando ceros a la izquierda si es necesario.
El resultado se muestra en la consola utilizando la función trace(). Creo que lo intentaré a mi manera pero agradezco explicación.
|
|
|
En línea
|
|
|
|
profinet
Desconectado
Mensajes: 31
|
Debes elevar al cuadrado cada valor RGB, después hacer la media, y luego calcular la raíz cuadrada de cada uno para revertir la primera operación. NewColor = sqrt((R1^2+R2^2)/2), sqrt((G1^2+G2^2)/2), sqrt((B1^2+B2^2)/2) Usando este enfoque, al elevar al cuadrado los componentes RGB antes de promediar, estamos aplicando un tipo de "ponderación" que favorece los valores más altos y minimiza el efecto de los valores más bajos. Esto es útil porque los valores RGB cuadrados preservan mejor las diferencias perceptuales entre los colores originales.
|
|
|
En línea
|
Don't shy away from the terminal; embrace it! In the GNU world, everything is a file.
|
|
|
Serapis
|
¿Por qué "0x"+ convierte a hexadecimal tan fácil? ¿es como una función (Number, toString, etc)? 0x es el prefijo para indicar que el número debe interpretarse como un valor hexadecimal. ¿Qué es esto (decimal1 >> 16) & 0xFF; (decimal1 >> 8) & 0xFF; decimal1 & 0xFF; los signos: << y >> son operadores de desplazamiento de bits. >> Equivale a dividir entre 2 por cada valor indicado. << Equivale a multiplicar por 2 por cada valor indicado. Por ejemplo, supongamos que tengo la variable 'valor' que vale 1234 entonces: 'valor << 3' significa que se añaden 3 bits con valor 0 en la posición de menor peso, lo que equivaldría a haberlo multiplicado por 8, es decir equivale a esto: valor = (valor * 2^³) con lo que el valor finalmente sería: En decimal:antes: 1234, luego: 9872 En binario:10011010010, luego 10011010010000 Ahora deberías entender que la operación: valor >> 3, lo que hace es eliminar los 3 bits más bajos que es equivalente a dividir entre 8. Al ser operaciones de bit, son operaciones mucho más rápidas que multiplicar o dividir, pues requieren un solo ciclo de reloj (técnicamente). El símbolo: '&' es el operador booleano AND y '0xFF' es el valor 255 expresado en hexadecimal, básicamene cuando haces un valor and 255, todos los bits por encima del 8º se ponen a cero. toma la calculadora escribe (en decimal) 123456 (luego pulsa el botón de opción 'bin' para ver el valor en binario, luego devuélvelo a decimal pulsando el botón de opción 'dec') pulsa la tecla AND y luego escribe 255, el resultado será: 64, es decir 0100.0000 dicho de otro modo, hace que el valor esté en el rango 0-255. En definitiva tratándose del valor del canal de un píxel se asegura que el resultado no esté fuera de rango. ¿Qué hace esto? function decimalToHex(decimal:Number):String { var hex:String = decimal.toString(16); while (hex.length < 6) { hex = "0" + hex; } return hex.toUpperCase(); }
¿Convierte decimal en string? Sí. Es una función que convierte un número decimal en una string formateado en hexadecimal y lo devuelve en mayúsculas . Según recuerdo lo que se convierte es lo que va entre paréntesis. Estás más verde de lo que pensaba en el lenguaje del que estás 'enamorado'... Convierte en hexadecimal el valor que contiene el parámetro de tipo numérico llamado 'decimal'. ¿Qué significaría 16? ¿convierte un número a hexadecimal así nomás? Luego entiendo que agrega 0s si la longitud del hex generado es <6. El 16, indica a la clase string, que lo cambie en la base numérica hexadecimal, si pones '8' lo convierte a octal, si pones '2' lo convierte a binario... creo que admite hasta la base 32 o así... (también 3, 5, 21,22... etc...) ¿Y esto qué es? var colorPromedio:String = decimalToHex((rPromedio << 16) | (gPromedio << 8) | bPromedio); Se define a una variable llamando a una función... ¿pero qué es << 16, << 8 y los | ? Se define un variable sí, que recibe como valor el retorno de la función. La función recibe un valor numérico, en este caso es una expresión numérica (una operación). Sería equivalente a definir una variable numerica y asignarle el resultado de esa expresión... y que luego fuere esa variable la que pasaras a la función, pero así como está escrito, te ahorras código (igualmente el compilador debe crear una variable temporal para calcular el resultado de la expresión). (rPromedio << 16) significa: multiplica 'rPromedio * 65536' (es una operación entera, como ya te indiqué más arriba no multiplica, solo añade bits, de la parte baja exactamente 16 bits '0', en realidad desplaza todos los bits (a la vez), 16 posiciones arriba, rellenando con 0 las posiciones más bajas que antes estaban ocupadas). Después de calcular esos 2 valores 'r' y 'g' los unifica en un solo valor mediante el operador OR (el símbolo '|') Un ejemplo de desplzamiento a la izquierda, sea el valor 5, en bnario 101, lo desplazaremos primero 1, luego 2, luego 3 y luego 8. 5 en binario: 101 5 << 1, que da: 1010, en decimal 10 5 << 2, que da: 10100, en decimal: 20 5 << 3, que da: 101000, en decimal: 40 5 << 8, que da: 10100000000, en decimal 1280 Esta expresión: (rPromedio << 16) | (gPromedio << 8) | bPromedio lo que en realidad está haciendo es colocar cada valor (byte) que representa el canal de color del pixel, en la posición que deben ocupar... sería equivalente a: color = (rojo * 65536) + (verde * 256) + azul colorPromedio = decimalToHex(color) Nota que usar la suma en bytes perfectamente acotados en sus rangos, es equivalente a usar el operador OR, que es más rápido que la suma. RR000 \RR posición del byte rojo, tras multiplicarlo por 65536 00VV00 \ GG posición del byte verde, tras multplicarlo por 256 0000AA \ posición del byte azul... -------------- RRVVAA Para calcular el promedio de 2 valores en efecto... 1 debes descomponer el color en sus canales: azul1 = (color1 and 255) verde1 = ((color1 \ 256) and 255) rojo1 = (color1 \ 65536) Lo mismo para color2... (rojo2, verde2 y azul2) 2 luego sumar los canales individuales y promediarlos: tmpRojo = ((rojo1 + rojo2) \2) tmpVerde = ((verde1 + verde2) \2) tmpAzul = ((azul1 + azul2) \2) 3 Finalmente montar el resultado de los canales al color deseado... color = (tmpRojo * 65536) + (tmpVerde * 256) + tmpAzul La forma seguida en el código es más óptima en cuanto al rendimiento, pues utiliza operaciones binarias... las multiplicaciones y divisiones son muy costosas comparativamente. Todo esto en realidad son cosas elementales de programación, te suena a chino, no solo por ser autodidacta (que no es en sí el problema), es debido quizás a ser demasiado cabezón en no haber querido aprender las cosas elementales que además son comunes e indistintas a cualquier lenguaje. El escaso tiempo que ahorraste en no aprender (3-6 mses) lo pierdes ahora (con creces) en detalles insignificantes porque para tí son galimatías incomprensibles.
|
|
« Última modificación: 8 Mayo 2024, 23:50 pm por Serapis »
|
En línea
|
|
|
|
Tachikomaia
Conectado
Mensajes: 1.245
Superhacker (es broma xD )
|
profinet: Eso lo pensaré más adelante. para tí son galimatías incomprensibles. En general 0x es el prefijo para indicar que el número debe interpretarse como un valor hexadecimal. Ya veo: A = 0x20; me da 32. Así que con >> y << las operaciones funcionan más rápido... Nunca me habían dicho. Pero sólo sirven si son *2^algo o /2^algo ¿no? El símbolo: '&' es el operador booleano AND y '0xFF' es el valor 255 expresado en hexadecimal, básicamene cuando haces un valor and 255, todos los bits por encima del 8º se ponen a cero. toma la calculadora escribe (en decimal) 123456 (luego pulsa el botón de opción 'bin' para ver el valor en binario, luego devuélvelo a decimal pulsando el botón de opción 'dec') pulsa la tecla AND y luego escribe 255, el resultado será: 64, es decir 0100.0000 dicho de otro modo, hace que el valor esté en el rango 0-255. En definitiva tratándose del valor del canal de un píxel se asegura que el resultado no esté fuera de rango. Esto me cuesta entenderlo ¿tiene sentido que le llaman AND? Bue, le llaman % al resto, no debería sorprender. El diccionario de Flash dice: & (operador AND como bit) Sintaxis
expresión1 & expresión2 Argumentos
expresión1, expresión2 Cualquier número.
Descripción
Operador (como bit); convierte expresión1 y expresión2 en números enteros de 32 bits sin signo y realiza una operación Booleana AND en cada bit de los argumentos del número entero. El resultado es un nuevo número entero de 32 bits sin signo.
Reproductor
Flash 5 o posterior. Si se ha utilizado el operador & en Flash 4 para concatenar cadenas. En Flash 5 el operador & es un AND como bit y los operadores add y + concatenan cadenas. Los archivos de Flash 4 que utilizan el operador & se actualizan automáticamente para utilizar add cuando se traen al entorno de autoría de Flash 5. Hice la prueba que me dijiste pero igual no lo entendí. A = 0 & 1; da 0. A = 2 & 34; da 2. A = 5 & 678; da 4. A = 9 & 1234; da 0. GPT: En Macromedia Flash 5, la línea de código "A = 0 & 1;" realiza una operación de "AND" a nivel de bits entre los números 0 y 1, y el resultado se asigna a la variable A.
En lenguajes de programación como ActionScript, el operador "&" se utiliza para realizar operaciones de bits a nivel de los valores binarios de los números. En este caso, el número 0 se representa como "00000000" y el número 1 como "00000001". Al realizar el operador "&", se compara cada bit en la misma posición en ambos números y se devuelve 1 solo si ambos bits son 1. De lo contrario, se devuelve 0.
En este caso específico, el resultado de la operación es 0, porque no hay ninguna posición en la que ambos números tengan un bit 1. Por lo tanto, la variable A se asignará con el valor 0.Otro: La expresión "123 & 456" también realiza una operación de "AND" a nivel de bits, pero esta vez entre los números decimales 123 y 456.
Para entender el resultado, primero debemos convertir esos números a su representación binaria:
123 en binario: 1111011 456 en binario: 111001000
Luego, aplicamos el operador "&" a nivel de bits comparando cada posición:
1111011 & 111001000 111001000O sea: 1111011 & 111001000 = 111001000 Significa escribir un nuevo número de modo que, en el lugar donde cada uno tenga un 1 va un 1 y sino un 0, hasta que sea tan largo como el nro más largo. Lo que no entiendo es lo de "convierte expresión1 y expresión2 en números enteros de 32 bits", imagino que si son números pequeños les pone 0s delante ¿y sin son largos sólo toma lo que está delante? Cuando se dice que el operador "&" convierte las expresiones a números enteros de 32 bits, significa que toma las expresiones y las representa internamente como números enteros de 32 bits antes de realizar la operación "AND" a nivel de bits.
Un número entero de 32 bits es una representación binaria de un número que utiliza 32 posiciones o bits. Cada bit puede tener un valor de 0 o 1. La conversión a 32 bits asegura que las expresiones se traten como números enteros de longitud fija antes de realizar cualquier operación a nivel de bits.
Si las expresiones originales son números más pequeños que 32 bits, se completa el número con ceros a la izquierda para alcanzar los 32 bits. Por ejemplo, si una expresión es el número decimal 5, se representa en binario como "00000000000000000000000000000101" para ocupar 32 bits.
Una vez que ambas expresiones se han convertido a números enteros de 32 bits, el operador "&" realiza la operación "AND" a nivel de bits entre cada par de bits correspondientes en las expresiones. El resultado es un nuevo número entero de 32 bits sin signo.
En resumen, la conversión a 32 bits asegura que las expresiones se traten como números enteros de longitud fija antes de realizar la operación "AND" a nivel de bits. Esto proporciona consistencia en la representación y permite realizar la operación de manera adecuada. Ah, ya veo, son muchos 0s, 32, me confundía con algo como esto: Si hay 1 número son 2 posibles valores. 2 -> 4 3 -> 8 4 -> 16 5 -> 32 O no sé, tengo mucho lío, cuando busco cheats en juegos la opción 8 bits son 2 dígitos (o sea de 00 a FF), y de 32 son más pero no tantos, ah, puede ser porque eso es hexadecimal... Entonces por ejemplo 123456 & xFF: 11110001001000000 & 00000000011111111 = 00000000001000000 = 64 ¡Ok! Y esto sirve para... "tratándose del valor del canal de un píxel se asegura que el resultado no esté fuera de rango.", entiendo, pero no para qué aumentó los valores o cómo es eso. Pero en el caso anterior no es así. 1111011 & 111001000 quedaría: 001111011 & 111001000 = 001001000 No entiendo entonces. Es una función que convierte un número decimal en una string formateado en hexadecimal y lo devuelve en mayúsculas . Estás más verde de lo que pensaba en el lenguaje del que estás 'enamorado'... Convierte en hexadecimal el valor que contiene el parámetro de tipo numérico llamado 'decimal'. Ya, pero es que hace mucho que no convierto algo único a String, lo más parecido que he estado haciendo es concatenar números así Dato1+" "+Dato2, y como pensaba acabo de ver que esto: J = 3; J = J+""; Hace que J sea "3", string, por lo que no hay necesidad de usar String(J) parece. Pero eso de J.toString(), no sé si alguna vez lo había visto, sobre cuestiones binarias y similares aún he visto muy poco. sería equivalente a:
Código: color = (rojo * 65536) + (verde * 256) + azul colorPromedio = decimalToHex(color) Ya ¿pero por qué funciona? A ver si lo puedo entender más simple: - Supongamos que en vez de 0 a 255 fuese de 0 a 2 y que tenemos los colores 200 y 210. - El resultado debería ser 100 o 110 dependiendo de cómo se redondeé. ¿Cómo se llega a ese resultado? ¿algo así? R1 = Floor(200/100) = 2 Restante = 200-100*R1 = 0 G1 = Floor(Restante/10) = 0 B1 = Restante-10*G1 = 0 R2 = Floor(210/100) = 2 Restante = 210-100*R1 = 10 G1 = Floor(Restante/10) = 1 B1 = Restante-10*G2 = 0 NuevoR = Round((R1+R2)/2) NuevoG = Round((G1+G2)/2) NuevoB = Round((B1+B2)/2) NuevoColor = NuevoR+""+NuevoG+NuevoB Se supone que eso concatena bien, sino lo cambio. Es mejor que obtener los caracteres como había planeado. Pero explicame el método de GPT o el tuyo con un ejemplo para que yo lo pueda entender, ojalá. Una de las diferencias es que los valores originales son hexadecimales y deben ser convertidos a decimales, supongo, para poder hacer el promedio. Ah, veo que lo hiciste: azul1 = (color1 and 255) verde1 = ((color1 \ 256) and 255) rojo1 = (color1 \ 65536) Lo que no entiendo es el and 255, y creo que te faltó ponerlo en rojo1 ¿no? Ese and 255 ¿se puede convertir en una operación normal como hiciste con los >> y << o es más bien algo lógico? son cosas elementales de programación, te suena a chino, no solo por ser autodidacta (que no es en sí el problema), es debido quizás a ser demasiado cabezón en no haber querido aprender las cosas elementales que además son comunes e indistintas a cualquier lenguaje. El escaso tiempo que ahorraste en no aprender (3-6 mses) lo pierdes ahora (con creces) en detalles insignificantes No sé, con ese criterio tendría que haber estudiado electrónica y física atómica que es más elemental, yo aprendí lo que me fue necesario (y que me enteré qie era posible), hasta ahora nunca había precisado esto... De hecho quiero entender si se puede hacer "normal" porque yo programo en un lenguaje "normal", ya sabes, la típica discusión de si conviene aprender lenguaje máquina o no, en mi caso no creo porque me cuesta y tengo poca memoria para ciertas cosas... ¿Te parece que pierdo más tiempo por estar unas horas intentando aprender eso, en vez de pasarme horas haciendo ejercicios? Yo quise estudiar Programación hace años pero había cupos limitados y no obtuve suficiente buena calificación (hubo gente que con 1 punto más que yo entró, pero bue), pero luego vi que a un amigo le pedían hacer cálculos de convertir a binario o cosas que me parecían raras o poco útiles... así que perdí interés. Es como en Química y Física, yo quiero hacer cosas, no cálculos. Tampoco quiero hacer las cosas haciendo malabares si se pueden hacer más simple, me refiero a no usar moles y en este caso... bue, me interesó porque dices que funciona más rápido, pero sino lo del desplazamiento no lo usaría.
|
|
« Última modificación: 12 Mayo 2024, 07:12 am por Tachikomaia »
|
En línea
|
|
|
|
EdePC
|
Si digo CC0000, es decir 204, 0, 0 y CCCCCC, es decir 204, 204, 204 el resultado debe ser 204, 102, 102
Entiendo que debo convertir el hexadecimal a decimal y luego hacer promedios. ¿Por qué "0x"+ convierte a hexadecimal tan fácil? ¿es como una función (Number, toString, etc)? Depende de como tomes el dato, por ejemplo CC0000 dará error porque para flash eso no es un número por lo que entenderá que es un nombre de variable que seguramente tampoco lo sea, para que Flash entienda que es un número debería ser: 0xCC0000, entonces Flash entenderá que le diste un número hexadecimal, si le das "CC0000" entenderá que es un String o Texto, en ambos no es que estás convirtiendo, solo le estás entregando los valores correctamente para que Flash lo entienda. Siempre me costó entender esas pistas, y este código claro que tampoco lo entiendo. Ese es código Action Script 2 o 3 por lo que se está usando declaración de variables tipadas especificando el tipo de variable (variable:String, variable:Number), se escribe la variable o función seguido de dos puntos y el tipo de dato que debe contener o devolver, quítalos para no tener problemas en Action Script 1 que es el que usas, no sé si ya hayas visto que hay programadores que usan prefijos en sus variables para indicar que tipo de variables son para ser más legibles, por ejemplo: sNombre = "pepe"; iEdad = 17; fEstatura = 1.67; (s de String, i de Integer, f de Float) --- Todo lo demás son operaciones a nivel bit, básicamente se usan los desplazamientos binarios y la operación AND binaria para descomponer tu número hexadecimal 0xCC0000 en 0xCC, 0x00 y 0x00, puedes tomar ese camino o puedes trabajar con String que es más legible siempre y cuando ya hayas trabajado o conozcas el método SubStr y/o SubString para extraer partes de una String, supongo que parseInt y toString ya lo conoces bien, sino revisa la documentación o pregunta: sColor1 = "CC0000"; sColor2 = "CCCCCC"; iR1 = parseInt(sColor1.SubStr(0, 2), 16); iG1 = parseInt(sColor1.SubStr(2, 2), 16); iB1 = parseInt(sColor1.SubStr(4, 2), 16); iR2 = parseInt(sColor2.SubStr(0, 2), 16); iG2 = parseInt(sColor2.SubStr(2, 2), 16); iB2 = parseInt(sColor2.SubStr(4, 2), 16); iPromR = (iR1 + iR2) / 2; iPromG = (iG1 + iG2) / 2; iPromB = (iB1 + iB2) / 2; trace(iPromR + ", " + iPromG + ", " + iPromB); sColorPromHex = iPromR.toString(16) + iPromG.toString(16) + iPromB.toString(16); trace(sColorPromHex);
Esto devuelve: 204, 102, 102 cc6666
|
|
|
En línea
|
|
|
|
Tachikomaia
Conectado
Mensajes: 1.245
Superhacker (es broma xD )
|
Depende de como tomes el dato, por ejemplo CC0000 dará error porque para flash eso no es un número por lo que entenderá que es un nombre de variable que seguramente tampoco lo sea, para que Flash entienda que es un número debería ser: 0xCC0000, entonces Flash entenderá que le diste un número hexadecimal, si le das "CC0000" entenderá que es un String o Texto, en ambos no es que estás convirtiendo, solo le estás entregando los valores correctamente para que Flash lo entienda. Ah, eso tiene mucha lógica. Ese es código Action Script 2 o 3 por lo que se está usando declaración de variables tipadas especificando el tipo de variable (variable:String, variable:Number), se escribe la variable o función seguido de dos puntos y el tipo de dato que debe contener o devolver, quítalos para no tener problemas en Action Script 1 que es el que usas Supuse que podía ser eso. no sé si ya hayas visto que hay programadores que usan prefijos en sus variables para indicar que tipo de variables son para ser más legibles, por ejemplo: sNombre = "pepe"; iEdad = 17; fEstatura = 1.67; (s de String, i de Integer, f de Float) Sí pero si lo veía sin que me lo dijeras no me daría cuenta, se me olvida, pero yo uso mCuadradito por ejemplo si me refiero al vínculo de Cuadradito (el nombre que se usa en el attach movie para indicar cual). puedes trabajar con String que es más legible siempre y cuando ya hayas trabajado o conozcas el método SubStr y/o SubString para extraer partes de una String, supongo que parseInt y toString ya lo conoces bien, sino revisa la documentación o pregunta Pruebo ahora, yo pensaba usar charat pero lo que dices es mejor.
|
|
|
En línea
|
|
|
|
EdePC
|
Si le quieres dar una aproximación más matemática puedes partir de este ejemplo en base 10 (lo normal): iColor1 = 123456; Si quisieras despejar 12 bastaría con dividirlo entre 10000, quedando 12.3456 y a esto le quitamos la parte decimal convirtiéndolo a entero = 12 Para despejar 34 hay que dividirlo entre 100, quedando 1234.56, luego lo convertimos a entero para obtener 1234, y por último obtenemos el módulo (residuo entero) entre 100 para conseguir 34 Para despejar 56 basta con obtener el módulo entre 100, quedando 56 Bien, pero esto que hemos hecho es con base 10, pero tú quieres trabajar con un valor hexadecimal, podrías convertirlos a decimal y trabajarlos así pero también lo puedes trabajar directo en hexadecimal sin complicaciones y sin perder legibilidad: iColor1 = 0xAABBCC; Si quisieras despejar 0xAA bastaría con dividirlo entre 0x10000 Para despejar 0xBB hay que dividirlo entre 0x100, quedando 0xAABB, luego obtenemos el módulo (residuo entero) entre 0x100 y obtenemos 0xBB Para despejar 0xCC basta con obtener el módulo entre 0x100 iColor1 = 0xAABBCC; iR1 = parseInt(iColor1 / 0x10000); iG1 = parseInt(iColor1 / 0x100) % 0x100; iB1 = iColor1 % 0x100; sColorHex = iR1.toString(16) + iG1.toString(16) + iB1.toString(16); trace(sColorHex);
Esto devuelve: aabbcc
El código completo para esta solución sería: iColor1 = 0xCC0000; iColor2 = 0xCCCCCC; iR1 = parseInt(iColor1 / 0x10000); iG1 = parseInt(iColor1 / 0x100) % 0x100; iB1 = iColor1 % 0x100; iR2 = parseInt(iColor2 / 0x10000); iG2 = parseInt(iColor2 / 0x100) % 0x100; iB2 = iColor2 % 0x100; iPromR = (iR1 + iR2) / 2; iPromG = (iG1 + iG2) / 2; iPromB = (iB1 + iB2) / 2; trace(iPromR + ", " + iPromG + ", " + iPromB); sColorPromHex = iPromR.toString(16) + iPromG.toString(16) + iPromB.toString(16); trace(sColorPromHex);
Obteniendo: 204, 102, 102 cc6666
--- La solución por el método binario te lo propuso ChatGPT pero para que te sea legible debes saber como funcionan internamente los operadores de desplazamiento binario y And binario, o al menos su equivalencia matemática, eso lo estaba explicando Serapis, te darás cuenta que es similar al método matemático que pasé antes, salvo que yo uso parseInt para deshacerme de los decimales y módulo para quitar números de la izquierda
|
|
|
En línea
|
|
|
|
Tachikomaia
Conectado
Mensajes: 1.245
Superhacker (es broma xD )
|
Debes elevar al cuadrado cada valor RGB, después hacer la media, y luego calcular la raíz cuadrada de cada uno para revertir la primera operación. NewColor = sqrt((R1^2+R2^2)/2), sqrt((G1^2+G2^2)/2), sqrt((B1^2+B2^2)/2) Usando este enfoque, al elevar al cuadrado los componentes RGB antes de promediar, estamos aplicando un tipo de "ponderación" que favorece los valores más altos y minimiza el efecto de los valores más bajos. Esto es útil porque los valores RGB cuadrados preservan mejor las diferencias perceptuales entre los colores originales. No confío mucho en esto, pero veamos. Si un color es 100, 100, 10 y el otro 10, 100, 100 el resultado normal sería 55, 100, 55 pero me dices que haga: Raíz((100*100+10*10)/2) para el 1er color en este caso. Raíz((10000+100)/2) Raíz((10100)/2) Raíz(5050) 71,06335201775947748485464743814 ¿Si son iguales cambia? A ver, el 2ndo color Raíz((100*100+100*100)/2) Raíz((10000+10000)/2) Raíz(10000) No, me da 100. Yo no veo que 71, 100, 71 sea el promedio y no le veo la ventaja. EdePC: Está bien, me puede servir. Luego intento averiguar cómo funciona lo del & y | por curiosidad y porque me puede servir, si el efecto que causa no es simplificable.
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
como capturar en colores con pinnacle?
Multimedia
|
Cuasar
|
0
|
1,194
|
27 Diciembre 2006, 03:55 am
por Cuasar
|
|
|
promediar
Programación C/C++
|
karmi
|
1
|
1,599
|
22 Noviembre 2010, 03:58 am
por Beakman
|
|
|
como cambiar colores con Substance?
Java
|
_teiki
|
5
|
6,025
|
28 Febrero 2011, 10:59 am
por NetJava
|
|
|
[COLORES] Como cambiar colores en c++
Programación C/C++
|
ianmorar03
|
1
|
3,225
|
20 Abril 2016, 06:50 am
por engel lex
|
|
|
.cmd .bat Como cambiar colores y como manejar el sistema desde la Consola
Scripting
|
UserDistortion
|
4
|
7,202
|
31 Marzo 2017, 15:09 pm
por Eleкtro
|
|