Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Gráficos
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 03-06-2006
Deiv Deiv is offline
Miembro
 
Registrado: jul 2005
Ubicación: La Paz - Bolivia
Posts: 364
Poder: 20
Deiv Va por buen camino
Exclamation Manejar Trozos de BMP

Hola!
Como novato acabo de darme cuenta que en Delphi se puede manejar trozos de un BMP (Números graficados por así decirlo=0123456789 dibujados en un solo BMP [con una determinada altura y ancho]) y que estos se puedan mostrar en un TPanel o TPaintBox, solo cierta parte. Vi este ejemplo en una Aplicación como ejemplo pero ejecutable ¿Como se realiza este proceso?

1.- Me explico: por así decirlo necesito mostrar solo el "4" y el "9" adyacentemente de la "Cadena BMP" = '0123456789' (gráficado) ¿como lo hago?
2.- De mostrarlo, ¿como simular un parpadeo (blinkado) con un trozo de BMP, el "4" (parpadeando) por así decirlo y el "9" nada que ver?
3.- ¿Donde es más adecuado (óptimo) mostrar este trozo de BMP? ¿En un TPanel? ¿En un TPaintBox? ¿En un TIMage? ¿En un TForm directamente? ¿Es indiferente según necesidades?

Saludos
Responder Con Cita
  #2  
Antiguo 08-06-2006
Deiv Deiv is offline
Miembro
 
Registrado: jul 2005
Ubicación: La Paz - Bolivia
Posts: 364
Poder: 20
Deiv Va por buen camino
Question

He encontrado en la página http://www.latiumsoftware.com/es/pascal/0012.php se asemeja a lo que requiero, pero este recorta seleccionando la imagen con el mouse, Lo que intento es realizar un cierto cálculo y como resultado obtenga un número (en integer o en string) pero que de alguna manera lo relacione con el BMP graficado del 0 al 9 y pueda mostrar solo aquel que me interese del BMP
¿Como relaciono ese cálculo para que pueda recortar solo una parte del BMP y mostrar lo que requiero?

Sobre el blinkado, me parece que debo crear un Gif, la pregunta es si tuviera que hacer todos los números (0-9) y todo el abecedario (A-Z) sería un trabajo tedioso. ¿No habrá forma de (relacionado a mi primera pregunta) de capturar sola una parte del BMP y hacerla blinkar realizando otra BMP de números de color diferente?
Responder Con Cita
  #3  
Antiguo 10-06-2006
madriles madriles is offline
Miembro
 
Registrado: may 2003
Ubicación: madrid
Posts: 93
Poder: 22
madriles Va por buen camino
hola
para lo que tu quieres, yo usaria un TPanel y dentro un TImage, cargado con el bmp con los numeros.
en el ejemplo de codigo he usado unos TSpeedButton con los numeros del 0 al 9. El TPanel tiene que tener el ancho de un numero cualquiera, que sera, logicamente, la decima parte del bmp

Código Delphi [-]
   //comun a todos los botones de numeros 
procedure TForm1.SpeedButton10Click(Sender: TObject);
begin
   Image1.Left := -(StrToInt((Sender as TSpeedButton).Caption) * Panel1.Width);
end;

para el tema del parpadeo, puedes hacer mas o menos lo mismo pero con la propiedad Top del TImage, y el bmp hacerlo el doble de alto, la parte de arriba con el numero en verde y la de abajo en rojo, por ejemplo de forma que, usando un TTimer te vaya pasando de rojo a verde segun el intervalo que le pongas.
espero haberte aclarado algo, un saludo
Responder Con Cita
  #4  
Antiguo 11-06-2006
Deiv Deiv is offline
Miembro
 
Registrado: jul 2005
Ubicación: La Paz - Bolivia
Posts: 364
Poder: 20
Deiv Va por buen camino
He encontrado ejemplos como este:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var
  b:TBitmap;
  RDest, RSource: TRect;
