Ahora voy daré mi opinión:
La primera alternativa es posible que sea más rápida y ha estado funcionando bien hasta ahora. El problema surge al querer hacer un marcado de los pixels quemados.
Si se hace sobre la imagen en 8 bits dentro de FastDraw o sobre la salida de fastDraw, ya se ha perdido información, pues se ha rendondeado y se marcarán muchos más pixels quemados de los que realmente están (no sólo los que tengan valor 65535 sino entre 65281 y 65535 (si usamos el algoritmo rápido x16>>8 propuesto por Manuel).
Para evitar eso, la alternativa propuesta por Manuel sugiere crear un nuevo buffer de ocho bits en el que se asignen los colores quemados calculados sobre el buffer ya revelado de 16 bits y convertir a continuación el buffer de 16 bits a 8 bits.
Luego se llama al FastDraw para el reescalado y se superpone la imagen de los pixels quemados.
A destacar que hay que hacer el reescalado dos veces: uno sobre la imagen y otro sobre el buffer de pixels quemados, para luego poder superponerlos.
Creo que la adtación a la gamma del monitor se puede hacer sobre la imagen de 8 bits sin problemas. Según dice GUI el lugar no afecta a los pixels quemados.
Aunque si esto es así igual se podía hacer justo después de la conversión a 8 bits, previo al reescalado y así no hay que hacerlo cada vez que se hace zoom de la imagen o pan.
_________________________________
No te molestes ariznaf, voy a implementar directamente la tuya y si la velocidad es suficiente pasamos de la otra.
Bien, Manuel a ver si funciona suficientemente bien.
De todas maneras creo que quedan cosas por pulir en este esquema que había propuesto.
Sobre el esquema de 16 bits:
En este caso la corrección de gamma para ajustar a la salida del monitor no se puede hacer previa como en el caso anterior, pues si el buffer es el de 16 bits de la salida del revelado (con una gamma lineal u otra que no coincida con la del monitor) si cambiamos el gamma estropeamos el buffer.
A no ser claro está que hiciéramos otra copia del buffer sobre el que trabajar o que cuando se vaya a guardar o a poner en el portapapeles se haga otro revelado partiendo de cero (quizás esto es lo mejor y creo que algo habíais comentado de utilizar algoritmos de más precisión para el revelado final) con lo que no importaría "estropear" el buffer del revelado.
En este caso el flujo sería así:
BUFFER SALIDA 16 bits -->Aplicación de Gamma rápida de monitor en 16 bits(si es distinta de la del revelado) --> Reescalado usando FastDraw Con detección altas luces y conversión a 8 bits rápida (detección previa a la conversión) Salida en 8 bits --> Dibujado encima de la parte de imagen seleccionada --> dibujado encima del histograma. --> mostrar en pantalla.
_________________________________
El meollo de la cuestión será en la forma de implementar el reescalado con FastDraw y las otras tareas que se le encomiendan:
Comentaste que era necesario llevar otro buffer interno. En principio creo que no es necesario (aunque no conozco en detalle cómo haces el escalado porque me pierdo un poco con tanta variable críptica
).
El algoritmo debería de ser algo así:
Código:
Para cada pixel que vaya a ir en la salida diezmada por el escalado {
Comprobar si el pixel está quemado: {
quemado: asignar en el buffer de salida un valor de 128 en el canal quemado.
no quemado: {
convertir el color a 8 bits // (usando el algoritmo >>8 será suficiente.El preciso para el guardado a disco o a portapapeles).
asignar al pixel de salida en 8 bits.
}
}
}
Como ves en ese esquema sólo se ejecutan los pasos sobre los pixels diezmados (seleccionados para la salida). Y no haría falta llevar otro buffer intermedio de 16 bits.
Cuando decías que el buffer era necesario me imagino que es porque usas algún algoritmo de copiado rápido de filas o algo así.
En ese caso, el procedimiento anterior podría hacerse por filas, pidiendo memoria únicamente para una fila de pixels de salida de 16 bits y luego haciendo los pasos de conversión a 8 bits y detección de altas luces.
Código:
Pedir memoria para una fila de pixels de salida con valores de 16 bits.
Para cada fila seleccionada {
Copiar pixels seleccionados a fila de 16 bits usando método de copiado rápido {
Para cada pixel de la fila {
Comprobar si el pixel está quemado: {
quemado: asignar en el buffer de salida un valor de 128 en el canal quemado.
no quemado: {
convertir el color a 8 bits (usando el algoritmo >>8 será suficiente. El preciso para el guardado a disco o a portapapeles).
asignar al pixel de salida en 8 bits.
}
}
}
}
liberar memoria pedida para fila de 16 bits.
Bueno algo así.
¿Ves algún fallo en ese esquema?
Marcadores