Você está na página 1de 4

1

Listagem 1. Desenhando um bitmap em um formulrio


{ Declare Bitmap: TBitmap na seo private } procedure TForm1.FormCreate(Sender: TObject); var begin Bitmap := TBitmap.Create; Bitmap.LoadFromFile('C:\Windows\Deserto.bmp'); end; procedure TForm1.FormPaint(Sender: TObject); begin Canvas.Draw(0, 0, Bitmap); end; procedure TForm1.FormDestroy(Sender: TObject); begin Bitmap.Free; end;

Listagem 2. Algoritmo de Stretch Bilinear


unit BM_MANIPULACAO_IMAGENS; interface uses Graphics; procedure StretchBilinear(Origem: TGraphic; Dest: TBitmap; Largura, Altura: integer); implementation type TCor24Bits = packed record R, G, B: byte; end; PCor24Bits = ^TCor24Bits; TLinha24Bits = array [0..0] of TCor24Bits; PLinha24Bits = ^TLinha24Bits; { *=========== StretchBilinear24 ===================== Faz o stretch Bilinear em um bitmap de 24 bits por pixel. O que o algoritmo faz mapear um cursor X, Y da imagem de origem na imagem de destino. Esse cursor teoricamente um nmero real. Sendo assim, esse cursor aponta para at quatro pixels. O valor do pixel do bitmap de destino a soma ponderada dos pixels apontados no bitmap de origem. Por exemplo, se o meu cursor possui o valor X = 2,4, isso significa que o bitmap de destino vai receber 40% do pixel 2 e 60% do pixel 3 no eixo X. Como no vamos utilizar ponto flutuante, nossas coordenadas vo ser multiplicadas por 65536 para no termos que fazer arredondamentos. } procedure StretchBilinear24(Origem,Dest:TBitmap); var x, y, { Posio x e y do nosso Bitmap final } PosX, PosY, { Posio x e y do nosso cursor no Bitmap de origem. Esses valores so multiplicados po 65536 } PosXReal, { Valor do cursor em X arredondado } IncY, IncX, { Incremento x e y do nosso cursor a cada iterao } Aux, { Varivel auxiliar } z, z2, iz2, { Variveis aux para clculo dos pesos } PesoX1Y1, { Pesos de cada pixel apontado pelo cursor } PesoX2Y1, { Utilizados na mdia ponderada } PesoX1Y2, PesoX2Y2: Integer; y1, y2: PLinha24Bits; { Linhas utilizadas no bitmap de origem } PixelAtual: PCor24Bits; { Pixel atualmente processado do bitmap de destino } begin { Inicializao das variveis }

2
PosY := 0; IncX := ((Origem.Width - 1) * 65536) div Dest.Width; IncY := ((Origem.Height - 1) * 65536) div Dest.Height; for y := 0 to Dest.Height - 1 do begin PixelAtual:= Dest.ScanLine[y]; PosX := 0; Aux := PosY div 65536; y1 := Origem.ScanLine[Aux]; { Temos que tomar cuidado com a ltima linha para no pegarmos alm do Bitmap } if Aux < Origem.Height - 1 then Inc(Aux); y2 := Origem.ScanLine[Aux]; z2 := (PosY and $FFFF) + 1; iz2 := ((not PosY) and $FFFF) + 1; for x:= 0 to Dest.Width - 1 do begin PosXReal := PosX div 65536; Z := PosX and $FFFF; { Clculo dos pesos } PesoX2Y1 := (iz2*z) shr 16; PesoX1Y1 := iz2 - PesoX2Y1; PesoX2Y2 := (z2*z) shr 16; PesoX1Y2 := z2 - PesoX2Y2; { Vamos fazer as somas ponderadas de cada cor } PixelAtual.b := (y1[PosXReal].b * PesoX1Y1 + y1[PosXReal + 1].b * PesoX2Y1 + y2[PosXReal].b * PesoX1Y2 + y2[PosXReal + 1].b * PesoX2Y2) div 65536; PixelAtual.g := (y1[PosXReal].g * PesoX1Y1 + y1[PosXReal + 1].g * PesoX2Y1 + y2[PosXReal].g * PesoX1Y2 + y2[PosXReal + 1].g * PesoX2Y2) div 65536; PixelAtual.r :=(y1[PosXReal].r * PesoX1Y1 + y1[PosXReal + 1].r * PesoX2Y1 + y2[PosXReal].r * PesoX1Y2 + y2[PosXReal + 1].r * PesoX2Y2) div 65536; Inc(PosX, IncX); { Aqui est um dos macetes de manipulao de imagens: Temos um ponteiro para o pixel atual e simplesmente incrementamo-no } Inc(PixelAtual); end; Inc(PosY, IncY); end; end; procedure StretchBilinear(Origem: TGraphic; Dest: TBitmap; Largura, Altura: integer); var CopiaOrigem: TBitmap; begin if (Origem is TBitmap) then CopiaOrigem := TBitmap(Origem) else begin { Se o nosso Origem no for um TBitmap, temos que copiar para um } CopiaOrigem := TBitmap.Create; CopiaOrigem.Width := Origem.Width; CopiaOrigem.Height := Origem.Height; CopiaOrigem.Canvas.Draw(0, 0, Origem); end; try { Vamos trabalhar somente com 24 bits } CopiaOrigem.PixelFormat := pf24bit; Dest.FreeImage; Dest.PixelFormat := pf24bit; Dest.Width := Largura; Dest.Height := Altura; StretchBilinear24(CopiaOrigem, Dest); Dest.Canvas.Draw(0, 0, Dest); finally if not (Origem is TBitmap) then CopiaOrigem.Free; end; end; end.