begin
  b := TBitmap.Create();
  b.Width := 100;
  b.Height := 100;
  // Creamos las zonas de copia origen y destino
  RDest := Rect(0,0,100,100);
  RSource := Rect(0,0,100, 100);
  // Copiar parte del form al bitmap
  b.Canvas.CopyRect(RDest, Self.Canvas, RSource);
end;

El ejemplo que encontré entre algunos, siempre se basan midiendo de un TPaintBox, TImage o de un TPanel PEGADOS al Form (es decir en el formulario están como OBLIGADOS uno de estos objetos para calcularlos con el CopyRect). Pero no encuentro un ejemplo que teniendo el BitMap en mi Directorio calcular (un x-ancho) y mostrarlo evidentemente en un TPaintBox, TImage, TPanel o en el Form solo UNA PARTE del BMP después de cierto cálculo.

Intentaré explicarlo sencillamente, tengo un TButton y un TPanel (con 2 TImage)...... ojo que no se si elegí la forma correcta aquí de los componentes, derepente hubiera sido mejor mostrarlos en un TpaintBox o directamente en el Form en cierta posición, no sé:

Código Delphi [-]
Case Num of //Después de un cálculo
0: //Mostrar solo el "Cero" de toda la imagen "BMPFuente" que tiene dibujado=0123456789 de 32 de alto x 320 pixels largo
1: //Mostrar solo el "1" de toda la imagen "BMPFuente" que tiene......... x 320 pixels largo (10 pixels para cada uno)
2: //Mostrar solo el "2" de toda la imagen "BMPFuente".........
....
end;

En el Case para cada caso mostraría un número de miBMP recortado en los TIMage contenidos en el TPanel o en un TPaintBox.

Quizá me digan que más sencillo resultaría crear BMPs para cada uno y mostrarlos.... de acuerdo! pero lo que no quiero es llenar por ejemplo de 10 BMPs como fuente de números en mi Directorio, mucho menos de 23 BMPs del Abecedario. Prefiero crear uno LARGO (uno solo) conteniendo a todos, para luego recortarlos uno a uno y mostrarlos según necesidades y cálculo.

Como dije arriba, de los ejemplos que encontré en la Red, todos se basan en el CopyRect teniendo el gráfico en el Form, y así calculando sus medidas y recortarlo. Lo que yo necesito es ver la forma de hacer ese recorte sin que se vea (sin que se encuentre) en el Form, solo sabiendo las medidas de mi BMP que se encuentra en mi directorio y tomando en el Case un ancho diferente para cada uno.

- Luego será otro lo del blinkado.

Última edición por Deiv fecha: 11-06-2006 a las 02:50:50.
Responder Con Cita
  #5  
Antiguo 11-06-2006
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Vamos a ir por partes, o mejor por trozos

Primero lo que tu pides:
Código Delphi [-]
procedure DibujarTrozo(Filename: string; Count, Index: Integer; Dest: TCanvas);
var
  Ancho: Integer;
begin
  with TBitmap.Create do
  try
    LoadFromFile(Filename);
    Ancho:= Width div Count;
    Dest.CopyRect(Rect(0,0,Ancho,Height), Canvas,
                  Rect(Ancho*Index,0,Ancho*(Index+1),Height));
  finally
    Free;
  end;
end;

Para utilizar esa funcion, pasale como parametro la ruta del bmp con los diferentes dibujos uno a continuacion del otro en horizontal, pasale tambien el numero de elementos que contine y el indice del que quieres dibujar teniendo en cuenta que el primero sera el 0 y el ultimo Count-1. Por ejemplo, si el bitmap tiene 10 elementos:

Código Delphi [-]
  // Dibujamos el trozo sobre el propio formulario
  DibujarTrozo('d:\1.bmp',10,0,Canvas);
  // Dibujamos el Trozo sobre un TPaintBox
  DibujarTrozo('d:\1.bmp',10,9,PaintBox1.Canvas);
  // Dibujamos el Trozo sobre un TImage
  DibujarTrozo('d:\1.bmp',10,5,Image1.Canvas);

