Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Trucos (https://www.clubdelphi.com/foros/forumdisplay.php?f=52)
-   -   Cambiar brillo y color de una imagen (https://www.clubdelphi.com/foros/showthread.php?t=80457)

seoane 09-06-2006 17:39:27

Cambiar brillo y color de una imagen
 
Esta funcion permite tratar de forma independiente cada canal de color de una imagen, esto permite cambiar el color de la imagen o si todos los canales se multiplican por el mismo valor se cambia el brillo.

Puede tratar cualquier imagen soportada por un TPicture (bmp, ico, wmf, emf y jpeg si se añade Jpeg a las uses), aunque la imagen resultante siempre es un bitmap.

Código Delphi [-]
type
  Triple = array[1..3]of Byte;

// Realiza la operacion (b * x) / 128
function Multiplicar(b: Byte; x: Integer): byte;
begin
  x:= (x * b);
  x:= x shr 7;
  if x > 255 then Result:= 255
    else Result:= x;
end;

procedure Canales(Imagen: TPicture; Rojo, Verde, Azul: Byte);
var
  Bitmap: TBitmap;
  P: ^Triple;
  i, j: Integer;
begin
  if not (Imagen.Graphic is TBitmap) then
  begin
    Bitmap:= TBitmap.Create;
    try
      Bitmap.Width:= Imagen.Width;
      Bitmap.Height:= Imagen.Height;
      Bitmap.Canvas.Draw(0,0,Imagen.Graphic);
      Imagen.Assign(Bitmap);
    finally
      Bitmap.Free;
    end;
  end;
  Imagen.Bitmap.PixelFormat:= pf24bit;
  for j:= 0 to Imagen.Bitmap.Height - 1 do
  begin
    P:= Imagen.Bitmap.ScanLine[j];
    for i:= 0 to Imagen.Bitmap.Width - 1 do
    begin
      P^[1]:= Multiplicar(P^[1],Azul);
      P^[2]:= Multiplicar(P^[2],Verde);
      P^[3]:= Multiplicar(P^[3],Rojo);
      inc(P);
    end;
  end;
end;

Ejemplos de uso:
Código Delphi [-]
 // Oscurecemos la imagen de un TImage
 Canales(Image1.Picture,64,64,64);
 // Iluminamos la imagen de un TImage
 Canales(Image1.Picture,192,192,192);
 // Esto no hace nada ya que 128 es el valor central
 Canales(Image1.Picture,128,128,128); 
 
 // Aqui abrimos una imagen, aumentamos el tono de rojo
 // y disminuimos el de azul, luego guardamos la imagen como Jpeg
var
  Imagen: TPicture;
  Jpeg: TJPEGImage;
begin
  Imagen:= TPicture.Create;
  Jpeg:= TJPEGImage.Create;
  try
    Imagen.LoadFromFile('d:\1.jpg');
    // Resaltamos el color rojo y bajamos el azul
    Canales(Imagen,192,128,64);
    Jpeg.Assign(Imagen.Bitmap);
    Jpeg.SaveToFile('d:\2.jpg');
  finally
    Imagen.Free;
    Jpeg.Free;
  end;
end;

turminator 19-06-2006 21:02:21

Hola Seoane, siento ser tan pesado pero creo que estoy por el buen camino y en breve espero acabar con este problema. resulta que tu codigo me va perfectamente. He creado un form con un timage y una imagen y con el codigo dentro de Implementation. Lo que he echo en el form es crear dos botones llamados oscurecer y Aclarecer, cada uno con sus funciones pertenecientes [delphi] // Oscurecemos la imagen de un TImage
Canales(Image1.Picture,64,64,64);
// Iluminamos la imagen de un TImage
Canales(Image1.Picture,192,192,192);[delphi]

Me funciona bien pero son excluyentes, es decir que cuando ejecuto " mi aplicacion" si le doy a oscurecer se oscurece pero si acto seguido le doy a aclarecer no me reacciona. En cambio si ejecuto la aplicación de nuevo y en vez de empezar oscureciendo empiezo, aclareciendo me funciona, y cuando despues le doy a oscurecer tampoco reacciona. Habria algun modo de que pudiera ir pulsando el boton aclarecer y oscurecer alternativamente y no tuviera que volver a ejecutar?

Muchisimas gracias de veras por tu dedicación y conocimientos.

turminator 19-06-2006 21:03:36

Hola Seoane, siento ser tan pesado pero creo que estoy por el buen camino y en breve espero acabar con este problema. resulta que tu codigo me va perfectamente. He creado un form con un timage y una imagen y con el codigo dentro de Implementation. Lo que he echo en el form es crear dos botones llamados oscurecer y Aclarecer, cada uno con sus funciones pertenecientes [delphi] // Oscurecemos la imagen de un TImage
Canales(Image1.Picture,64,64,64);
// Iluminamos la imagen de un TImage
Canales(Image1.Picture,192,192,192);[delphi]

Me funciona bien pero son excluyentes, es decir que cuando ejecuto " mi aplicacion" si le doy a oscurecer se oscurece pero si acto seguido le doy a aclarecer no me reacciona. En cambio si ejecuto la aplicación de nuevo y en vez de empezar oscureciendo empiezo, aclareciendo me funciona, y cuando despues le doy a oscurecer tampoco reacciona. Habria algun modo de que pudiera ir pulsando el boton aclarecer y oscurecer alternativamente y no tuviera que volver a ejecutar?

Muchisimas gracias de veras por tu dedicación y conocimientos.

turminator 19-06-2006 21:05:48

Lo que sucede es que cada vez que quiero pulsar oscurecer se oscurece pero si quiero pulsar después aclarecer, no me responde, es como si fueran excluyentes, que una vez pulsado uno me desactive el otro, porque tambien me sucede a la inversa.

Muchas gracias por tu dedicacion y conocimientos, de veras.

PD: Creo que ocurrió algun error en el foro cuando quise meterle los claudatores de Delphi.

seoane 20-06-2006 01:37:51

Parece ser que el problema es que el TImage no se actualiza, pero tiene facil solucion:

Código Delphi [-]
  Canales(Image1.Picture,64,64,64);
  // Esta instruccion la añadimos para actualizar el TImage
  Image1.Repaint

seoane 20-06-2006 01:46:07

Parece ser que el problema es que el TImage no se actualiza, pero tiene facil solucion:

Código Delphi [-]
  Canales(Image1.Picture,64,64,64);
  // Esta instruccion la añadimos para actualizar el TImage
  Image1.Repaint


La franja horaria es GMT +2. Ahora son las 01:00:02.

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