Fórum Brilho na imagem com RGB #268930
17/02/2005
0
O efito que quero é semelhante ao que ocorre nos botões do outlook.
Tentei usando a função RGB, mas só em aumentar apenas uma unidade nos valores as cores já ficam muito diferentes.
Quero também o inverso. Escurecer um pouquinho a imagem.
Raserafim
Curtir tópico
+ 0Posts
17/02/2005
Beppe
Gostei + 0
17/02/2005
Marcelo Saviski
Ou vc pode tentar ver nesse [url=http://forum.clubedelphi.net/viewtopic.php?t=5986&highlight=brilho+imagem]outro tópico[/url]
Gostei + 0
17/02/2005
Raserafim
Marcelo, eu já havia visto este tópico, mas não entendi o código. Não gosto de escrever uma função sem saber exatamente o q esto fazendo. Caso o código da revista seja mais simples, vc poderia colocar aqui?
Gostei + 0
17/02/2005
Beppe
Gostei + 0
17/02/2005
Massuda
Gostei + 0
17/02/2005
Beppe
Como o Massuda disse vc pode usar a rotina ColorAdjustLuma, mas também existem lá as rotinas GetHighLightColor e GetShadowColor(note que elas tomam um argumento padrão), entretanto, eu chequei, elas não fazem exatamente o que o Outlook faz. Se vc quer duplicar o efeito, acho que terá que usar uma destas 3 funções com um valor baseado na luminosidade atual.
Eu também olhei a implementação, e isto me desencorajou de implementar em MMX. Como elas me parecem(não testei) lentas, considere fazer um ´cache´ das imagens, ou monte uma tabela de hash com as cores. Em GraphUtils isto é feito apenas para a última cor.
T+
Gostei + 0
17/02/2005
Beppe
unit Unit1;
interface
uses
Windows, Forms, Controls, StdCtrls, Buttons, Graphics, Classes, ExtCtrls,
SysUtils, GraphUtil;
type
TForm1 = class(TForm)
Image1: TImage;
BitBtn1: TBitBtn;
BitBtn2: TBitBtn;
BitBtn3: TBitBtn;
procedure FormCreate(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
procedure BitBtn3Click(Sender: TObject);
private
{ Private declarations }
public
Bmp: TBitmap;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function ColorAddChannel(C: TColor; N: Integer): TColor;
asm
pxor mm0, mm0
movd mm1, C
movd mm2, N
punpcklbw mm1, mm0
packuswb mm2, mm2
packuswb mm2, mm2
paddusb mm2, mm1
packuswb mm2, mm0
movd eax, mm2
and eax, $ffffff
emms
end;
procedure ColorAddChannelArray32(A, B: PIntegerArray; Size, N: Integer);
asm
pxor mm0, mm0
movd mm2, N
packuswb mm2, mm2
packuswb mm2, mm2
@loop:
movd mm1, [A]
punpcklbw mm1, mm0
paddusb mm1, mm2
packuswb mm1, mm0
movd [B], mm1
and [B], $ffffff
add A, 4
add B, 4
dec Size
jnz @loop
emms
end;
procedure TForm1.FormCreate(Sender: TObject);
var
A: TColor;
X, Y: TColor;
begin
A := clRed;
X := ColorAddChannel(A, 30);
ColorAddChannelArray32(@A, @Y, 1, 30);
Caption := Format(´¬x - ¬x´, [X, Y]);
Image1.Picture.Bitmap.PixelFormat := pf32bit;
Bmp := TBitmap.Create;
Bmp.Assign(Image1.Picture.Graphic);
Image1.Picture.Assign(Bmp);
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
var
X, Y: Integer;
begin
for X := 0 to Bmp.Width - 1 do
for Y := 0 to Bmp.Height - 1 do
Image1.Canvas.Pixels[X, Y] := ColorAddChannel(Bmp.Canvas.Pixels[X, Y], 90);
end;
procedure TForm1.BitBtn2Click(Sender: TObject);
var
I: Integer;
A, B: Pointer;
S, F: Int64;
begin
QueryPerformanceCounter(S);
// A := Bmp.ScanLine[Image1.Height - 1];
// B := Image1.Picture.Bitmap.ScanLine[Image1.Height - 1];
// ColorAddChannelArray32(A, B, Bmp.Width * Bmp.Height, 90);
for I := 0 to Bmp.Height - 1 do
begin
A := Bmp.ScanLine[I];
B := Image1.Picture.Bitmap.ScanLine[I];
ColorAddChannelArray32(A, B, Bmp.Width, 90);
end;
QueryPerformanceCounter(F);
Caption := IntToStr(F - S);
end;
procedure TForm1.BitBtn3Click(Sender: TObject);
var
X, Y: Integer;
begin
for X := 0 to Bmp.Width - 1 do
for Y := 0 to Bmp.Height - 1 do
Image1.Canvas.Pixels[X, Y] := GetHighLightColor(Bmp.Canvas.Pixels[X, Y]);
end;
end.Pode ver que o resultado é diferente, mas melhor, na minha opinião.
Gostei + 0
18/02/2005
Raserafim
mas valeu tb massuda, era mesmo o q eu queria, algo simples. E a procedure ColorAdjustLuma caiu certinho. É só eu passar como parâmetro o pixel que quero modificar (ex: Image1.Canvas.Pixels[X, Y]), mais um parämetro que diz o brilho (coloquei 35 e -35, para clarear e escurecer respectivamente), e mais um parâmetro que não entendi pra q serve mas coloquei true.
Mas agora preciso resolver um outro problema:
Tive que criar um laço for para varrer toda imagem pegando pixel por pixel e colando em um outro image. Mas o problema é que essa varredura é muito lenta e demora um pouco para a imagem alterada aparecer.
Como faço para agilizar esse processo?
Gostei + 0
18/02/2005
Marcelo Saviski
Usa a função do Beppe :) :P
Gostei + 0
18/02/2005
Beppe
Trabalho algum, apenas uma oportunidade para treinar meu MMX.
O último parâmetro é ignorado pela função.
Está sendo gentil né? ColorAdjustLuma foi umas 100x mais lenta que a minha função. O problema é que vc deve estar usando Canvas.Pixels[], que é bem lento por design. Use ScanLine, que recupera o array de pixels(lembre-se de chamar Refresh na imagem depois, eu esqueci disso no exemplo).
[quote:709c368e52=´Marcelo Saviski´]
Usa a função do Beppe :) :P[/quote:709c368e52]
Eu concordo. :P Mas se ele prefere fazer do modo lento, doloroso, e mais feim, opção dele... :D
ColorAdjustLuma(60), ColorAddChannelArray32(90)
[URL=http://img67.exs.cx/my.php?loc=img67&image=high6sw.jpg][img:709c368e52]http://img67.exs.cx/img67/8725/high6sw.th.jpg[/img:709c368e52][/URL]
Gostei + 0
18/02/2005
Marcelo Saviski
Gostei + 0
18/02/2005
Beppe
MMX é mais básico que tem. Mas é meu preferido, questão de utilidade e padronização.
MMX - Desde o Pentium (I) MMX. AMD também tem. Aritmética inteira.
SS2 - Desde o Pentium III. AMD também tem. Aritmética flutuante.
SS3 - Desde o Pentium 4. Aritmética inteira.
3DNOW - Apenas AMD.
Todos são SIMD(instrução única operando sobre dados múltiplos, i.e. um array)
Gostei + 0
18/02/2005
Marcelo Saviski
quem sabe um dia ainda acordo sabendo isso...
Gostei + 0
22/02/2005
Raserafim
Gostei + 0
22/02/2005
Beppe
procedure TForm1.BitBtn2Click(Sender: TObject); var I: Integer; A, B: Pointer; S, F: Int64; begin QueryPerformanceCounter(S); A := Bmp.ScanLine[Image1.Height - 1]; B := Image1.Picture.Bitmap.ScanLine[Image1.Height - 1]; for I := 0 to Bmp.Height * Bmp.Width - 1 do PIntegerArray(B)[I] := ColorAdjustLuma(PIntegerArray(A)[I], Valor); QueryPerformanceCounter(F); ShowMessage(´Demorou ´ + IntToStr(F - S) + ´ ciclos.´); end;
Este é um exemplo básico, pode aplicar qualquer transformação de cor assim.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)