Ahora te digo lo que haria yo, utilizaria un TImageList y en el OnCreate del formulario utilizaria esto para cargar las imagenes:

Código Delphi [-]
var
  Bitmap: TBitmap;
begin
  Bitmap:= TBitmap.Create;
  try   
    Bitmap.LoadFromFile('d:\1.bmp');
    ImageList1.Width:= Bitmap.Width div 10; // 10 Elementos
    ImageList1.Height:= Bitmap.Height;
    ImageList1.Masked:= FALSE;
    ImageList1.Add(Bitmap,nil);
  finally
    Bitmap.Free;
  end;
end;

Y luego cada vez que lo quisiera dibujar utilizaria esto otro:
Código Delphi [-]
  // Esto por ejemplo dibuja el trozo numero 6
  ImageList1.Draw(Canvas,0,0,5);
  // Y esto por dibuja el trozo numero 10 en un TPaintbox
  ImageList1.Draw(PaintBox1.Canvas,0,0,9);

Tu decides ...

Última edición por seoane fecha: 11-06-2006 a las 04:42:29.
Responder Con Cita
  #6  
Antiguo 11-06-2006
madriles madriles is offline
Miembro
 
Registrado: may 2003
Ubicación: madrid
Posts: 93
Poder: 22
madriles Va por buen camino
Hola Deiv
la verdad es que no entiendo realmente tu problema ¿ estas obligado a cargar la imagen ?, por supuesto, siempre tendras que cargarla en memoria para hacer los calculos, da lo mismo el sistema que uses. ¿Que problema te supone cargar un JPG de 32*320 pixel?, son 5 Kb. Ademas, teniendola en tu ejecutable te evitas que por error borren tu imagen del directorio y te salte una excepcion.
Con la solucion que te propongo solo tienes que tener un TPanel mas en tu formulario (de 32 * 32 pixel) que contiene la imagen completa y luego solo es cuestion de moverla con un calculo sencillo como es, en tu caso

Código Delphi [-]
Image1.Left := -(Num * 32);//ya que 32 es tu ancho fijo de dibujo

tienes, por supuesto, muchas otras soluciones, pero mas sencillas y con menos codigo...

bueno, tu tienes la ultima palabra, utiliza la solucion que mas te convenga y haznos saber como te queda
un saludo
Responder Con Cita
  #7  
Antiguo 11-06-2006
Deiv Deiv is offline
Miembro
 
Registrado: jul 2005
Ubicación: La Paz - Bolivia
Posts: 364
Poder: 20
Deiv Va por buen camino
Gracias amigos, en este momento no dispongo de Delphi, llegando a casa probaré las sugerencias y luego les comento.
Saludos
Responder Con Cita
  #8  
Antiguo 12-06-2006
Deiv Deiv is offline
Miembro
 
Registrado: jul 2005
Ubicación: La Paz - Bolivia
Posts: 364
Poder: 20
Deiv Va por buen camino
Gracias Seoane (interesante tu nueva identificación "Registered User") y gracias Madriles por sus orientaciones, me solucionaron el caso, tienen razón existe muchas formas, yo ya la estaba viendo "cuadrado" pensando que no había solución, ahora solo me queda como realizar el BLINKADO con un TTimer para el mismo caso.
Responder Con Cita
  #9  
Antiguo 12-06-2006
madriles madriles is offline
Miembro
 
Registrado: may 2003
Ubicación: madrid
Posts: 93
Poder: 22
madriles Va por buen camino
parpadeo del bmp

hola de nuevo,
para el parpadeo del bmp, siguiendo con mi propuesta, solo tienes que hacer el bmp el doble de alto, en la parte superior el numero normal y en la parte de abajo el numero de parpadeo, nose en color verde por ejemplo asi con este codigo u otro parecido lo consigues