3
Listagem 3. Implementao dos mtodos GeraImagem e InvalidaRect
procedure TForm1.GeraImagem(indice: integer); var Tempo: Cardinal; Fat: Double; begin InvalidaRect(indice); { Calcula o tamanho do Bitmap achatado } if indice = 1 then Fat := ScrollBar1.Position / 100 else Fat := ScrollBar2.Position / 100; FRects[indice] := Rect(0, 0, Round(FPicture.Width * Fat), Round(FPicture.Height * Fat)); { Inicializao do clculo do tempo } Tempo := GetTickCount; if Indice = 1 then begin { Stretch normal do Delphi } FBitmaps[1].Width := FRects[1].Right; FBitmaps[1].Height := FRects[1].Bottom; FBitmaps[1].Canvas.StretchDraw(FRects[1], FPicture.Graphic); end else begin { Stretch bilinear } StretchBilinear(FPicture.Graphic, FBitmaps[2], FRects[2].Right, FRects[2].Bottom); end; Tempo := GetTickCount - Tempo; if Indice = 1 then begin Label5.Caption := IntToStr(Tempo) + ' milissegundos'; OffsetRect(FRects[1], Label5.Left, TopoImagem); end else begin Label6.Caption := IntToStr(Tempo) + ' milissegundos'; OffsetRect(FRects[2], Label6.Left, TopoImagem); end; { Posiciona o retnculo do bitmap no formulrio } InvalidaRect(indice); end; procedure TForm1.InvalidaRect(i: integer); begin InvalidateRect(Handle, @FRects[i], True); end;

Listagem 4. Cdigo do boto para abrir a imagem


procedure TForm1.Button1Click(Sender: TObject); begin if OpenPictureDialog1.Execute then begin InvalidaRect(0); FPicture.LoadFromFile( OpenPictureDialog1.FileName); FRects[0] := Rect(16, TopoImagem, 16 + FPicture.Width, TopoImagem + FPicture.Height); InvalidaRect(0); GeraImagem(1); GeraImagem(2); end; end;

Listagem 5. Cdigo dos eventos do formulrio


procedure TForm1.FormCreate(Sender: TObject); begin FBitmaps[1] := TBitmap.Create; FBitmaps[2] := TBitmap.Create; FPicture := TPicture.Create; end;

4
procedure TForm1.FormDestroy(Sender: TObject); begin FBitmaps[1].Free; FBitmaps[2].Free; FPicture.Free; end; procedure TForm1.FormPaint(Sender: TObject); begin Canvas.Draw(FRects[0].Left, FRects[0].Top, FPicture.Graphic); Canvas.Draw(FRects[1].Left, FRects[1].Top, FBitmaps[1]); Canvas.Draw(FRects[2].Left, FRects[2].Top, FBitmaps[2]); end;

Você também pode gostar