3.1柔化和锐化处理

柔化处理的原理是将图片中每一个像素都由与其相邻的n*n个像素的平均值来代替。N的取值决定了其模糊程度。下面是柔化处理的程序。

程序3.1

unit Unit1;

{柔化处理}

Interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, GraphicProcess, StdCtrls, ExtCtrls;

type

TForm1 = class(TForm)

PaintBox1: TPaintBox;

btnExe: TButton;

txtN: TEdit;

Label1: TLabel;

procedure FormCreate(Sender: TObject);

procedure PaintBox1Paint(Sender: TObject);

procedure btnExeClick(Sender: TObject);

procedure FormDestroy(Sender: TObject);

private

Procedure SmoothPicture(const Bit : TBitmap;var  n : Integer);

public

{ Public declarations }

end;

procedure WritePixel(Pic: TBitmap; tPix: TPixels);

procedure ReadPixel(Pic: Tbitmap; var tPix: TPixels);

var

Form1: TForm1;

Bits : TBitmap;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);

begin

Bits:=TBitmap.Create;

Bits.LoadFromFile(‘Test.Bmp‘);

end;

procedure TForm1.PaintBox1Paint(Sender: TObject);

begin

PaintBox1.Canvas.StretchDraw(Rect(0,0,400,300),Bits);

end;

procedure TForm1.SmoothPicture(const Bit: TBitmap;var n: Integer);

var R,G,B:Integer;

i,j,k,l : Integer;

Pix : TPixels;

nDiv : Integer;

nDivRs : Integer;

jP,jM,ip,im:Integer;

OpCount : Integer;

begin

ReadPixel(Bit,Pix);

if n mod 2 = 0 then n := n +1;

nDiv := n * n;

nDivRs := n div 2;

For i := 0 to Bit.Width-1 do begin

ip:= i + nDivRs;

im := i ;

if im < 0 then im := 0;

if ip > Bit.Width -1 then ip := Bit.Width-1;

For j := 0 to Bit.Height -1 do

begin

R:=0;

G:=0;

B:=0;

jP := j + nDivRs;

jM := j - nDivRs;

if Jp > bit.Height-1 then

jp := Bit.Height-1;

if jm <0 then jm :=0;

OpCount := (ip - im+1) *(jp-jm+1);

For k := im to Ip do  begin

For l := jm to jp do

begin

R := R + Pix[k,l].rgbtRed;

G := G + Pix[k,l].rgbtGreen;

B := B + Pix[k,l].rgbtBlue;

end;

end;

Pix[i,j].rgbtBlue := B div opCount;

Pix[i,j].rgbtGreen := G div opCount;

Pix[i,j].rgbtRed := R div  opCount;

end;

end;

WritePixel(Bit,Pix);

end;

procedure ReadPixel(Pic: Tbitmap; var tPix: TPixels);

Var PixPtr:PbyteArray;i,j,m:Integer;

begin

SetLength(tPix,Pic.Width,Pic.Height);

Pic.PixelFormat := pf24bit;

Pic.HandleType:=bmDIB;

For i :=0 to pic.Height-1 do begin

PixPtr:=Pic.ScanLine[i];

for  j:= 0 to pic.Width-1 do begin

m := j*3;

tPix[j,i].rgbtBlue:=PixPtr[m];

tPix[j,i].rgbtGreen := PixPtr[m+1];

tPix[j,i].rgbtRed := PixPtr[m+2];

end;

end;

end;

procedure WritePixel(Pic: TBitmap; tPix: TPixels);

var PixPtr:PByteArray;i,j,m:Integer;

begin

pic.PixelFormat := pf24bit;

pic.HandleType:=bmDIB;

Pic.Height := High(tPix[0])+1;

Pic.Width:= High(tPix)+1;

For i :=0 to pic.Height-1 do begin

PixPtr:=Pic.ScanLine[i];

for  j:= 0 to pic.Width-1 do begin

m := j*3;

PixPtr[M] := tPix[j,i].rgbtBlue;

PixPtr[m+1] := tPix[j,i].rgbtGreen;

PixPtr[m+2] := tPix[j,i].rgbtRed;

end;

end;

end;

procedure TForm1.btnExeClick(Sender: TObject);

var n :Integer;

begin

n := StrToInt(txtN.Text);

Bits.LoadFromFile(‘Test.bmp‘);

SmoothPicture(Bits,n);

PaintBox1.Refresh;

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

Bits.Free;

end;

end.

原图

柔化系数=21

锐化处理的原理是把每一像素的值与该像素斜上方的像素值之差乘以一个系数再加上该像素原来的颜色值。