Código Delphi [-]
procedure TForm1.Timer1Timer(Sender: TObject);
begin
    if Image1.Top =  0   Then
       Image1.Top := -32 else
       Image1.Top := 0;
end;

un saludo
Responder Con Cita
  #10  
Antiguo 20-06-2006
Deiv Deiv is offline
Miembro
 
Registrado: jul 2005
Ubicación: La Paz - Bolivia
Posts: 364
Poder: 20
Deiv Va por buen camino
Question

No consigo transparentar la parte que recupero del BitMap he colocado el código, en TFormCreate:
Código Delphi [-]
TransparentBmp.TransparentColor := clWhite;

TransparentBmp.Transparent := True;

al código de arriba:


Código Delphi [-]
procedure DibujarTrozo(Filename: string; Count, Index: Integer; Dest: TCanvas);
var
  Ancho: Integer;
begin
  with TBitmap.Create do
  try
    LoadFromFile(Filename);
    Ancho:= Width div Count;
    Dest.CopyRect(Rect(0,0,Ancho,Height), Canvas,
                  Rect(Ancho*Index,0,Ancho*(Index+1),Height));
  finally
    Free;
  end;
end;

Mi BitMap tiene fondo blanco, y con el DRAW me dibuja todo pero transparente, en cambio según el código de arriba no logro transparentarlo. Una ayuda please.

Saludos

Última edición por Deiv fecha: 20-06-2006 a las 20:45:57.
Responder Con Cita
  #11  
Antiguo 22-06-2006
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Cita:
Empezado por Deiv
No consigo transparentar la parte que recupero del BitMap
...

Mi BitMap tiene fondo blanco, y con el DRAW me dibuja todo pero transparente, en cambio según el código de arriba no logro transparentarlo. Una ayuda please.
No es la forma mas elegante de hacerlo pero si muy sencilla de entender, vamos comprobando pixel a pixel y solo copiamos los que no son blancos

Código Delphi [-]
procedure DibujarTrozo(Filename: string; Count, Index: Integer; Dest: TCanvas);
var
  Ancho: Integer;
  i,j: Integer;
begin
  with TBitmap.Create do
  try
    LoadFromFile(Filename);
    Ancho:= Width div Count;
    for i:= 0 to Ancho - 1 do
      for j:= 0 to Height -1 do
        if Canvas.Pixels[(Ancho*Index)+i,j] <> clWhite then
          Dest.Pixels[i,j]:= Canvas.Pixels[(Ancho*Index)+i,j];
  finally
    Free;
  end;
end;

De todas yo consideraria la posibilidad de usar un TImageList como te sugeri un poco mas arriba.
Responder Con Cita
  #12  
Antiguo 23-06-2006
Deiv Deiv is offline
Miembro
 
Registrado: jul 2005
Ubicación: La Paz - Bolivia
Posts: 364
Poder: 20
Deiv Va por buen camino
Wink

Gracias Seoane, funciona!
Responder Con Cita
  #13  
Antiguo 27-06-2006
Deiv Deiv is offline
Miembro
 
Registrado: jul 2005
Ubicación: La Paz - Bolivia
Posts: 364
Poder: 20
Deiv Va por buen camino
Arrow

Probé el consejo de Seoane con el TImageList, y modifiqué un poco el código para transparentarlo de la siguiente forma:
Código Delphi [-]
var
  Bitmap: TBitmap;
begin
  Bitmap:= TBitmap.Create;
  try
    BitMap.LoadFromFile(FileName);
    ImageList1.Width:= BitMap.Width div 10; // 10 Elementos
    ImageList1.Height:= BitMap.Height;
    ImageList1.BkColor:=clNone;
    ImageList1.BlendColor:= clNone;
    ImageList1.DrawingStyle:= dsTransparent;
    ImageList1.Masked:= True;
    ImageList1.AddMasked(Bitmap, Bitmap.Canvas.Pixels[0,0]);
  finally
    BitMap.Free;
  end;
