Manejo de imágenes Bitmap estilo Winamp
#1
Posted 29 March 2011 - 09:07 AM
Abro este hilo como modo de aprendizaje, ya que es una curiosidad que me persiste hace tiempo y no hay información congruente en la red, así que espero sus comentarios.
Saludos.
#2
Posted 29 March 2011 - 11:19 AM
Yo no soy ningún experto en el tema pero si te puedo decir alguna cosa. No se como lo hace Winamp pero analizando programas con pieles te puedo decir que su frontal no tiene o tiene muy pocos controles. Es decir, cada control clásico en windows es una ventana, en estas aplicaciones no aparecen mas que la ventana del frame. Te iba a decir que jugaras con la pequeña utilidad que hice WinInfo y que colgué en la zona de descargas, pero ahora no aparece dicha zona. Si te interesa la subo.
Bueno, no es fácil el tema y se puede hacer de muchas formas. Básicamente se trata de usar un bitmap para representar la carátula y controles. Sobre ese bitmap se realiza una máscara bicolor o bien puede ser dada en otro bitmap. Esta máscara se usa para crear regiones. Una región en windows es una zona de una ventana que es sensible a entradas y pintado de la misma. Generalmente corresponde a todo el área de la ventana, pero podemos restringirlo. Es decir, todo lo que no se incluya en la región, es como si no perteneciese de la ventana. Así podemos usar imágenes de contornos caprichosos.
Ahora el truco está en dibujar bitmaps y regiones. La aplicación no puede ser diseñada con los controles clásicos, por lo que debemos establecer un sistema de localización de zonas sensibles del ratón, capturando sus mensajes y analizando en que región o zona de la misma está.
Una forma mas sencilla, pero menos elástica, sería diseñar nuestros controles derivados de los propios de windows, como el ejemplo que publiqué en el foro platino, SkinButton. Aquí uso bitmaps y regiones para crear el efecto. Con esta técnica es mas fácil trabajar después, ya que lo haremos como siempre, la desventaja está en que el usuario final tendrá menos plasticidad en los Skins.
Por último, te dejo un enlace donde explican un poco el tema de regiones y bitmap. Se pueden encontrar otros muchos en la Red.
Otra posibilidad es usar sistemas o controles Skin comerciales.
Saludos.
#3
Posted 30 March 2011 - 08:41 AM
Con la finalidad de ilustrar un poco el tema y realizar el ejercicio práctico, he preparado un pequeño ejemplo.
La filosofía empleada es la que expliqué arriba, usando Bitmap, máscara y regiones. En este ejemplo utilizo un Bitmap simple que sirve de Skin y de máscara al mismo tiempo.
El corazón es la función CreateBitmapRgn. Esta función que he implementado consigue una región a partir de un bitmap. la definición es la siguiente:
function CreateBitmapRgn(hbmp: HBITMAP; Color: COLORREF; Tr: boolean): HRGN;
hbmp: Es el bitmap a partir del que vamos a obtener una región.
Color: Es el color que va a definir la región dependiendo del valor de Tr.
Tr: Modifica el funcionamiento. Si Tr es true, Color se considerará que será transparente, en caso contrario, Color será opaco y todo lo demás transparente.
En el ejemplo aparece un Form presonalizado con un Skin y un botón para cerrar, nada mas.
La API PtInRegion nos localiza si pulsamos el botón.
Espero que te sirva de ayuda.
Saludos.
Attached Files
#4
Posted 01 April 2011 - 12:59 PM
He ahondado un poco mas en este tema y he preparado un ejemplo mas complejo.
La mecánica es preparar un formulario con los botones y su funcionalidad como haríamos normalmente. Se añade TImage que hará el Skin.
Partimos de tres bitmaps. Uno con el skin dibujado con los botones en reposo, otro con los botones pulsados y un tercero con máscaras de colores, un color por cada botón. Este último va a representar la zona sensible del ratón.
Creamos una región para todo el Skin que será la representación del formulario. Cada botón tendrá su región extraída de su máscara, aquí se asocia cada TButton con su "botón skin", la región la guardamos en la propiedad tag del TButton.
Solo queda pintar el bitmap pulsado en la región correspondiente cada vez que se pulsa un "Botón skin" o dibujar el estado de reposo al soltarlo.
Las acciones de cada botón se simulan llamando al evento OnClick correspondiente.
El diseño del formulario.
El skin en reposo y tras pulsar la tecla "PLAY"
Saludos.
Attached Files
Edited by escafandra, 10 May 2015 - 10:10 AM.
Subo enlace roto, la última versión backup que encontré
#5
Posted 01 April 2011 - 01:16 PM
Muy bueno, alucinante.
Me he quedado
Impresionante Maestro.
Saludos
#6
Posted 01 April 2011 - 01:41 PM
#7
Posted 01 April 2011 - 03:20 PM
solo aparece esta rana congelada:
Saludos!
#8
Posted 01 April 2011 - 03:38 PM
En realidad el diseño gráfico lo tomé prestado, sólo le hice algunos cambios para adaptarlo a lo que quería. La filosofía y el código funcionan perfectamente.
El ejemplo sólo usa botones, pero se puede extender a otros controles como Edits y barras de progreso usando semitransparecias o algún truco por el estilo. Para los TrackBar habrá que usar algún invento diferente... La imaginación es libre.
Todo está en el código que subí, pero para los que sólo vean la ranita, subo las imágenes al foro.
Saludos.
Attached Files
#9
Posted 04 April 2011 - 06:09 AM
#10
Posted 04 April 2011 - 06:30 AM
Ah caray desde mi oficina no he podido descargar los fuentes, los enlaces de descargas están bloqueadas
¿Quieres que te los envíe por correo? o ¿puedes desde casa?
Saludos.
#11
Posted 04 April 2011 - 06:34 AM
Saludos.
#12
Posted 04 April 2011 - 07:01 AM
Saludos.
#13
Posted 05 April 2011 - 11:59 AM
#14
Posted 05 April 2011 - 05:31 PM
#15
Posted 07 April 2011 - 04:54 AM
Gracias a vosotros.
He realizado algunas mejoras jugando con esta prueba de concepto:
1. Tipo de gráficos usado que ahora es png, mas ligero que el bmp (con el mismo código podría usarse otros formatos) .
2. Universalización en la creación de regiones desde un HBITMAP.
3. Automatización en la asignación de los eventos OnClick de los Botones.
Subo los nuevos archivos.
Saludos.
Attached Files
#16
Posted 23 November 2018 - 05:31 PM
Tras una petición de adaptar el código a Berlin / Tokio publico la adaptación que solo varía en la función CreateHBITMAPFromFile debido al uso de UNICODE del que delphi7 carecía, estando escrito el código original para esa versión de delphi.
La función queda como sigue:
function CreateHBITMAPFromFile(FileName: PCHAR): HBITMAP; var gdiplusToken: DWORD; GdiPlusStartupInput: array[0..2] of int64; GBitmap: THANDLE; begin Result:= 0; // Initialize GDI+. GdiPlusStartupInput[0]:= 1; GdiPlusStartupInput[1]:= 0; if GdiplusStartup(gdiplusToken, @GdiPlusStartupInput, nil) = 0 then begin GdipCreateBitmapFromFile(FileName, GBitmap); GdipCreateHBITMAPFromBitmap(GBitmap, Result, 0); //shutdown GDI+ GdiplusShutdown(gdiplusToken); end; end;
Subo el proyecto completo.
Saludos.
Attached Files
#17
Posted 23 November 2018 - 06:21 PM
Se ve genial, gracias por compartir amigo.
Saludos