如果记图像中任意一个像素(x,y) (x∈[1,图像宽度-1],y∈[1,图像高度-1])修改前的RGB分值分别为OldRed, OldGreen, OldBlue, 修改后的RGB分值分别为NewR,NewG,NewB,有:

newR = (oldR - (x-1,y-1)的Red分值)×待定系数 + OldRed

newG = (oldG - (x-1,y-1)的Green分值)×待定系数 + OldGreen

newB = (oldB - (x-1,y-1)的Blue分值)×待定系数 + OldBlue

根据这个公式,我们的程序如下:

程序3.12

unit Sharp;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, ExtCtrls;

type

TPixels = Array of Array of TRGBTriple;

TfrmMain = class(TForm)

PaintBox1: TPaintBox;

btnExecute: TButton;

lblCap: TLabel;

txtS: TEdit;

procedure FormCreate(Sender: TObject);

procedure FormDestroy(Sender: TObject);

procedure btnExecuteClick(Sender: TObject);

procedure PaintBox1Paint(Sender: TObject);

private

Procedure SharpPic(Bit : TBitmap; n : Single);

public

{ Public declarations }

end;

procedure WritePixel(Pic: TBitmap; tPix: TPixels);

procedure ReadPixel(Pic: Tbitmap; var tPix: TPixels);

var

frmMain: TfrmMain;

Bits : TBitmap;

implementation

{$R *.dfm}

procedure TfrmMain.FormCreate(Sender: TObject);

begin

Bits := TBitmap.Create;

Bits.LoadFromFile(‘Test.bmp‘);

end;

procedure TfrmMain.FormDestroy(Sender: TObject);

begin

Bits.Free;

end;

procedure TfrmMain.btnExecuteClick(Sender: TObject);

var n : Single;c : Integer;

begin

Bits.LoadFromFile(‘Test.BMP‘);

Val(txtS.Text,n,c);

SharpPic(Bits,n);

PaintBox1.Refresh;

end;

procedure ReadPixel(Pic: Tbitmap; var tPix: TPixels);

Var PixPtr:PbyteArray;i,j,m:Integer;

begin

SetLength(tPix,Pic.Width,Pic.Height);

Pic.PixelFormat := pf24bit;

Pic.HandleType:=bmDIB;

For i :=0 to pic.Height-1 do begin

PixPtr:=Pic.ScanLine[i];

for  j:= 0 to pic.Width-1 do begin

m := j*3;

tPix[j,i].rgbtBlue:=PixPtr[m];

tPix[j,i].rgbtGreen := PixPtr[m+1];

tPix[j,i].rgbtRed := PixPtr[m+2];

end;

end;

end;

procedure WritePixel(Pic: TBitmap; tPix: TPixels);

var PixPtr:PByteArray;i,j,m:Integer;

begin

pic.PixelFormat := pf24bit;

pic.HandleType:=bmDIB;

Pic.Height := High(tPix[0])+1;

Pic.Width:= High(tPix)+1;

For i :=0 to pic.Height-1 do begin

PixPtr:=Pic.ScanLine[i];

for  j:= 0 to pic.Width-1 do begin

m := j*3;

PixPtr[M] := tPix[j,i].rgbtBlue;

PixPtr[m+1] := tPix[j,i].rgbtGreen;

PixPtr[m+2] := tPix[j,i].rgbtRed;

end;

end;

end;

procedure TfrmMain.SharpPic(Bit: TBitmap; n: Single);

var R, G, B : Integer;

i,j:Integer;

Pix : TPixels;

im,jm : Integer;

begin

ReadPixel(Bit,Pix);

For i := 1 to Bit.Width-1 do begin

im := i-1;

For j := 1 to Bit.Height-1 do begin

jm := j-1;

R := Pix[i,j].rgbtRed + Round((Pix[i,j].rgbtRed-Pix[im,jm].rgbtRed)*n);

G := Pix[i,j].rgbtGreen + Round((Pix[i,j].rgbtGreen-Pix[im,jm].rgbtGreen)*n);

B := Pix[i,j].rgbtBlue + Round((Pix[i,j].rgbtBlue-Pix[im,jm].rgbtBlue)*n);

if R > 255 then R := 255;

If R <0 then R := 0;

if G > 255 then G := 255;

If G <0 then G := 0;

if B > 255 then B := 255;

If B <0 then B := 0;

Pix[i,j].rgbtRed := R;

Pix[i,j].rgbtGreen := G;

Pix[i,j].rgbtBlue := B;

end;

end;

WritePixel(Bit,Pix);