end;
Funciona bien.
He cargado 2 PaintBox capturando en ellos diferentes trozos del BitMap que tengo:
Código Delphi [-]
   ImageList1.Draw(PaintBox1.Canvas,0,0,0);
   ImageList1.Draw(PaintBox2.Canvas,0,0,1);
Todo bien, he intendado MOVERLOS y cruzar a ambos manteniendo su transparencia con TTimer, y ahí tengo un problemita del cual
no me doy cuenta, y requiero de vuestra ayuda:
Código Delphi [-]
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  PaintBox1.Left:=PaintBox1.Left+2;
  PaintBox1.Repaint;
  ImageList1.Draw(PaintBox1.Canvas,0,0,0);
  PaintBox2.Left:=PaintBox2.Left-2;
  PaintBox2.Repaint;
  ImageList1.Draw(PaintBox2.Canvas,0,0,1);
end;
Necesitaba sobreponer uno sobre el otro en el momento de cruce transparentes. Arriba lo que hace es uno sobrepone al otro
pero sin transparentarlo (lo tapa, o lo cubre). Es decir necesito en el momento de cruce dibujar uno y encima el otro, pero
mostrando ambos ¿Donde voy mal?
Pd.- Tal vez no me estoy dejando entender si el código de arriba no estuviera en un TTimer, y los ubico en posición de cruce
(left) me muestra bien a ambos (sin TTimer) es lo que requiero en realidad pero que eso se vea así al momento de cruce.
Gracias y saludos
Responder Con Cita
  #14  
Antiguo 03-07-2006
Deiv Deiv is offline
Miembro
 
Registrado: jul 2005
Ubicación: La Paz - Bolivia
Posts: 364
Poder: 20
Deiv Va por buen camino
Finalmente, para el poco conocimiento que tengo logre lo que quería, tuve que darle muchas vueltas al código y finalmente comprendí que el orden de las líneas estaban mal. Este funciona:
Código Delphi [-]
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  PaintBox1.Left:=PaintBox1.Left+2;
  PaintBox1.Repaint;
  PaintBox2.Left:=PaintBox2.Left-2;
  PaintBox2.Repaint;
  
  ImageList1.Draw(PaintBox1.Canvas,0,0,0);
  ImageList1.Draw(PaintBox2.Canvas,0,0,1);
end;
Ahora estoy enredado en otro, estoy intentando blinkar habiendo creado el doble de alto como sugirió madriles, pero el ejemplo de arriba está dado para un TImage con la propiedad Top, y yo estoy trabajando con una TImageList como mencioné en mi último post y este no tiene la propiedad Top????
Código Delphi [-]
var
  Bitmap: TBitmap;
implementation
procedure TForm1.FormCreate(Sender: TObject);
begin
  Bitmap:= TBitmap.Create;
  try
    BitMap.LoadFromFile(getcurrentdir+'/BigBmp.bmp');
    ImageList1.Width:= BitMap.Width div 10; // 10 Elementos
    ImageList1.Height:= BitMap.Height div 2;  //Muestro solo la parte superior del BitMap de doble alto
    ImageList1.BkColor:=clNone;
    ImageList1.BlendColor:= clNone;
    ImageList1.DrawingStyle:= dsTransparent;
    ImageList1.Masked:= True;
    ImageList1.AddMasked(Bitmap, Bitmap.Canvas.Pixels[0,0]);
  finally
    BitMap.Free;
  end;
end;
¿Como podría blinkar esa sección del TImageList?
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
manejar directorios XxEdwinxX Varios 1 20-12-2005 23:26:28
como manejar el datapicker jas010 Conexión con bases de datos 7 04-04-2005 22:32:40
Manejar subtitulos... SGOFx Varios 6 05-02-2005 21:09:16
Manejar dirección API cardomjar Varios 7 08-12-2004 13:13:59
Manejar Componetes sergio_015 OOP 12 25-11-2004 12:01:47


La franja horaria es GMT +2. Ahora son las 01:05:46.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi