PDA

Ver la Versión Completa : Cambiar brillo y color de una imagen


seoane
09-06-2006, 18:39:27
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.


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:

// 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, 22: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, 22: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, 22: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, 02:37:51
Parece ser que el problema es que el TImage no se actualiza, pero tiene facil solucion:


Canales(Image1.Picture,64,64,64);
// Esta instruccion la añadimos para actualizar el TImage
Image1.Repaint

seoane
20-06-2006, 02:46:07
Parece ser que el problema es que el TImage no se actualiza, pero tiene facil solucion:


Canales(Image1.Picture,64,64,64);
// Esta instruccion la añadimos para actualizar el TImage
Image1.Repaint