end;

procedure TfrmMain.PaintBox1Paint(Sender: TObject);

begin

PaintBox1.Canvas.StretchDraw(Rect(0,0,400,300),Bits);

end;

end.

程序的运行结果如下图所示。

原图

锐化系数 = 0.95

探究Delphi的图形处理 之八 -- 图像混合(透明度)效果 

  图像混合(透明度)效果

这种效果经常用在动画的转场过度上。这是一个由图像A逐渐变化为图像B的中间效果。就像向图像B以变量N为透明度覆盖在图像B一样。下图展示了这种效果。

透明度 = 100%

透明度 = 50%

透明度 = 0%

图像过渡效果的原理是,如果记透明度为A,那么在确保图像A和图像B同等大小的情况下,创建一个与图像A或B等大的图像C,对于图像C中每一个像素点P(x,y),它的颜色值为:

R = 图像A的像素点(x,y).R +(图像B的像素点(x,y).R-图像A的像素点(x,y).R)×A

G = 图像A的像素点(x,y).G +(图像B的像素点(x,y).G-图像A的像素点(x,y).G)×A

B = 图像A的像素点(x,y).B +(图像B的像素点(x,y).B-图像A的像素点(x,y).B)×A

根据公式,有下面的程序:

程序3.2

unit AlphaBlending;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, ComCtrls, StdCtrls, ExtCtrls;

type

TPixels = Array of array of TRGBTriple;

TForm1 = class(TForm)

PaintBox1: TPaintBox;

Label1: TLabel;

scA: TTrackBar;

lblPos: TLabel;

Bevel1: TBevel;

procedure FormCreate(Sender: TObject);

procedure PaintBox1Paint(Sender: TObject);

procedure FormDestroy(Sender: TObject);

procedure scAChange(Sender: TObject);

private

public

{ Public declarations }

end;

Procedure GraphicFading(PicA, PicB: TPixels; const PicR: tBitmap; Percent: Byte);

procedure WritePixel(Pic: TBitmap; tPix: TPixels);

procedure ReadPixel(Pic: Tbitmap; var tPix: TPixels);

var

Form1: TForm1;

BitA,BitB:TBitmap;

Bits: TBitmap;

PixA,PixB:TPixels;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);

begin

BitA := TBitmap.create;

BitB := TBitmap.Create;

Bits := TBitmap.Create;

BitA.LoadFromFile(‘PicA.bmp‘);

BitB.LoadFromFile(‘PicB.bmp‘);

Bits.Assign(BitA); //这个语句可以把BitA中的内容复制到Bits中

Bits.PixelFormat := pf24Bit;

ReadPixel(BitA,PixA);

ReadPixel(BitB,PixB);

end;

procedure TForm1.PaintBox1Paint(Sender: TObject);

begin

PaintBox1.Canvas.Draw(0,0,Bits);

end;

Procedure GraphicFading(PicA, PicB: TPixels;

const PicR: tBitmap; Percent: Byte);//Make a Fading Picture From

var                                            //PicA to PicB

MidR,MidG,MidB : Byte;

i,j : integer; m:Integer;

pixPtrA,pixPtrB,pixPtrR : PByteArray;

Position : Single;rPos,gPos:Integer;

PicRWidth:Integer;

begin

Position := Percent / 100;

PicRWidth:=PicR.Width-1;

for i := 0 to picR.Height -1 do begin

PixPtrR := picR.ScanLine[i];

for j := 0 to picRWidth do Begin

m:=j*3;

rPos:=m+2;

gPos:=m+1;

midR := PicA[j,i].RGBTRed+Round((PicB[j,i].RGBTRed-PicA[j,i].RGBTRed)*Position);

midG := PicA[j,i].RGBTgREEN+Round((PicB[j,i].RGBTgREEN-PicA[j,i].RGBTgREEN)*Position);

midB := PicA[j,i].RGBTBlue+Round((PicB[j,i].RGBTBlue-PicA[j,i].RGBTBlue)*Position);

pixPtrR[m] := midB;

pixPtrR[gPos] := midG;

pixPtrR[rPos] := MidR;

end;

end;

end;

procedure ReadPixel(Pic: Tbitmap; var tPix: TPixels);

Var PixPtr:PbyteArray;i,j,m:Integer;

begin

SetLength(tPix,Pic.Width,Pic.Height);

Pic.PixelFormat := pf24bit;

Pic.HandleType:=bmDIB;

For i :=0 to pic.Height-1 do begin

PixPtr:=Pic.ScanLine[i];

for  j:= 0 to pic.Width-1 do begin

