OJODIGITAL |
|
|
|
| Debates sobre la programación Para tratar temas sobre programación |
![]() |
|
|||
|
Sobre el funcionamiento del Zoom
Hay una cosa que no me gusta en cómo funciona el zoom actualmente.
Cuando le damos a la rueda del botón para aumentar el zoom, el punto que se conserva en la imagen presentada es el de la esquina superior izquiera de la ventana. Lo que despista un poco, pues da la sensación de que toda la imagen se desplaza hacia abajo y la derecha. Además cuando se reduce el zoom la cosa no funciona igual, pues cuando la imagen pasa a ocupar menos que la ventana de repente "salta" y se centra en la ventana. Creo que sería más intuitivo si la imagen mantuviera siempre el punto central de la ventana en el centro durante los zooms. Mejor aún sería que el punto que se mantuviera en su lugar dentro de la ventana fuera el correspondiente al punto sobre el que se encuentre el ratón en el momento de hacer el zoom (al darle a la rueda), pues será el punto sobre el que el usuario mantiene en ese momento la atención y se mantendría en su sitio sin saltar a ninguna otra posición. Creo que sería mucho más intuitivo. |
| Publicidad |
|
||||
|
Cita:
__________________
"En ocasiones veo halos." Canon EOS 350D | EOS 300 | 10-22 | 24-70 f2.8L | 70-200 f4L | 300 f4L IS http://www.guillermoluijk.com para suscribirte pulsa aquí |
|
|||
|
Cita:
De hecho he estado jugueteando con lo de dibujar una elipse/rectángulo encima de la imagen para seleccionar el patch de bits con el que hacer el cálculo de balance de blancos y ya me funciona... bueno menos por una cosa: el centrado que se produce cuando la imagen ocupa menos que la ventana, que me lo desconfigura todo. Pero el cálculo de las transformaciones algebráicas para colocar la imagen, creo que debe de hacerse fuera del fastdraw, en PerfectView, para que la transformación sea idéntica para el dibujo del bitmap y el dibujo de los patch. He mirado el código que hay al inicio de fastdraw que hace el cálculo del zoom y del centrado y la verdad es que es endemoniado, no conseguí aclararme muy bien. Otra cosa es el tema del zoom: por lo que veo no todos los zooms se hacen, algunos de ellos se convierten al mismo valor. Esto afectará a la tranformación a realizar fuera de fastdraw, pues ha de hacerla con el zoom final que se utiliza y o con el valor almacenado como float, pues sino las transformaciones serían distintas. Necesitaría algo más de aclaración sobre cómo implementaste esto. |
|
||||
|
Cita:
Cuando se pasa de un modo al otro, el rectángulo/elipse previamente definido se convierte de manera biunívoca en la otra forma geométrica: Las esquinas (x0,y0) y (x1,y1) del rectángulo se transforman en el centro de la elipse inscrita en dicho rectángulo: (x2,y2)=( (x0+x1)/2, (y0+y1)/2 ) y sus radios respectivos Rx=(x1-x0)/2 y Ry=(y1-y0)/2. El paso contrario es sencillo también: x0=x2-Rx, y0=y2-Ry, x1=x2+Rx, y1=y2+Ry Yo las coordenadas las hice todas relativas a una imagen de tamaño 1x1 (es decir, representaban coordenadas en tanto por 1), y luego convertía mediante width y height a los píxels reales. Como os sea más fácil. Lo complicado es adecuar la representación y la entrada de datos al grado de zoom del display y posición de la imagen en un momento dado. Yo no tuve ese problema porque ZN no tiene zoom ![]() ![]()
__________________
"En ocasiones veo halos." Canon EOS 350D | EOS 300 | 10-22 | 24-70 f2.8L | 70-200 f4L | 300 f4L IS http://www.guillermoluijk.com para suscribirte pulsa aquí |
|
||||
|
En principio tienes que implementarlo en la función MakeZoom, a la que habrá que pasarle el punto X,Y en el que se ha hecho click respecto a las coordenadas del pictureBox y corregidas con el Zoom. Como tú ya habías hecho tu propia implementación de MakeZoom es mejor que no haga yo otra porque tendrás que cambiar tú otras cosas.
La idea es cambiar el cálculo que hacía yo antes en MakeZoom: Código:
bX = (int)(pX[view]+ w[view] / (2*Zoom[view]));
bY = (int)(pY[view]+ h[view] / (2*Zoom[view]));
Zoom[view] *= ZoomQ;
pX[view] = (int)(bX - w[view] / (2 * Zoom[view]) + 1);
pY[view] = (int)(bY - h[view] / (2 * Zoom[view]) + 1);
Por otro en el que se tengan en cuenta las coordenada en las que estaba el ratón al mover la rueda y mantenga ese punto, no sus coordenadas absolutas claro, sino las relativas a la imagen final. En bX y bY (de before zoom X y before zoom Y) se calcula la esquina superior izquierda actual de la imagen, luego en pX, pY se calcula la nueva coordenada X,Y de la imagen para que sea igual a la anterior, lo que viene a partir de ahí lo dejas como está, que es para que se pare en los bordes, en los que no se podrá mantener el punto en el centro, claro. Cita:
Código:
cx=(int)((float)width/2-(int)((float)width2*z/2.0)); cy=(int)((float)height/2-(int)((float)height2*z/2.0)); if(cx<0) cx=0; if(cy<0) cy=0; if((int)(cx+width2*z)>=width) cx=0; if((int)(cy+height2*z)>=height) cy=0; Es muy parecido al cálculo de antes, calcula desde el centro del buffer de salida, en qué coordenada hay que empezar a pintar (de ese buffer de salida) para que con el Zoom actual, quepa la mitad de la imagen en la mitad izquierda del buffer de salida. Luego se asegura de que la coordenada no quede fuera del buffer de salida. Cita:
Cita:
, ![]() ![]() ![]() ... tienes que replicar _exactamente_ lo mismo que hace la DLL en C#, no puede ser complicado, la sintaxis de C y C# es similar.Cita:
Por cierto, como vamos a usar sRGB a capón voy a crear una LUT para exactamente 65536 valores con esa gamma y se hace en tiempo de visualización con solo una búsqueda de tabla, que en los procesadores actuales es rapidísimo... ya puestos... Sobre esto que te cuento, pregunta lo que necesites. En realidad programo casi siempre por intuición, así que tampoco puedo darte muchas más explicaciones. Tendría que ponerme a analizar más a fondo lo que yo mismo he hecho ![]() ![]() ![]() ![]() .Un saludo: Última edición por ManuelLlorens; 19-may-2008 a las 22:21. |
|
|||
|
Cita:
Además se puede dibujar fuera de la ventana. De hecho yo hago una transformación para que las coordenadas coincidan con las de la imagen total al dibujar con esa transformación, si el círculo queda fuera de la ventana, no se dibuja nada, pero cuando se haga el pan de la ventana a la zona donde cae el círculo, este aparece y el GDI hace el clipping. Cita:
Ya me extrañaba porque lo de dibujar parecía funcionar bien. Lo del parpadeo sí, pero lo de la gamma, ya comenté antes que creo que sería mejor hacerlo una sola vez sobre la imagen de 16 bits revelada (aunque la "estropee"). Cuando se vaya a guardar en disco o clipboard habría que hacer un revelado completo nuevamente. Así evitaremos un cálculo de gamma cada vez que se cambie el zoom o se haga desplazamiento de la ventana. Según GUI la gamma no afecta a los pixels quemados (no cambia el valor del 0 y el 65535) por tanto se puede hacer antes que esto. Hacerlo después de los pixels quemados afectaría al color mostrado para los pixels quemados que no sería un valor medio (aunque no creo que eso sea importante). En cualquier caso si se quiere hacer después por el motivo que sea, lo suyo sería hacerlo después del FastDraw sobre los 356 bits (aunque no sea tan exacto) ¿no? Última edición por ManuelLlorens; 19-may-2008 a las 21:59. |
|
||||
|
Cita:
De todos modos creo que con una LUT como la que comento no habrá ningún problema de velocidad (y se sería exactamente igual de rápida en 16 que en 8 bits), visto lo visto con el desplazamiento. Además, sería muy fácil cambiar la tabla cuando se meta la gestión de color en la aplicación. Las búsquedas en tablas están también muy optimizadas en el procesador. Lo que pretendo es mapear en una tabla los 0-65535 valores, antes de corregir como índices a la tabla, y una vez corregidos con la gamma como valores de la tabla. De ese modo no hay que hacer ningún cálculo, sólo cambiar un valor por el valor que la tabla da para ese valor como índice: Código:
valor16=LUT(valor16); // Antes de pasar a 8 bits. ![]() ![]() .Un saludo: Última edición por ManuelLlorens; 19-may-2008 a las 22:20. |
|
|||
|
Cita:
Yo lo de la gamma (la corrección para el monitor) lo haría antes de llamar a FastDraw para ahorrar tiempo de cálculo y dejar un código más limpio. Añadirá algún pixel quemado más, pero eso se puede modificar cambiando el umbral. Incluso se puede pensar en meter el umbral correspondiente a una gamma lineal y modificar el valor del umbral en función de la gamma (convirtiendo el valor correspondiente a 65535-umbral con la curva de gamma. El valor que salga será el nuevo umbral). Si aún así creéis imprescindible hacerlo después de los pixels quemados, será mejor hacerlo a posteriori del reescalado. El código será más entendible y además facilitará cambios posteriores en el flujo del procesamiento de la imagen revelada. Lo de la LUT me parece una gran idea. ¿La generas al cargar la dll? El sitio adecuado para ponerla sería en el DLLMain de la dll, al cargarla, podrías calcular todos los valores de la curva gamma entre 0 y 65535. Así te evitas ponerla a pedal en el código. Hombre puesto en el código como una tabla const será un pelín más rápida probablemente, por las optimizaciones que pueda hacer el procesador al ver que multiplica por valores constantes en vez de por el valor de una variable. Pero no sé si merece la pena. |
|
||||
|
Cita:
Imagen de dcraw (16 bits) -> Obtención del histograma completo (image.dl) -> Aplicación de gamma sRGB rápida (pero precisa) (image.dll) -> Visualización de esa copia en una vista a 8 bits (image.dll) -> Histograma parcial de la vista (image.dll). Como ahora tú mantienes image.dll te pasaré código en C para las tres cosas nuevas que pongo arriba y tú lo integras. _GUI_, lee y comenta estos dos párrafos que siguen: Luego, la visualización o no del histograma parcial puede ir en GDI+. Me queda la duda de si la aplicación de la gamma afecta al balance de blancos, que entiendo que no, y por tanto, no hace falta guardar una copia del buffer que devuelve dcraw sin aplicar la gamma, ya que hemos definido que los píxeles quemados se calculan después de aplicar la gamma. Otra cosa que quiero definir: dice _GUI_ que pongamos un slider para el control del punto de saturación (creo que mejor será un control numericUpDown que es más preciso que un slider, pero ese es otro tema). Digo yo que lo lógico sería poder poner el umbral del marcado de píxeles quemados igual al punto de saturación de la cámara, ¿no? Para eso, ambos controles deben estar juntos en el GUI y con una opción de enlazarlos de modo que al mover uno lo haga el otro, ¿qué os parece? Un saludo: Última edición por ManuelLlorens; 20-may-2008 a las 12:26. |
|
||||
|
Cita:
La corrección de gamma de dcraw no la vamos a usar nada más que para la salida a TIFF, la reharemos en la DLL. Lo demás sí es así. Cita:
Cita:
Cita:
Un saludo: Última edición por ManuelLlorens; 20-may-2008 a las 12:25. |
|
||||
|
Uy no había visto este hilo sorry:
Cita:
Cita:
A ver son cosas distintas:
Estos aspectos son muy importantes para qeu este revelador sea realmente "algo diferente" a todo lo existente. Os queda claro el pipeline del revelado?
__________________
"En ocasiones veo halos." Canon EOS 350D | EOS 300 | 10-22 | 24-70 f2.8L | 70-200 f4L | 300 f4L IS http://www.guillermoluijk.com para suscribirte pulsa aquí Última edición por _GUI_; 21-may-2008 a las 02:29. |
|
||||
|
Cita:
Cita:
Cita:
Un saludo: |
|
||||
|
Cita:
Te contesto aquí: Sobre el Balance de Blancos con parches.
__________________
"En ocasiones veo halos." Canon EOS 350D | EOS 300 | 10-22 | 24-70 f2.8L | 70-200 f4L | 300 f4L IS http://www.guillermoluijk.com para suscribirte pulsa aquí Última edición por _GUI_; 21-may-2008 a las 12:20. |
|
|||
|
Contestación movida al hilo anterior empezado por GUI
Última edición por ariznaf; 21-may-2008 a las 12:31. |
|
||||
|
Cita:
Cita:
Cita:
Un saludo: |