m := j*3;

tPix[j,i].rgbtBlue:=PixPtr[m];

tPix[j,i].rgbtGreen := PixPtr[m+1];

tPix[j,i].rgbtRed := PixPtr[m+2];

end;

end;

end;

procedure WritePixel(Pic: TBitmap; tPix: TPixels);

var PixPtr:PByteArray;i,j,m:Integer;

begin

pic.PixelFormat := pf24bit;

pic.HandleType:=bmDIB;

Pic.Height := High(tPix[0])+1;

Pic.Width:= High(tPix)+1;

For i :=0 to pic.Height-1 do begin

PixPtr:=Pic.ScanLine[i];

for  j:= 0 to pic.Width-1 do begin

m := j*3;

PixPtr[M] := tPix[j,i].rgbtBlue;

PixPtr[m+1] := tPix[j,i].rgbtGreen;

PixPtr[m+2] := tPix[j,i].rgbtRed;

end;

end;

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

BitB.Free;

BitA.Free;

BitS.Free;

end;

procedure TForm1.scAChange(Sender: TObject);

begin

GraphicFading(PixA,PixB,Bits,scA.Position);

paintBox1.Canvas.Draw(0,0,Bits);

lblPos.Caption := IntToStr(scA.Position) + ‘ %‘;

lblPos.Refresh;

end;

end.

探究Delphi的图形处理 之九 -- 转为灰度图像 

作者:何咏     发布日期:(2005-4-12 20:56:06

         转为灰度图像

将图像转为灰度的算法非常简单,把图像中每一个像素的R、G、B分值都设置为该像素R、G、B分值的平均值即可。这是因为,在RGB编码中,如果一个像素的R、G、B分值相等,那么这就是一个灰色的像素。例如RGB(i,i,i) (i∈[0,255])可以表示不同灰度等级的灰色。当i = 255时,该像素为白色,当 i = 0时,该像素为白色。下面的程序段给出了灰度图像的算法。这一次,我们使用PRGBTriple类型作为ScanLine的指针类型,大家可以参考一下。

程序3.3

Function GraphicToGray(const Pic: Tbitmap): Integer;

var

i,j : integer;

pixPtr : PRGBTriple;

picH : integer;

picW : Integer;

GrayVal : Byte;

Begin

Pic.PixelFormat := pf24Bit;

Pic.HandleType := bmDIB;

picH := pic.Height;

picW := pic.Width;

for i := 0 to picH -1 do begin

pixPtr := pic.ScanLine[i];

for j := 0 to picW -1 do begin

GrayVal := Round((pixPtr^.rgbtBlue + pixPtr^.rgbtRed +pixptr^.rgbtGreen)/3);

pixPtr^.rgbtBlue := grayVal;

pixptr^.rgbtGreen := grayval;

pixptr^.rgbtRed := grayval;

inc(pixPtr);

end;

end;

end;

下面是上一端程序的运行结果:

原图

处理后

 
探究Delphi的图形处理 之十 -- 对比度调整和反色处理 

  对比度调整和反色处理

图像对比度是指图像颜色值与中间颜色值的距离大小。在图形处理中,我们定义颜色RGB(127,127,127)为中间颜色值。增大或减小某一个像素值与这个值的差距就可以提高和降低图像的颜色值。如果我们记对比度调整前每一颜色通道(即像素颜色值的R、G、B分值)的值为x,修改后的值为y,那么有下图所示的线性关系:

从图中我们可以看出,对于未调整的图像,f(x) = x。如果调整了对比度,那么f(x) 的图像以点(127,127)为原点旋转。如果我们设f(x)= kx + b,提高对比度的问题就转变为根据k求b,在用k和b求f(x)的值的问题(也就是转换坐标系的问题)。其中,k是由用户指定的,它决定了是提高对比度还是降低对比度。如果k>1,就提高对比度,反之则降低对比度。如果k<0,那么可以达到反色的效果。

如果我们以点(127,127)为原点作一个平面直角坐标系,那么在新的坐标系XOY中,我们有Y = kX。把坐标系XOY向左、向下各移动127个单位,此时XOY与xoy重合,我们得到

Y = k(x-127) + 127

因此,我们得到了下面的公式:

NewRed   = k(OldRed  - 127) + 127

NewGreen = k(OldGreen - 127) + 127

NewBlue  = k(OldBlue  - 127) + 127

我们用下面的程序段可以实现对比度的调整。这里直接调用了第2章给出的ReadPixel和WritePixel方法。

程序3.4

Procedure GraphicContrast(Pic: TBitmap;Const tPix: TPixels;Value:Integer);

var RPos:Double;i,j:Integer;

NewR,newG,NewB:Integer;

OffSetValue:Single;

begin

RPos:=Value/100;

OffSetValue:=RPos*(-127)+127;

For  i:=0 to Pic.Width-1 do begin

For  j := 0 to Pic.Height-1 do Begin

NewR := Round(tPix[i,j].rgbtRed*RPos+OffSetValue);

NewG := Round(tPix[i,j].rgbtGreen*RPos+OffSetValue);

NewB := Round(tPix[i,j].rgbtBlue*RPos+OffSetValue);

If NewR>255 then

NewR := 255;

if NewG > 255 then

NewG:=255;

If NewB > 255 then

NewB:=255;

if NewR<0 then NewR := 0;

if NewG<0 then NewG := 0;

if NewB<0 then NewB := 0;

tPix[i,j].rgbtBlue := NewB;

tPix[i,j].rgbtGreen := NewG;

tPix[i,j].rgbtRed := NewR;

end;

end;

WritePixel(pic,tPix);

end;

程序的运行结果如下图所示。

原图

对比度系数k = 1.5

对比度系数 k = -1

探究Delphi的图形处理 之十一 -- 亮度的调整 

作者:何咏

         亮度的调整

我们知道RGB(255,255,255)表示白色,而RGB(0,0,0)表示黑色。由此,如果RGB分量的值越接近255,这个像素越“亮”,如果越接近0,那么像素越“暗”。所以,亮度调整的原理就是对原图像的每一个像素的RGB值都加上或减去一个常量即可。

下面的程序可以调整图像的亮度。

程序3.5

unit Brightness;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, ComCtrls, StdCtrls, ExtCtrls;

type

TPixels = Array of array of TRGBTriple;

TForm1 = class(TForm)

PaintBox1: TPaintBox;

Label1: TLabel;

scB: TTrackBar;

Label2: TLabel;

Label3: TLabel;

Label4: TLabel;

procedure FormCreate(Sender: TObject);

procedure FormDestroy(Sender: TObject);

procedure PaintBox1Paint(Sender: TObject);

procedure scBChange(Sender: TObject);

private

Procedure BrightnessChange(Bit : TPixels; n : Integer);

public

{ Public declarations }

end;

procedure WritePixel(Pic: TBitmap; tPix: TPixels);

procedure ReadPixel(Pic: Tbitmap; var tPix: TPixels);

var

Form1: TForm1;

Bits : TBitmap;

PixA : TPixels;

Pix : TPixels;

implementation

{$R *.dfm}

procedure ReadPixel(Pic: Tbitmap; var tPix: TPixels);

Var PixPtr:PbyteArray;i,j,m:Integer;

begin

SetLength(tPix,Pic.Width,Pic.Height);

Pic.PixelFormat := pf24bit;

Pic.HandleType:=bmDIB;

For i :=0 to pic.Height-1 do begin

PixPtr:=Pic.ScanLine[i];

for  j:= 0 to pic.Width-1 do begin

m := j*3;

tPix[j,i].rgbtBlue:=PixPtr[m];

tPix[j,i].rgbtGreen := PixPtr[m+1];

tPix[j,i].rgbtRed := PixPtr[m+2];

end;

end;

end;

procedure WritePixel(Pic: TBitmap; tPix: TPixels);

var PixPtr:PByteArray;i,j,m:Integer;

begin

pic.PixelFormat := pf24bit;

pic.HandleType:=bmDIB;

Pic.Height := High(tPix[0])+1;

Pic.Width:= High(tPix)+1;

For i :=0 to pic.Height-1 do begin

PixPtr:=Pic.ScanLine[i];

for  j:= 0 to pic.Width-1 do begin

m := j*3;

PixPtr[M] := tPix[j,i].rgbtBlue;

PixPtr[m+1] := tPix[j,i].rgbtGreen;

PixPtr[m+2] := tPix[j,i].rgbtRed;

end;

end;

end;

procedure TForm1.BrightnessChange(Bit: TPixels; n: Integer);

var i ,j :Integer;

R,G,B:Integer;

begin

For i := 0 to Length(Bit)-1 do begin

for j := 0 to Length(Bit[0])-1 do begin

B:= Bit[i,j].rgbtBlue + n;

G := Bit[i,j].rgbtGreen + n;

R := Bit[i,j].rgbtRed + n;

If B > 255 then B := 255;

If B <0 then B := 0;

If G > 255 then G := 255;

If G <0 then G := 0;

If R > 255 then R := 255;

If R <0 then R := 0;

Bit[i,j].rgbtBlue := B;

Bit[i,j].rgbtGreen := G;

Bit[i,j].rgbtRed := R;

end;

end;

end;

procedure TForm1.FormCreate(Sender: TObject);

var i,j :Integer;

begin

Bits := TBitmap.Create;

Bits.LoadFromFile(‘Test.bmp‘);

ReadPixel(Bits,Pix);

SetLength(PixA,Bits.Width,Bits.Height);

For i := 0 to Bits.Width-1 do begin

For j := 0 to Bits.Height-1 do begin

PixA[i,j] := Pix[i,j];

end;

end;

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

Bits.Free;

end;

procedure TForm1.PaintBox1Paint(Sender: TObject);

begin

PaintBox1.Canvas.Draw(0,0,Bits);

end;

procedure TForm1.scBChange(Sender: TObject);

var i,j : Integer;

begin

Caption := IntToStr(scB.Position) + ‘%‘;

For i := 0 to Bits.Width-1 do begin

For j := 0 to Bits.Height-1 do begin

Pix[i,j] := PixA[i,j];

end;

end;

BrightnessChange(Pix,scB.Position);

WritePixel(Bits,Pix);

PaintBox1.Canvas.Draw(0,0,Bits);

end;

end.

程序的运行结果如下。

亮度-50

原图

亮度+50

探究Delphi的图形处理 之十二 -- 浮雕效果 

  浮雕效果

浮雕效果的原理是将图像的每一个像素的颜色值与该像素斜下方的像素值的差的绝对值加上一个常数。这个常数决定了浮雕效果的亮度。程序3.7给出了浮雕效果的源代码。

程序3.7

unit Emboss;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, ComCtrls, StdCtrls, ExtCtrls;

type

TPixels = Array of array of TRGBTriple;

TfrmMain = class(TForm)

PaintBox1: TPaintBox;

Label1: TLabel;

scS: TTrackBar;

procedure FormCreate(Sender: TObject);

procedure FormDestroy(Sender: TObject);

procedure scSChange(Sender: TObject);

procedure PaintBox1Paint(Sender: TObject);

procedure PaintBox1Click(Sender: TObject);

private

procedure Emboss(Bit: TPixels; n: Integer);

{ Private declarations }

public

{ Public declarations }

end;

procedure WritePixel(Pic: TBitmap; tPix: TPixels);

procedure ReadPixel(Pic: Tbitmap; var tPix: TPixels);

var

frmMain: TfrmMain;

Bits : TBitmap;

PixA : TPixels;

Pix : TPixels;

implementation

{$R *.dfm}

procedure ReadPixel(Pic: Tbitmap; var tPix: TPixels);

Var PixPtr:PbyteArray;i,j,m:Integer;

begin

SetLength(tPix,Pic.Width,Pic.Height);

Pic.PixelFormat := pf24bit;

Pic.HandleType:=bmDIB;

For i :=0 to pic.Height-1 do begin

PixPtr:=Pic.ScanLine[i];

for  j:= 0 to pic.Width-1 do begin

m := j*3;

tPix[j,i].rgbtBlue:=PixPtr[m];

tPix[j,i].rgbtGreen := PixPtr[m+1];

tPix[j,i].rgbtRed := PixPtr[m+2];

end;

end;

end;

procedure WritePixel(Pic: TBitmap; tPix: TPixels);

var PixPtr:PByteArray;i,j,m:Integer;

begin

pic.PixelFormat := pf24bit;

pic.HandleType:=bmDIB;

Pic.Height := High(tPix[0])+1;

Pic.Width:= High(tPix)+1;

For i :=0 to pic.Height-1 do begin

PixPtr:=Pic.ScanLine[i];

for  j:= 0 to pic.Width-1 do begin

m := j*3;

PixPtr[M] := tPix[j,i].rgbtBlue;

PixPtr[m+1] := tPix[j,i].rgbtGreen;

PixPtr[m+2] := tPix[j,i].rgbtRed;

end;

end;

end;

procedure TFrmMain.Emboss(Bit: TPixels; n: Integer);

var i ,j :Integer;

R,G,B:Integer;

begin

For i := 0 to Length(Bit)-2 do begin

for j := 0 to Length(Bit[0])-2 do begin

B:= ABS(Bit[i,j].rgbtBlue-Bit[i+1,j+1].rgbtBlue) + n;    // 把当前像素值的

G := ABS(Bit[i,j].rgbtGreen-Bit[i+1,j+1].rgbtGreen) + n; // RGB分量设置为

R := ABS(Bit[i,j].rgbtRed-Bit[i+1,j+1].rgbtRed) + n;     // 当前像素值与下一个像素值的差的绝对值+系数n。

{如果像素值超过范围,设置像素值为0或255}

If B > 255 then B := 255;

If B <0 then B := 0;

If G > 255 then G := 255;

If G <0 then G := 0;

If R > 255 then R := 255;

If R <0 then R := 0;

Bit[i,j].rgbtBlue := B;

Bit[i,j].rgbtGreen := G;

Bit[i,j].rgbtRed := R;

end;

end;

end;

procedure TfrmMain.FormCreate(Sender: TObject);

var i,j:Integer;

begin

Bits := TBitmap.Create;

Bits.LoadFromFile(‘Test.bmp‘);

ReadPixel(Bits,Pix);

SetLength(PixA,Bits.Width,Bits.Height);

For i := 0 to Bits.Width-1 do begin

For j := 0 to Bits.Height-1 do begin

PixA[i,j] := Pix[i,j];

end;

end;

end;

procedure TfrmMain.FormDestroy(Sender: TObject);

begin

Bits.Free;

end;

procedure TfrmMain.scSChange(Sender: TObject);

var i,j:Integer;

begin

{我们在ScrollBar的Change事件中处理浮雕效果}

Caption := IntToStr(scS.Position);

{先将像素值复原}

For i := 0 to Bits.Width-1 do begin

For j := 0 to Bits.Height-1 do begin

Pix[i,j] := PixA[i,j];

end;

end;

Emboss(Pix,scS.Position);//调用浮雕效果处理过程。

WritePixel(Bits,Pix);

PaintBox1.Canvas.Draw(0,0,Bits); //显示结果。

end;

procedure TfrmMain.PaintBox1Paint(Sender: TObject);

begin

PaintBox1.Canvas.Draw(0,0,Bits);

end;

procedure TfrmMain.PaintBox1Click(Sender: TObject);

begin

WritePixel(Bits,PixA);

PaintBox1.Canvas.Draw(0,0,Bits);

end;

end.

下图是程序的运行结果。

原图

浮雕亮度 = 127

探究Delphi的图形处理 之十三 -- 马赛克效果 

  马赛克效果

马赛克效果的原理是,把图象分割成n*n的小块,把每一个区域中的所有像素值变为这个区域像素值的平均值即可。下面的程序段可以实现这种效果。这里调用了第二章给出的ReadPixel和WritePixel方法。

程序3.7

Procedure Mosic(const Bit: TBitmap;var n: Integer);

var R,G,B:Integer;

i,j,k,l : Integer;

Pix : TPixels;

nDiv : Integer;

nDivRs : Integer;

jP,jM,ip,im:Integer;

OpCount : Integer;

begin

ReadPixel(Bit,Pix);

if n mod 2 = 0 then n := n +1;

nDiv := n * n;

nDivRs := n;

I := 0 ;

While I<= Bit.Width-1 do begin

ip:= i + nDivRs;

im := i ;

if im < 0 then im := 0;

if ip > Bit.Width -1 then ip := Bit.Width-1;

j := 0;

While j <= Bit.Height-1 do begin

R:=0;

G:=0;

B:=0;

jP := j + nDivRs;

jM := j - nDivRs;

if Jp > bit.Height-1 then

jp := Bit.Height-1;

if jm <0 then jm :=0;

OpCount := (ip - im+1) *(jp-jm+1);

For k := im to Ip do  begin

For l := jm to jp do

begin

R := R + Pix[k,l].rgbtRed;

G := G + Pix[k,l].rgbtGreen;

B := B + Pix[k,l].rgbtBlue;

end;

end;

For k := im to Ip do  begin

For l := jm to jp do

begin

Pix[k,l].rgbtBlue := B div opCount;

Pix[k,l].rgbtGreen := G div opCount;

Pix[k,l].rgbtRed := R div  opCount;

end;

end;

j := j + n;

end;

i := i + n;

end;

WritePixel(Bit,Pix);

end;

以下是程序的运行结果。

原图

马赛克大小 = 25

Delphi GDI+ 图形处理(3)

图形处理 柔化和锐化处理相关推荐

  1. VC++ .Net 实例学习

    VC++.NET中添加由C#编译的DLL引用的方法 http://blog.csdn.net/much0726/article/details/4986627 关于VC.NET的资料网络上确实非常少, ...

  2. VC++和VC++.NET中与图像处理有关的几个概念、结构和类

    VC++和VC++.NET中与图像处理有关的几个概念.结构和类 最近一直在看VC++有关图像处理方面的书,终于把以前一直混淆的几个概念.结构和类弄清楚了,特整理如下.如有错误,请大家批评指正,不胜感激 ...

  3. C#图形处理系列(一)——最简单第一步:逆反处理、二值处理

    在本系列博文中,将介绍几种常见的图形处理算法.上文C#图片处理常见方法性能比较 中以彩色转灰色处理为例探讨了3中方法的性能,因此彩色转灰度处理就不再另做介绍. public enum DealType ...

  4. AI芯片结构目标图形处理

    AI芯片结构目标图形处理 AI chip architecture targets graph processing 东京--AI处理器设计师Blaize,原名ThinCI(发音为"Thin ...

  5. AI芯片体系结构目标图形处理

    AI芯片体系结构目标图形处理 AI chip architecture targets graph processing 可编程图形流处理器(GSP)能够执行"直接图形处理.片上任务图管理和 ...

  6. 图形处理(十二)拉普拉斯网格优化、最小二乘网格模型光顺

    看这篇博文前,请先参考我的另外一篇博文<图形处理(三)简单拉普拉斯网格变形-Siggraph 2004>学习拉普拉斯坐标的相关理论知识.这里要分享的paper,是通过拉普拉斯的方法实现三角 ...

  7. .NET Core跨平台图形处理库ImageSharp

    ImageSharp 是支持.NET Core跨平台图形处理库,ImageSharp是ImageProcessor 的.NET Core跨平台实现. ImageSharp 支持如下操作: 调整大小,裁 ...

  8. 数字图像处理课设图像的锐化_数字图像处理图像锐化处理.ppt

    数字图像处理图像锐化处理 4.7.2 灰度级到彩色转换 灰度级到彩色转换(例) 在HSI彩色空间的直方图均衡强度均衡处理没有改变图像的色调和饱和度值,但它的确影响了整体图像的彩色感观. 向量分量可以用 ...

  9. 计算机图形系统基本处理流程,计算机图形系统是进行图形处理的计算机系统-read.ppt...

    计算机图形系统是进行图形处理的计算机系统-read 2009 * 第2章 图形系统与图形生成 2.1 计算机图形系统构成 2.2 图形显示原理 2.3 基本图元生成原理 内容提要: 2009 * 2. ...

最新文章

  1. 腾讯offer是什么样子_记一次腾讯社招前端面试(已拿到offer入职)
  2. mysql 硬负载_为啥单机MySQL又遭遇瓶颈?MySQL主从复制替你解决单机问题
  3. IO多路复用之epoll总结
  4. HihoCoder - 1465 后缀自动机五·重复旋律8(后缀自动机)
  5. matlab tf离散,求matlab离散化程序对于一个二阶传函,求其在MATLAB中的离散化程序.抱歉,没办法写清楚传函表达式.我试试:Gp(...
  6. Java Code Geeks通过Twitter赠送了免费的Sublime Text Editor许可
  7. wps合并所有sheet页_WPS里面如何批量打印(WPS2019)
  8. [MySQL] MySQL x64 下载地址
  9. 第二阶段第八天站立会议
  10. eclipse下开发简单的Java Web Service
  11. ASP.NET MVC:实现我们自己的视图引擎
  12. 公司买的机器不能自己装系统,问对方几天没回一个字
  13. Python爬虫——下载韩寒博客文章
  14. python有效的变量名有哪些_python变量名有哪些
  15. 截止失真放大电路_每周经典电路分析:一个经典实际运放的内部电路分析(1)
  16. MonthCalendar的mousedown方法选择日期
  17. 分享一些Photoshop的教程电子档(pdf格式),初学者与设计师适用
  18. vim 编辑器 不小心点了crtl+s 终端停止输出问题
  19. Ubuntu 7.04 feisty 安装设置笔记
  20. 利用二维数组编程输出九九乘法表 ← C语言

热门文章

  1. 浅论高职院校的IT类专业的校企合作
  2. 我们参与投资36Kr股权众筹项目“易途8”的决策过程
  3. 中国计算机专业创始人,无怨无悔来时路――访计算机专业创始人吴忠明校友
  4. Jmeter压力测试案例
  5. 百度地图api离线开发(示例源代码)
  6. 【数据结构-链表】链表的相关算法
  7. Putty将公钥私钥文件改成ppk文件
  8. 如何做好项目工时管理?看这一篇就够了!
  9. PVS更新Vdisk大型环境中提升为测试版
  10. linux内核培训广州,嵌入式Linux驱动开发高级培训班-华清远见嵌入式培训中心