收获网页中验证码图片的url地址,获取网页中验证码图片的url地址

手续一:获取网页中验证码图片的url地址

手续一:获取网页中验证码图片的url地址

//浮雕
procedure
Emboss(SrcBmp,DestBmp:TBitmap;AzimuthChange:integer);overload;
var
  i, j, Gray, Azimuthvalue, R, G, B: integer;
  SrcRGB, SrcRGB1, SrcRGB2, DestRGB: pRGBTriple;
begin
  for i := 0 to SrcBmp.Height – 1 do
  begin
    SrcRGB := SrcBmp.ScanLine[i];
    DestRGB := DestBmp.ScanLine[i];

在delphi中参与一个BitBtn和一个memo以及WebBrowser控件完结网页中验证码图片的url地址的收获

在delphi中加入一个BitBtn和一个memo以及WebBrowser控件落成网页中验证码图片的url地址的得到

    if (AzimuthChange >= -180) and (AzimuthChange < -135) then
    begin
      if i > 0 then
        SrcRGB1 := SrcBmp.ScanLine[i-1]
      else
        SrcRGB1 := SrcRGB;
      Inc(SrcRGB1);
      SrcRGB2 := SrcRGB;
      Inc(SrcRGB2);
    end
    else if (AzimuthChange >= -135) and (AzimuthChange < -90)
then
    begin
      if i > 0 then
        SrcRGB1 := SrcBmp.ScanLine[i-1]
      else
        SrcRGB1 := SrcRGB;
      SrcRGB2 := SrcRGB1;
      Inc(SrcRGB2);
    end
    else if (AzimuthChange >= -90) and (AzimuthChange < -45)
then
    begin
      if i > 0 then
        SrcRGB1 := SrcBmp.ScanLine[i-1]
      else
        SrcRGB1 := SrcRGB;
      SrcRGB2 := SrcRGB1;
    end
    else if (AzimuthChange >= -45) and (AzimuthChange < 0) then
    begin
      SrcRGB1 := SrcRGB;
      if i > 0 then
        SrcRGB2 := SrcBmp.ScanLine[i-1]
      else
        SrcRGB2 := SrcRGB;
    end
    else if (AzimuthChange >= 0) and (AzimuthChange < 45) then
    begin
      SrcRGB2 := SrcRGB;
      if (i < SrcBmp.Height – 1) then
        SrcRGB1 := SrcBmp.ScanLine[i+1]
      else
        SrcRGB1 := SrcRGB;
    end
    else if (AzimuthChange >= 45) and (AzimuthChange < 90) then
    begin
      if (i < SrcBmp.Height – 1) then
        SrcRGB1 := SrcBmp.ScanLine[i+1]
      else
        SrcRGB1 := SrcRGB;
      SrcRGB2 := SrcRGB1;
    end
    else if (AzimuthChange >= 90) and (AzimuthChange < 135) then
    begin
      if (i < SrcBmp.Height – 1) then
        SrcRGB1 := SrcBmp.ScanLine[i+1]
      else
        SrcRGB1 := SrcRGB;
      SrcRGB2 := SrcRGB1;
      Inc(SrcRGB1);
    end
    else if (AzimuthChange >= 135) and (AzimuthChange <= 180)
then
    begin
      if (i < SrcBmp.Height – 1) then
        SrcRGB2 := SrcBmp.ScanLine[i+1]
      else
        SrcRGB2 := SrcRGB;
      Inc(SrcRGB2);
      SrcRGB1 := SrcRGB;
      Inc(SrcRGB1);
    end;

次第如下:
procedure TForm1.BitBtn1Click(Sender: TObject);

程序如下:
procedure TForm1.BitBtn1Click(Sender: TObject);

    for j := 0 to SrcBmp.Width – 1 do
    begin
      if (AzimuthChange >= -180) and (AzimuthChange < -135) then
      begin
        Azimuthvalue := AzimuthChange + 180;
        R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed)*Azimuthvalue div
45)-((SrcRGB2.rgbtRed)*(45-Azimuthvalue) div 45)+78;
        G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen)*Azimuthvalue div
45)-((SrcRGB2.rgbtGreen)*(45-Azimuthvalue) div 45)+78;
        B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue)*Azimuthvalue div
45)-((SrcRGB2.rgbtBlue)*(45-Azimuthvalue) div 45)+78;
      end
      else if (AzimuthChange >= -135) and (AzimuthChange < -90)
then
      begin
        Azimuthvalue := AzimuthChange + 135;
        R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed)*Azimuthvalue div
45)-((SrcRGB2.rgbtRed)*(45-Azimuthvalue) div 45)+78;
        G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen)*Azimuthvalue div
45)-((SrcRGB2.rgbtGreen)*(45-Azimuthvalue) div 45)+78;
        B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue)*Azimuthvalue div
45)-((SrcRGB2.rgbtBlue)*(45-Azimuthvalue) div 45)+78;
      end
      else if (AzimuthChange >= -90) and (AzimuthChange < -45)
then
      begin
        if j=1 then Inc(SrcRGB1,-1);
        Azimuthvalue := AzimuthChange + 90;
        R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed)*Azimuthvalue div
45)-((SrcRGB2.rgbtRed)*(45-Azimuthvalue) div 45)+78;
        G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen)*Azimuthvalue div
45)-((SrcRGB2.rgbtGreen)*(45-Azimuthvalue) div 45)+78;
        B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue)*Azimuthvalue div
45)-((SrcRGB2.rgbtBlue)*(45-Azimuthvalue) div 45)+78;
      end
      else if (AzimuthChange >= -45) and (AzimuthChange < 0)
then
      begin
        if j=1 then
        begin
          Inc(SrcRGB1,-1);
          Inc(SrcRGB2,-1);
        end;
        Azimuthvalue := AzimuthChange + 45;
        R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed)*Azimuthvalue div
45)-((SrcRGB2.rgbtRed)*(45-Azimuthvalue) div 45)+78;
        G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen)*Azimuthvalue div
45)-((SrcRGB2.rgbtGreen)*(45-Azimuthvalue) div 45)+78;
        B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue)*Azimuthvalue div
45)-((SrcRGB2.rgbtBlue)*(45-Azimuthvalue) div 45)+78;
      end
      else if (AzimuthChange >= 0) and (AzimuthChange < 45) then
      begin
        if j=1 then
        begin
          Inc(SrcRGB1,-1);
          Inc(SrcRGB2,-1);
        end;
        Azimuthvalue := AzimuthChange;
        R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed)*Azimuthvalue div
45)-((SrcRGB2.rgbtRed)*(45-Azimuthvalue) div 45)+78;
        G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen)*Azimuthvalue div
45)-((SrcRGB2.rgbtGreen)*(45-Azimuthvalue) div 45)+78;
        B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue)*Azimuthvalue div
45)-((SrcRGB2.rgbtBlue)*(45-Azimuthvalue) div 45)+78;
      end
      else if (AzimuthChange >= 45) and (AzimuthChange < 90)
then
      begin
        if j=1 then Inc(SrcRGB2,-1);
        Azimuthvalue := AzimuthChange – 45;
        R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed)*Azimuthvalue div
45)-((SrcRGB2.rgbtRed)*(45-Azimuthvalue) div 45)+78;
        G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen)*Azimuthvalue div
45)-((SrcRGB2.rgbtGreen)*(45-Azimuthvalue) div 45)+78;
        B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue)*Azimuthvalue div
45)-((SrcRGB2.rgbtBlue)*(45-Azimuthvalue) div 45)+78;
      end
      else if (AzimuthChange >= 90) and (AzimuthChange < 135)
then
      begin
        Azimuthvalue := AzimuthChange – 90;
        R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed)*Azimuthvalue div
45)-((SrcRGB2.rgbtRed)*(45-Azimuthvalue) div 45)+78;
        G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen)*Azimuthvalue div
45)-((SrcRGB2.rgbtGreen)*(45-Azimuthvalue) div 45)+78;
        B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue)*Azimuthvalue div
45)-((SrcRGB2.rgbtBlue)*(45-Azimuthvalue) div 45)+78;
      end
      else if (AzimuthChange >= 135) and (AzimuthChange <= 180)
then
      begin
        Azimuthvalue := AzimuthChange – 135;
        R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed)*Azimuthvalue div
45)-((SrcRGB2.rgbtRed)*(45-Azimuthvalue) div 45)+78;
        G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen)*Azimuthvalue div
45)-((SrcRGB2.rgbtGreen)*(45-Azimuthvalue) div 45)+78;
        B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue)*Azimuthvalue div
45)-((SrcRGB2.rgbtBlue)*(45-Azimuthvalue) div 45)+78;
      end;
      R:=Min(R,255);
      R:=Max(R,0);
      G:=Min(G,255);
      G:=Max(G,0);
      B:=Min(B,255);
      B:=Max(B,0);
      Gray := (R shr 2) + (R shr 4) + (G shr 1) + (G shr 4) + (B shr
3);
      DestRGB.rgbtRed:=Gray;
      DestRGB.rgbtGreen:=Gray;
      DestRGB.rgbtBlue:=Gray;
      if (j=-180) and (AzimuthChange<-135)) or
((AzimuthChange>=90) and (AzimuthChange<=180))) then
      begin
        Inc(SrcRGB1);
      end;
      if (j=135) and (AzimuthChange<180)) or
((AzimuthChange>=-180) and (AzimuthChange<=-90))) then
      begin
        Inc(SrcRGB2);
      end;
      Inc(SrcRGB);
      Inc(DestRGB);
    end;
  end;
end;

var

var

procedure
Emboss(Bmp:TBitmap;AzimuthChange:integer;ElevationChange:integer;WeightChange:integer);overload;
var
  DestBmp:TBitmap;
begin
  DestBmp:=TBitmap.Create;
  DestBmp.Assign(Bmp);
  Emboss(Bmp,DestBmp,AzimuthChange,ElevationChange,WeightChange);
  Bmp.Assign(DestBmp);
end;

  I:Integer;

  I:Integer;

//反色
procedure Negative(Bmp:TBitmap);
var
  i, j: Integer;
  PRGB: pRGBTriple;
begin
  Bmp.PixelFormat:=pf24Bit;
  for i := 0 to Bmp.Height – 1 do
  begin
    PRGB := Bmp.ScanLine[i];
    for j := 0 to Bmp.Width – 1 do
    begin
      PRGB^.rgbtRed :=not PRGB^.rgbtRed ;
      PRGB^.rgbtGreen :=not PRGB^.rgbtGreen;
      PRGB^.rgbtBlue :=not PRGB^.rgbtBlue;
      Inc(PRGB);
    end;
  end;
end;

begin

begin

//曝光
procedure Exposure(Bmp:TBitmap);
var
  i, j: integer;
  PRGB: pRGBTriple;
begin
  Bmp.PixelFormat:=pf24Bit;
  for i := 0 to Bmp.Height – 1 do
  begin
    PRGB := Bmp.ScanLine[i];
    for j := 0 to Bmp.Width – 1 do
    begin
      if PRGB^.rgbtRed<128 then
        PRGB^.rgbtRed :=not PRGB^.rgbtRed ;
      if PRGB^.rgbtGreen<128 then
        PRGB^.rgbtGreen :=not PRGB^.rgbtGreen;
      if PRGB^.rgbtBlue<128 then
        PRGB^.rgbtBlue :=not PRGB^.rgbtBlue;
      Inc(PRGB);
    end;
  end;
end;

  for I:=0 to WebBrowser1.OleObject.document.images.length-1 do

  for I:=0 to WebBrowser1.OleObject.document.images.length-1 do

//模糊
procedure Blur(SrcBmp:TBitmap);
var
  i, j:Integer;
  SrcRGB:pRGBTriple;
  SrcNextRGB:pRGBTriple;
  SrcPreRGB:pRGBTriple;
  Value:Integer;

    Memo1.Lines.Add(WebBrowser1.OleObject.document.images.item(i).href);

    Memo1.Lines.Add(WebBrowser1.OleObject.document.images.item(i).href);

  procedure IncRGB;
  begin
    Inc(SrcPreRGB);
    Inc(SrcRGB);
    Inc(SrcNextRGB);
  end;

end;

end;

  procedure DecRGB;
  begin
    Inc(SrcPreRGB,-1);
    Inc(SrcRGB,-1);
    Inc(SrcNextRGB,-1);
  end;

 步骤二:下载网页中验证码图片到image中 
在delphi中参预一个BitBtn和一个image以及WebBrowser控件,image用来显示下载的图纸
代码:
procedure TForm1.BitBtn5Click(Sender: TObject);
var
  i:Integer;
  rang:IHTMLControlRange;
  s:string;
begin
try
  s := (IHTMLDocument2(WebBrowser.Document).images.item(‘img_validatecode’,EmptyParam) as
IHTMLElement).getAttribute(‘src’,0);
  rang:=((IHTMLDocument2(WebBrowser.Document).body as
HTMLBody).createControlRange)as IHTMLControlRange;
  rang.add(IHTMLDocument2(WebBrowser.Document).images.item(‘img_validatecode’,EmptyParam)as
IHTMLControlElement);
  rang.execCommand(‘Copy’,False,0);
 
Image1.Picture.Assign(clipboard);//若为参与Clipbrd单元,编译时会提醒clipboard为定义
except
end;
end; 
注意:
1、在程序的uses中必须先参预ActiveX,Clipbrd单元,其中Clipbrd不投入会造成 clipboard未定义
2、img_validatecode 为网页验证码图片的id号,
3、上边代码为delphi WebBrowser中的通用代码,使用时只需修改id号和uses中
添加单元即可使用

 步骤二:下载网页中验证码图片到image中 
在delphi中参预一个BitBtn和一个image以及WebBrowser控件,image用来展现下载的图纸
代码:
procedure TForm1.BitBtn5Click(Sender: TObject);
var
  i:Integer;
  rang:IHTMLControlRange;
  s:string;
begin
try
  s := (IHTMLDocument2(WebBrowser.Document).images.item(‘img_validatecode’,EmptyParam) as
IHTMLElement).getAttribute(‘src’,0);
  rang:=((IHTMLDocument2(WebBrowser.Document).body as
HTMLBody).createControlRange)as IHTMLControlRange;
  rang.add(IHTMLDocument2(WebBrowser.Document).images.item(‘img_validatecode’,EmptyParam)as
IHTMLControlElement);
  rang.execCommand(‘Copy’,False,0);
 
Image1.Picture.Assign(clipboard);//若为参预Clipbrd单元,编译时会提示clipboard为定义
except
end;
end; 
注意:
1、在程序的uses中务必先投入ActiveX,Clipbrd单元,其中Clipbrd不进入会促成 clipboard未定义
2、img_validatecode 为网页验证码图片的id号,
3、上边代码为delphi WebBrowser中的通用代码,使用时只需修改id号和uses中
添加单元即可使用

begin
  SrcBmp.PixelFormat:=pf24Bit;
  for i := 0 to SrcBmp.Height – 1 do
  begin
    if i > 0 then
      SrcPreRGB:=SrcBmp.ScanLine[i-1]
    else
      SrcPreRGB := SrcBmp.ScanLine[i];
    SrcRGB := SrcBmp.ScanLine[i];
    if i < SrcBmp.Height – 1 then
      SrcNextRGB:=SrcBmp.ScanLine[i+1]
    else
      SrcNextRGB:=SrcBmp.ScanLine[i];
    for j := 0 to SrcBmp.Width – 1 do
    begin
      if j > 0 then DecRGB;
      Value:=SrcPreRGB.rgbtRed+SrcRGB.rgbtRed+SrcNextRGB.rgbtRed;
      if j > 0 then IncRGB;
     
Value:=Value+SrcPreRGB.rgbtRed+SrcRGB.rgbtRed+SrcNextRGB.rgbtRed;
      if j < SrcBmp.Width – 1 then IncRGB;
      Value:=(Value+SrcPreRGB.rgbtRed+SrcRGB.rgbtRed+SrcNextRGB.rgbtRed)
div 9;
      DecRGB;
      SrcRGB.rgbtRed:=value;
      if j > 0 then DecRGB;
     
Value:=SrcPreRGB.rgbtGreen+SrcRGB.rgbtGreen+SrcNextRGB.rgbtGreen;
      if j > 0 then IncRGB;
     
Value:=Value+SrcPreRGB.rgbtGreen+SrcRGB.rgbtGreen+SrcNextRGB.rgbtGreen;
      if j < SrcBmp.Width – 1 then IncRGB;
     
Value:=(Value+SrcPreRGB.rgbtGreen+SrcRGB.rgbtGreen+SrcNextRGB.rgbtGreen)
div 9;
      DecRGB;
      SrcRGB.rgbtGreen:=value;
      if j > 0 then DecRGB;
      Value:=SrcPreRGB.rgbtBlue+SrcRGB.rgbtBlue+SrcNextRGB.rgbtBlue;
      if j > 0 then IncRGB;
     
Value:=Value+SrcPreRGB.rgbtBlue+SrcRGB.rgbtBlue+SrcNextRGB.rgbtBlue;
      if j < SrcBmp.Width – 1 then IncRGB;
     
Value:=(Value+SrcPreRGB.rgbtBlue+SrcRGB.rgbtBlue+SrcNextRGB.rgbtBlue)
div 9;
      DecRGB;
      SrcRGB.rgbtBlue:=value;
      IncRGB;
    end;
  end;
end;

 步骤三:image图片的灰度处理   首先大家要求驾驭图片的灰度处理是将一些花团锦簇的验证码图片变成黑色图片方便图片的持续处理,那里有二种办法对图纸展开青色处理。
 方法一:求出RGB这个像素点的平均值,然后把平均值分给两个像素点;
 方法二:求每个像素点RGB三个轻重的最大值,然后把最大值分给多少个像素点;
 方法三:按照YUV的颜色空间,求出Y的值;
 方法一:
 代码: 
 procedure TForm1.BitBtn4Click(Sender: TObject);

 手续三:image图片的灰度处理   首先我们须求精晓图片的灰度处理是将有些多彩的验证码图片变成肉色图片方便图片的继续处理,那里有三种格局对图纸举办粉黑色处理。
 方法一:求出RGB那五个像素点的平均值,然后把平均值分给八个像素点;
 方法二:求每个像素点RGB三个轻重的最大值,然后把最大值分给多个像素点;
 方法三:根据YUV的颜色空间,求出Y的值;
 方法一:
 代码: 
 procedure TForm1.BitBtn4Click(Sender: TObject);

//锐化
procedure Sharpen(SrcBmp:TBitmap);
var
  i, j: integer;
  SrcRGB: pRGBTriple;
  SrcPreRGB: pRGBTriple;
  Value: integer;
begin
  SrcBmp.PixelFormat:=pf24Bit;
  for i := 0 to SrcBmp.Height – 1 do
  begin
    SrcRGB := SrcBmp.ScanLine[i];
    if i > 0 then
      SrcPreRGB:=SrcBmp.ScanLine[i-1]
    else
      SrcPreRGB:=SrcBmp.ScanLine[i];
    for j := 0 to SrcBmp.Width – 1 do
    begin
      if j = 1 then Dec(SrcPreRGB);
      Value:=SrcRGB.rgbtRed+(SrcRGB.rgbtRed-SrcPreRGB.rgbtRed) div 2;
      Value:=Max(0,Value);
      Value:=Min(255,Value);
      SrcRGB.rgbtRed:=value;
      Value:=SrcRGB.rgbtGreen+(SrcRGB.rgbtGreen-SrcPreRGB.rgbtGreen) div
2;
      Value:=Max(0,Value);
      Value:=Min(255,Value);
      SrcRGB.rgbtGreen:=value;
      Value:=SrcRGB.rgbtBlue+(SrcRGB.rgbtBlue-SrcPreRGB.rgbtBlue) div
2;
      Value:=Max(0,Value);
      Value:=Min(255,Value);
      SrcRGB.rgbtBlue:=value;
      Inc(SrcRGB);
      Inc(SrcPreRGB);
    end;
  end;
end;
 [图像的旋转和扭转]

var

var

以下代码用ScanLine协作指针移动已毕,用于24位色!

  p: pbyteArray;  //位指针

  p: pbyteArray;  //位指针

//旋转90度
procedure Rotate90(const Bitmap:TBitmap);
var
  i,j:Integer;
  rowIn,rowOut:pRGBTriple;
  Bmp:TBitmap;
  Width,Height:Integer;
begin
  Bmp:=TBitmap.Create;
  Bmp.Width := Bitmap.Height;
  Bmp.Height := Bitmap.Width;
  Bmp.PixelFormat := pf24bit;
  Width:=Bitmap.Width-1;
  Height:=Bitmap.Height-1;
  for  j := 0 to Height do
  begin
    rowIn  := Bitmap.ScanLine[j];
    for i := 0 to Width do
    begin
      rowOut := Bmp.ScanLine[i];
      Inc(rowOut,Height – j);
      rowOut^ := rowIn^;
      Inc(rowIn);
    end;
  end;
  Bitmap.Assign(Bmp);
end;

  x,y: integer;//x宽,y高

  x,y: integer;//x宽,y高

//旋转180度
procedure Rotate180(const Bitmap:TBitmap);
var
  i,j:Integer;
  rowIn,rowOut:pRGBTriple;
  Bmp:TBitmap;
  Width,Height:Integer;
begin
  Bmp:=TBitmap.Create;
  Bmp.Width := Bitmap.Width;
  Bmp.Height := Bitmap.Height;
  Bmp.PixelFormat := pf24bit;
  Width:=Bitmap.Width-1;
  Height:=Bitmap.Height-1;
  for  j := 0 to Height do
  begin
    rowIn  := Bitmap.ScanLine[j];
    for i := 0 to Width do
    begin
      rowOut := Bmp.ScanLine[Height – j];
      Inc(rowOut,Width – i);
      rowOut^ := rowIn^;
      Inc(rowIn);
    end;
  end;
  Bitmap.Assign(Bmp);
end;

  Bmp: TBitmap;//位图组件(TBitMap)

  Bmp: TBitmap;//位图组件(TBitMap)

//旋转270度
procedure Rotate270(const Bitmap:TBitmap);
var
  i,j:Integer;
  rowIn,rowOut:pRGBTriple;
  Bmp:TBitmap;
  Width,Height:Integer;
begin
  Bmp:=TBitmap.Create;
  Bmp.Width := Bitmap.Height;
  Bmp.Height := Bitmap.Width;
  Bmp.PixelFormat := pf24bit;
  Width:=Bitmap.Width-1;
  Height:=Bitmap.Height-1;
  for  j := 0 to Height do
  begin
    rowIn  := Bitmap.ScanLine[j];
    for i := 0 to Width do
    begin
      rowOut := Bmp.ScanLine[Width – i];
      Inc(rowOut,j);
      rowOut^ := rowIn^;
      Inc(rowIn);
    end;
  end;
  Bitmap.Assign(Bmp);
end;

  Gray: integer;//灰度值

  Gray: integer;//灰度值

//任意角度
function
RotateBitmap(Bitmap:TBitmap;Angle:Integer;BackColor:TColor):TBitmap;
var
  i,j,iOriginal,jOriginal,CosPoint,SinPoint : integer;
  RowOriginal,RowRotated : pRGBTriple;
  SinTheta,CosTheta : Extended;
  AngleAdd : integer;
begin
  Result:=TBitmap.Create;
  Result.PixelFormat := pf24bit;
  Result.Canvas.Brush.Color:=BackColor;
  Angle:=Angle Mod 360;
  if Angle<0 then Angle:=360-Abs(Angle);
  if Angle=0 then
    Result.Assign(Bitmap)
  else if Angle=90 then
  begin
    Result.Assign(Bitmap);
    Rotate90(Result);//要是是旋转90度,直接调用上边的代码
  end
  else if (Angle>90) and (Angle<180) then
  begin
    AngleAdd:=90;
    Angle:=Angle-AngleAdd;
  end
  else if Angle=180 then
  begin
    Result.Assign(Bitmap);
    Rotate180(Result);//假如是旋转180度,直接调用上边的进程
  end
  else if (Angle>180) and (Angle<270) then
  begin
    AngleAdd:=180;
    Angle:=Angle-AngleAdd;
  end
  else if Angle=270 then
  begin
    Result.Assign(Bitmap);
    Rotate270(Result);//即使是旋转270度,直接调用上边的历程
  end
  else if (Angle>270) and (Angle<360) then
  begin
    AngleAdd:=270;
    Angle:=Angle-AngleAdd;
  end
  else
    AngleAdd:=0;
  if (Angle>0) and (Angle<90) then
  begin
  SinCos((Angle + AngleAdd) * Pi / 180, SinTheta, CosTheta);
  if (SinTheta * CosTheta) < 0 then
  begin
    Result.Width := Round(Abs(Bitmap.Width * CosTheta – Bitmap.Height
* SinTheta));
    Result.Height := Round(Abs(Bitmap.Width * SinTheta – Bitmap.Height
* CosTheta));
  end
  else
  begin
    Result.Width := Round(Abs(Bitmap.Width * CosTheta + Bitmap.Height
* SinTheta));
    Result.Height := Round(Abs(Bitmap.Width * SinTheta + Bitmap.Height
* CosTheta));
  end;
  CosTheta:=Abs(CosTheta);
  SinTheta:=Abs(SinTheta);
  if (AngleAdd=0) or (AngleAdd=180) then
  begin
    CosPoint:=Round(Bitmap.Height*CosTheta);
    SinPoint:=Round(Bitmap.Height*SinTheta);
  end
  else
  begin
    SinPoint:=Round(Bitmap.Width*CosTheta);
    CosPoint:=Round(Bitmap.Width*SinTheta);
  end;
  for j := 0 to Result.Height-1 do
  begin
    RowRotated := Result.Scanline[j];
    for i := 0 to Result.Width-1 do
    begin
      Case AngleAdd of
        0:
        begin
          jOriginal :=
Round((j+1)*CosTheta-(i+1-SinPoint)*SinTheta)-1;
          iOriginal :=
Round((i+1)*CosTheta-(CosPoint-j-1)*SinTheta)-1;
        end;
        90:
        begin
          iOriginal :=
Round((j+1)*SinTheta-(i+1-SinPoint)*CosTheta)-1;
          jOriginal :=
Bitmap.Height-Round((i+1)*SinTheta-(CosPoint-j-1)*CosTheta);
        end;
        180:
        begin
          jOriginal :=
Bitmap.Height-Round((j+1)*CosTheta-(i+1-SinPoint)*SinTheta);
          iOriginal :=
Bitmap.Width-Round((i+1)*CosTheta-(CosPoint-j-1)*SinTheta);
        end;
        270:
        begin
          iOriginal :=
Bitmap.Width-Round((j+1)*SinTheta-(i+1-SinPoint)*CosTheta);
          jOriginal :=
Round((i+1)*SinTheta-(CosPoint-j-1)*CosTheta)-1;
        end;
      end;
      if (iOriginal >= 0) and (iOriginal <= Bitmap.Width-1)and
         (jOriginal >= 0) and (jOriginal <= Bitmap.Height-1)
      then
      begin
        RowOriginal := Bitmap.Scanline[jOriginal];
        Inc(RowOriginal,iOriginal);
        RowRotated^ := RowOriginal^;
        Inc(RowRotated);
      end
      else
      begin
        Inc(RowRotated);
      end;
    end;
  end;
  end;
end;

begin

begin

//水平翻转
procedure FlipHorz(const Bitmap:TBitmap);
var
  i,j:Integer;
  rowIn,rowOut:pRGBTriple;
  Bmp:TBitmap;
  Width,Height:Integer;
begin
  Bmp:=TBitmap.Create;
  Bmp.Width := Bitmap.Width;
  Bmp.Height := Bitmap.Height;
  Bmp.PixelFormat := pf24bit;
  Width:=Bitmap.Width-1;
  Height:=Bitmap.Height-1;
  for  j := 0 to Height do
  begin
    rowIn  := Bitmap.ScanLine[j];
    for i := 0 to Width do
    begin
      rowOut := Bmp.ScanLine[j];
      Inc(rowOut,Width – i);
      rowOut^ := rowIn^;
      Inc(rowIn);
    end;
  end;
  Bitmap.Assign(Bmp);
end;

  Bmp := TBitmap.Create;//建立一个TBitmap

  Bmp := TBitmap.Create;//建立一个TBitmap

//垂直翻转
procedure FlipVert(const Bitmap:TBitmap);
var
  i,j:Integer;
  rowIn,rowOut:pRGBTriple;
  Bmp:TBitmap;
  Width,Height:Integer;
begin
  Bmp:=TBitmap.Create;
  Bmp.Width := Bitmap.Height;
  Bmp.Height := Bitmap.Width;
  Bmp.PixelFormat := pf24bit;
  Width:=Bitmap.Width-1;
  Height:=Bitmap.Height-1;
  for  j := 0 to Height do
  begin
    rowIn  := Bitmap.ScanLine[j];
    for i := 0 to Width do
    begin
      rowOut := Bmp.ScanLine[Height – j];
      Inc(rowOut,i);
      rowOut^ := rowIn^;
      Inc(rowIn);
    end;
  end;
  Bitmap.Assign(Bmp);
end;

  Bmp.Assign(Form1.Image1.Picture.Bitmap);//将image图片转为位图情势

  Bmp.Assign(Form1.Image1.Picture.Bitmap);//将image图片转为位图形式

[亮度、比较度、饱和度的调整]

  Bmp.PixelFormat := pf24bit; //设为24位之彩色位图,PixelFormat 为位图的内存格式和颜料深浅,总共9个值

  Bmp.PixelFormat := pf24bit; //设为24位之彩色位图,PixelFormat 为位图的内存格式和颜色深浅,总共9个值

以下代码用ScanLine合作指针移动完毕!

  for y := 0 to Bmp.Height-1 do

  for y := 0 to Bmp.Height-1 do

function Min(a, b: integer): integer;
begin
  if a < b then
    result := a
  else
    result := b;
end;

  begin

  begin

function Max(a, b: integer): integer;
begin
  if a > b then
    result := a
  else
    result := b;
end;

    p :=Bmp.ScanLine[y];//ScanLine方法用于获取像素颜色值

    p :=Bmp.ScanLine[y];//ScanLine方法用于获取像素颜色值

//亮度调整
procedure BrightnessChange(const
SrcBmp,DestBmp:TBitmap;ValueChange:integer);
var
  i, j: integer;
  SrcRGB, DestRGB: pRGBTriple;
begin
  for i := 0 to SrcBmp.Height – 1 do
  begin
    SrcRGB := SrcBmp.ScanLine[i];
    DestRGB := DestBmp.ScanLine[i];
    for j := 0 to SrcBmp.Width – 1 do
    begin
      if ValueChange > 0 then
      begin
        DestRGB.rgbtRed := Min(255, SrcRGB.rgbtRed + ValueChange);
        DestRGB.rgbtGreen := Min(255, SrcRGB.rgbtGreen + ValueChange);
        DestRGB.rgbtBlue := Min(255, SrcRGB.rgbtBlue + ValueChange);
      end else begin
        DestRGB.rgbtRed := Max(0, SrcRGB.rgbtRed + ValueChange);
        DestRGB.rgbtGreen := Max(0, SrcRGB.rgbtGreen + ValueChange);
        DestRGB.rgbtBlue := Max(0, SrcRGB.rgbtBlue + ValueChange);
      end;
      Inc(SrcRGB);
      Inc(DestRGB);
    end;
  end;
end;

    for x:=0 to Bmp.Width-1 do

    for x:=0 to Bmp.Width-1 do

//比较度调整
procedure ContrastChange(const
SrcBmp,DestBmp:TBitmap;ValueChange:integer);
var
  i, j: integer;
  SrcRGB, DestRGB: pRGBTriple;
begin
  for i := 0 to SrcBmp.Height – 1 do
  begin
    SrcRGB := SrcBmp.ScanLine[i];
    DestRGB := DestBmp.ScanLine[i];
    for j := 0 to SrcBmp.Width – 1 do
    begin
      if ValueChange>=0 then
      begin
      if SrcRGB.rgbtRed >= 128 then
        DestRGB.rgbtRed := Min(255, SrcRGB.rgbtRed + ValueChange)
      else
        DestRGB.rgbtRed := Max(0, SrcRGB.rgbtRed – ValueChange);
      if SrcRGB.rgbtGreen >= 128 then
        DestRGB.rgbtGreen := Min(255, SrcRGB.rgbtGreen + ValueChange)
      else
        DestRGB.rgbtGreen := Max(0, SrcRGB.rgbtGreen – ValueChange);
      if SrcRGB.rgbtBlue >= 128 then
        DestRGB.rgbtBlue := Min(255, SrcRGB.rgbtBlue + ValueChange)
      else
        DestRGB.rgbtBlue := Max(0, SrcRGB.rgbtBlue – ValueChange);
      end
      else
      begin
      if SrcRGB.rgbtRed >= 128 then
        DestRGB.rgbtRed := Max(128, SrcRGB.rgbtRed + ValueChange)
      else
        DestRGB.rgbtRed := Min(128, SrcRGB.rgbtRed – ValueChange);
      if SrcRGB.rgbtGreen >= 128 then
        DestRGB.rgbtGreen := Max(128, SrcRGB.rgbtGreen + ValueChange)
      else
        DestRGB.rgbtGreen := Min(128, SrcRGB.rgbtGreen – ValueChange);
      if SrcRGB.rgbtBlue >= 128 then
        DestRGB.rgbtBlue := Max(128, SrcRGB.rgbtBlue + ValueChange)
      else
        DestRGB.rgbtBlue := Min(128, SrcRGB.rgbtBlue – ValueChange);
      end;
      Inc(SrcRGB);
      Inc(DestRGB);
    end;
  end;
end;

    begin

    begin

//饱和度调整
procedure SaturationChange(const
SrcBmp,DestBmp:TBitmap;ValueChange:integer);
var 
  Grays: array[0..767] of Integer;
  Alpha: array[0..255] of Word;
  Gray, x, y: Integer;
  SrcRGB,DestRGB: pRGBTriple;
  i: Byte;
begin
ValueChange:=ValueChange+255;
for i := 0 to 255 do
  Alpha[i] := (i * ValueChange) Shr 8;
x := 0;
for i := 0 to 255 do
begin 
  Gray := i – Alpha[i];
  Grays[x] := Gray;
  Inc(x);
  Grays[x] := Gray;
  Inc(x);
  Grays[x] := Gray;
  Inc(x);
end; 
for y := 0 to SrcBmp.Height – 1 do
begin
  SrcRGB := SrcBmp.ScanLine[Y];
  DestRGB := DestBmp.ScanLine[Y];
  for x := 0 to SrcBmp.Width – 1 do
  begin
    Gray := Grays[SrcRGB.rgbtRed + SrcRGB.rgbtGreen +
SrcRGB.rgbtBlue];
    if Gray + Alpha[SrcRGB.rgbtRed]>0 then
      DestRGB.rgbtRed := Min(255,Gray + Alpha[SrcRGB.rgbtRed])
    else
      DestRGB.rgbtRed := 0;
    if Gray + Alpha[SrcRGB.rgbtGreen]>0 then
      DestRGB.rgbtGreen := Min(255,Gray + Alpha[SrcRGB.rgbtGreen])
    else
      DestRGB.rgbtGreen := 0;
    if Gray + Alpha[SrcRGB.rgbtBlue]>0 then
      DestRGB.rgbtBlue := Min(255,Gray + Alpha[SrcRGB.rgbtBlue])
    else
      DestRGB.rgbtBlue := 0;
    Inc(SrcRGB);
    Inc(DestRGB);
  end;
end; 
end;

      Gray:=(p[3*x+2]+p[3*x+1]+p[3*x]) div
3;//3处像素点的平均值

      Gray:=(p[3*x+2]+p[3*x+1]+p[3*x]) div
3;//3处像素点的平均值

//RGB调整
procedure
RGBChange(SrcBmp,DestBmp:TBitmap;RedChange,GreenChange,BlueChange:integer);
var
  SrcRGB, DestRGB: pRGBTriple;
  i,j:integer;
begin
  for i := 0 to SrcBmp.Height- 1 do
  begin
    SrcRGB := SrcBmp.ScanLine[i];
    DestRGB :=DestBmp.ScanLine[i];
    for j := 0 to SrcBmp.Width – 1 do
    begin
      if RedChange> 0 then
        DestRGB.rgbtRed := Min(255, SrcRGB.rgbtRed + RedChange)
      else
        DestRGB.rgbtRed := Max(0, SrcRGB.rgbtRed + RedChange);

      p[3*x+2]:=byte(Gray);

      p[3*x+2]:=byte(Gray);

      if GreenChange> 0 then
        DestRGB.rgbtGreen := Min(255, SrcRGB.rgbtGreen + GreenChange)
      else
        DestRGB.rgbtGreen := Max(0, SrcRGB.rgbtGreen + GreenChange);

      p[3*x+1]:=byte(Gray);

      p[3*x+1]:=byte(Gray);

      if BlueChange> 0 then
        DestRGB.rgbtBlue := Min(255, SrcRGB.rgbtBlue + BlueChange)
      else
        DestRGB.rgbtBlue := Max(0, SrcRGB.rgbtBlue + BlueChange);
      Inc(SrcRGB);
      Inc(DestRGB);
    end;
  end;
end;

      p[3*x]:=byte(Gray);

      p[3*x]:=byte(Gray);

[水豫剧整]

    end;

    end;

//RGB<=>BGR
procedure RGB2BGR(const Bitmap:TBitmap);
var 
  X: Integer; 
  Y: Integer;
  PRGB: pRGBTriple;
  Color: Byte;
begin
  for Y := 0 to (Bitmap.Height – 1) do
  begin
    for X := 0 to (Bitmap.Width – 1) do
    begin
      Color := PRGB^.rgbtRed;
      PRGB^.rgbtRed := PRGB^.rgbtBlue;
      PRGB^.rgbtBlue := Color;
      Inc(PRGB);
    end;
    end
  end;
end;

  end;

  end;

//灰度化(加权)
procedure Grayscale(const Bitmap:TBitmap);
var 
  X: Integer; 
  Y: Integer; 
  PRGB: pRGBTriple;
  Gray: Byte;
begin
  for Y := 0 to (Bitmap.Height – 1) do
  begin
    PRGB := Bitmap.ScanLine[Y];
    for X := 0 to (Bitmap.Width – 1) do
    begin
      Gray := (77 * Red + 151 * Green + 28 * Blue) shr 8;
      PRGB^.rgbtRed:=Gray;
      PRGB^.rgbtGreen:=Gray;
      PRGB^.rgbtBlue:=Gray;
      Inc(PRGB);
    end;
  end;
end;

  image4.Picture.Bitmap := Bmp;

  image4.Picture.Bitmap := Bmp;

理论篇:
关键词:
绘图区-即窗口显示图像的区域,亦可为全屏幕(在全显示器下绘图的作用比相似窗口下好)
主题点-即要绘图区突显的主干点在原有图像的坐标(讲明:这些定义更加重大)
  先说说图像的松开,要松开一张图片,大家一般的做法是一向放大图像,但本文介绍的不二法门仅放大我们可以看出的片段,放大分二种情状,一种是加大后比绘图区还要小,那种气象没什么好说,当然是显得整个的图像;第二种是拓宽后的图像比绘图区大,那才是大家明天要探究的要害话题,那种情况下我们先要确定图像放大后的深浅,然后按照“中央点”总计在原来图像的职位和分寸,最后把截取的图像放大到绘图区。
  再说说图像的畅游,当突显的图像超越绘图区时,我们要求对图像进行旅游,以便看到任何的图像。原理是:当鼠标在绘图区举办单击时,那时发轫漫游,先记下鼠标的单击地方,然后检测鼠标的移动,根据鼠标和上次的位移总计出“主旨点”(须求将显示器坐标转换为本来图像坐标),按照在上头放大的法则到原有图像中取出要出示的一部分,放大展现到绘图区。
算法落成篇:
1.图像放大
变量定义:
PZoom:放大率(整数:100时为100%,按照必要可以将 100 该为 10000
或者更大些,但不推荐使用浮点数)
a,b:中心点
w,h:要截取原始图像的宽和高
x,y:要截取的岗位(左上角)
sw,sh:原始图像的宽和高
p1,p2:放大比例
aw,ah:放大后图像的高低
pw,ph:绘图区大小
vx,vy:在绘图区展现的职责(左上角)
vw,vh:在绘图区彰显的尺寸
ptx,pty:临时变量
已知的变量:PZoom,(a,b),(sw,sh),(p1,p2),(aw,ah),(pw,ph)
要计算的变量:(x,y),(w,h),(vx,vy),(vw,vh)
千帆竞发总括:
aw=Round(PZoom*sw/100);
ah=Round(PZoom*sh/100);
p1=aw/pw
p2=ah/ph
// 注:Round 用于取整,如其余语言的Int(),Fix()等
if p1>1 then w=Round(sw/p1) else w=sw
if p2>1 then h=Round(sh/p2) else h=sh
// 注:shr 为右移运算符,可以拔取“>>1”、“div
2”、“\2”或“Round(w/2)”代替
x=a-w shr 1
y=b-h shr 1
// 注:div 为整除运算符
ptx=(w*PZoom) div 100
pty=(h*PZoom) div 100
// 以下总结在绘图区突显的图像大小和职位
变量
    Pencent:double;  // 缩放比
    wx:double;       // 宽缩放比
    hx:double;       // 高缩放比
    // 获得缩放比
    wx:=pw/ptx
    hx:=ph/pty
    if wx>hx then Pencent:=hx
    else          Pencent:=wx;
    // 得到图片最终的分寸
    vw:=Round(Pencent*ptx);
    vh:=Round(Pencent*pty);
    // 总计出图片的岗位
    vx:=(pw-vw) div 2;
    vy:=(ph-vh) div 2;
// ————————————
好了,多个重点的天职成功(x,y),(w,h),(vx,vy),(vw,vh)已经全体总计得出,上边的做事就是体现了,我们选择Windows API 举行操作
// 以下呈现图像 ———————–
变量
sDC 为原本图片的装备句柄(DC)
tDC 为临时设备句柄
dDC 最终装备句柄
BitBlt(tDC,0,0,w,h,sDC,0,0,SRCCOPY);
SetStretchBltMode(dDC,STRETCH_DELETESCANS);
StretchBlt(dDC,0,0,vw,vh,tDC,0,0,w,h,SRCCOPY);
末尾绘制到体现的区域即可:
例如:BitBlt(GetDC(0),vx,vy,vx+vw,xy+vh,dDC,0,0,SRCCOPY);
// ————————————
2.图像遨游
先定义多个全局变量:
FBeginDragPoint   :TPoint;         // 记录鼠标初始拖动的任务
FBeginDragSBPoint :TPoint;         // 记录“中心点”位置
FBeginDrag        :boolean;        // 是或不是曾经开始“拖动”
a,b               :integer;        // “中心点”位置
在鼠标左键点击时,记录鼠标的职位和“中央点”的地点,同时安装 FBeginDrag
为真
当鼠标右键弹起时,设置 FBeginDrag 为假
鼠标移动时,判断 FBeginDrag
,假诺为假不开展处理,假如为真举行上边处理:
如若 X,Y 为鼠标当前的岗位
a=FBeginDragPoint.X-((X-FBeginDragPoint.X)*100) div PZoom
b=FBeginDragPoint.Y-((Y-FBeginDragPoint.Y)*100) div PZoom
最终动用方面介绍的图像放大彰显出图像
技巧篇:
1.只要图像较大,使用 delphi 的
位图对象会油但是生内存溢出荒谬,那时可以开展如下设置:
    bitImage:=TBitmap.Create;
    bitImage.PixelFormat:=pf24bit;
    bitImage.ReleaseHandle;
2.比方要让图像自动适应窗口的大小,参考以下代码:
var
    p1,p2       :double;
begin
    p1:=pw/sw;
    p2:=ph/sw;
    if p1>p2 then PZoom:=Round(p2*100)
    else          PZoom:=Round(p1*100);
    if PZoom=0 then PZoom:=100;
end;

  Bmp.Free;//释放TBitmap

  Bmp.Free;//释放TBitmap

Delphi灰度图像像素颜色亮度处理
  在图像处理中,速度是很重大的。因而,我们得重新处理一下TBitmap,得到电视机czhBitmap。那只是因为GetPixels和SetPixels的进程太慢,换一个方法而已。
  unit untBitmapProc;
  interface
  uses Graphics, SysUtils;
  type
  TVczhBitmap=class(TBitmap)
  private
  Data:PByteArray;
  Line:Integer;
  procedure SetFormat;
  function GetBytePointer(X,Y:Integer):PByte;
  procedure SetBytes(X,Y:Integer;Value:Byte);
  function GetBytes(X,Y:Integer):Byte;
  protected
  published
  constructor Create;
  public
  property Bytes[X,Y:Integer]:Byte read GetBytes write SetBytes;
  procedure LoadFromFile(FileName:String);
  procedure ToGray;
  end;
  implementation
  procedure TVczhBitmap.SetFormat;
  begin
  HandleType:=bmDIB;
  PixelFormat:=pf24bit;
  end;
  function TVczhBitmap.GetBytePointer(X,Y:Integer):PByte;
  begin
  if Line<>Y then
  begin
  Line:=Y;
  Data:=ScanLine[Y];
  end;
  Longint(result):=Longint(Data)+X;
  end;
  procedure TVczhBitmap.SetBytes(X,Y:Integer;Value:Byte);
  begin
  GetBytePointer(X,Y)^:=Value;
  end;
  function TVczhBitmap.GetBytes(X,Y:Integer):Byte;
  begin
  result:=GetBytePointer(X,Y)^;
  end;
  constructor TVczhBitmap.Create;
  begin
  inherited Create;
  SetFormat;
  Line:=-1;
  end;
  procedure TVczhBitmap.LoadFromFile(FileName:String);
  begin
  inherited LoadFromFile(FileName);
  SetFormat;
  Line:=-1;
  end;
  procedure TVczhBitmap.ToGray;
  var X,Y,R:Integer;
  B:Byte;
  begin
  for Y:=0 to Height-1 do
  for X:=0 to Width-1 do
  begin
  R:=0;
  for B:=0 to 2 do
  R:=R+GetBytes(X*3+B,Y);
  for B:=0 to 2 do
  SetBytes(X*3+B,Y,R div 3);
  end;
  end;
  end.
  此后,大家要求树立多少个窗体。首个用来显示图片,第三个用来拍卖图片,其他的窗体都无冕自第一个窗体,包罗实际的拍卖措施。
  先看第一个窗口:
  unit untProc;
  interface
  uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
  Dialogs, ExtCtrls, untBitmapProc, StdCtrls, ComCtrls;
  type
  TfrmProcessor = class(TForm)
  pbBar: TPaintBox;
  gpProc: TGroupBox;
  Button1: TButton;
  procedure FormCreate(Sender: TObject);
  procedure FormDestroy(Sender: TObject);
  procedure FormShow(Sender: TObject);
  procedure pbBarPaint(Sender: TObject);
  procedure Button1Click(Sender: TObject);
  private
  { Private declarations }
  public
  { Public declarations }
  BarData:array[0..255]of Byte;
  Bar:TVczhBitmap;
  procedure DrawBar;
  end;
  var
  frmProcessor: TfrmProcessor;
  implementation
  {$R *.dfm}
  uses untViewer;
  procedure TfrmProcessor.DrawBar;
  var I:Integer;
  begin
  Bar.Canvas.FillRect(Bar.Canvas.ClipRect);
  Bar.Canvas.MoveTo(0,255-BarData[0]);
  for I:=1 to 255 do
  Bar.Canvas.LineTo(I,255-BarData[I]);
  end;
  procedure TfrmProcessor.FormCreate(Sender: TObject);
  begin
  Bar:=TVczhBitmap.Create;
  Bar.Width:=256;
  Bar.Height:=256;
  Bar.Canvas.Brush.Color:=clWhite;
  Bar.Canvas.Brush.Style:=bsSolid;
  end;
  procedure TfrmProcessor.FormDestroy(Sender: TObject);
  begin
  Bar.Free;
  end;
  procedure TfrmProcessor.FormShow(Sender: TObject);
  var I:Integer;
  begin
  for I:=0 to 255 do
  BarData[I]:=I;
  DrawBar;
  end;
  procedure TfrmProcessor.pbBarPaint(Sender: TObject);
  begin
  pbBar.Canvas.Draw(0,0,Bar);
  end;
  procedure TfrmProcessor.Button1Click(Sender: TObject);
  var X,Y:Integer;
  begin
  for Y:=0 to Buffer.Height-1 do
  for X:=0 to Buffer.Width*3-1 do
  Played.Bytes[X,Y]:=BarData[Buffer.Bytes[X,Y]];
  frmViewer.FormPaint(frmViewer);
  end;
  end.
  之后,做一个窗口继承自它,则调整BarData[]后,按Apply即可知到结果。
  现在起始将图像处理。具体职能见示例程序。
  
  一、颜色反转。
  灰度图像的颜料都是从0~255,所以,为了使颜色反转,大家得以用255减去该颜色值以赢得反转后的水彩。
  var I:Integer;
  begin
  inherited;
  for I:=0 to 255 do
  BarData[I]:=255-I;//用255减去该颜色值
  DrawBar;
  pbBarPaint(pbBar);
  end;
  
  二、减弱颜色范围以夯实或裁减亮度
  颜色本来是从0~255的。若是调试它的限定,例如从0~16,则会是图像显著变暗。我们能够把初步值设为a,把终止值设为b,则新的颜色值New=a+(b-1)*Old/255。这样做的话可以改变亮度,并且不会损坏原先颜色的逐一。代码如下
  var I:Integer;
  begin
  for I:=0 to 255 do
  BarData[I]:=(255-sbMin.Position)+Round((sbMin.Position-sbMax.Position)/255*I);
  DrawBar;
  pbBarPaint(pbBar);
  Button1Click(Button1);
  end;
  那里的sbMin.Position和sb马克斯Position都是反转过的。所以使用时要用255去减
  
  三、扩展某个范围内的水彩范围
  如果图像本身的水彩范围很小的画,你可以因此那种措施来加大图像的对比度,有利于对图像的分析。具体做法:
  选拔一个值a做为初叶值,选择一个值b做为终止值,然后按以下公式变形:
  | 0 (X<=a)
  f(X)= | 255/(b-a)*(X-a)
  | 255(X>=b)
  var I:Integer;
  begin
  for I:=0 to 255 do
  begin
  if I<=sbMin.Position then
  BarData[I]:=0
  else if I>=sbMax.Position then
  BarData[I]:=255
  else
  BarData[I]:=Round(255/(sbMax.Position-sbMin.Position)*(I-sbMin.Position));
  end;
  DrawBar;
  pbBarPaint(pbBar);
  Button1Click(Button1);
  end;
  
  四、变为黑白图片
  在利用第几个职能的时候,你会发觉当b<=a时,图像上的颜料除了灰色就是反革命。那样操作的功利是无法平昔体现出来的。那只要到了比较高级的图像处理如边缘检测等,才有功力。本例可以拿第三种方法的公式再变形,因而不作详细演说。
  
  五、指数级亮度调整
   
 

end;
原图:    图片 1
处理后:图片 2 

end;
原图:    图片 3
处理后:图片 4 

  大家只要这些图的定义域是[0,1],值域也是[0,1]。那么,定义函数f(x)=x^c,则f(x)的图像有一段如上图。大家再用鼠标操作时,可以在上面取一点P(a,b),然后使f(x)透过点P,则c=ln(b)/ln(a)。有了c之后,我们就足以对颜色举行操作了:
  New=(Old/255)^c*255=exp(ln(old/255)*c)*255
  var ea,eb,ec:Extended;
  I:Integer;
  begin
  ea:=A/255;
  eb:=B/255;
  ec:=Ln(eb)/Ln(ea);
  for I:=1 to 255 do
  BarData[I]:=Round(Exp(Ln((I/255))*ec)*255);
  DrawBar;
  pbBarPaint(pbBar);
  Button1Click(Button1);
  end;
  那样做可以调节图像的亮度。
Delphi图形突显特效的技能
 概述 
  —-目前在不胜枚举就学软件、游戏光盘中,平日会面到种种 
  图形突显技术,凭着图形的位移、交错、雨水状、百页窗、积木堆叠等表现方式,使画面变得尤为活跃活泼,更
能吸引观众。本文将追究怎样在delphi中落实各个图片突显技术。 
  基本原理 
  —-在delphi中,已毕一副图象的显得是卓殊不难的,只要在form中定义一个timage组件,设置其picture属性,然后接纳任何有效的.ico、.bmp、.emf或.wmf文件,举办load,所选文
件就显示在timage组件中了。但那只是直接将图片呈现在窗体中,毫无技巧可言。为了使图形突显所有别具一格的功能,可以按下列步骤完成: 
  —-定义一个timage组件,把要体现的图片先装入到timage组件中,也就是说,把图纸内容从磁盘载入内存中,
做为图形缓存。 
  —-制造一新的位图对象,其尺寸跟timage组件中的图形一样。 
  —-利用画布(canvas)的copyrect功能(将一个画布的矩形区域拷贝到另一个画布的矩形区域),使用技术,动态形 
  成位图文件内容,然后在窗体中浮现位图。 
  —-落成格局 
  上面介绍各个图片突显技术: 
1.推拉效果 
  将要突显的图纸由上、下、左、右方向拉进屏幕内浮现,同时将屏幕上原本的旧图盖掉,此种效果可分为四 
  种,上拉、下拉、左拉、右拉,但原理都几乎,以上拉 效果为例。 
规律:首先将放在暂存图形的第一条水平线,搬移至要呈现的位图的最后一条,接着再将暂存图形的前两条水平线,依序搬移至要突显位图的末尾两条水平线,然后搬移前三条、前四条叄?直到整个图形数据搬完为止。在搬移的历程中即可看出显示的位图由下而上浮起,而完结上拉的法力。 
次第算法: 
procedure tform1.button1click(sender: tobject); 
var 
newbmp: tbitmap; 
i,bmpheight,bmpwidth:integer; 
begin 
newbmp:= tbitmap.create; 
newbmp.width:=image1.width; 
newbmp.height:=image1.height; 
bmpheight:=image1.height; 
bmpwidth:=image1.width; 
for i:=0 to bmpheight do 
begin 
newbmp.canvas.copyrect(rect 
(0,bmpheight-i,bmpwidth,bmpheight), 
image1.canvas, 
rect(0,0,bmpwidth,i)); 
form1.canvas.draw(120,100,newbmp); 
end; 
newbmp.free; 
end; 
2.垂直交错效果 
规律:将要突显的图纸拆成两片段,奇数条扫描线由上往下搬移,偶数条扫描线的部分则由下往上搬移,而且两岸同时开展。从屏幕上便可知到个别由上下两端出现的较淡图形向屏幕焦点活动,直到完全清楚截至。 
先后算法: 
procedure tform1.button4click(sender: tobject); 
var 
newbmp:tbitmap; 
i,j,bmpheight,bmpwidth:integer; 
begin 
newbmp:= tbitmap.create; 
newbmp.width:=image1.width; 
newbmp.height:=image1.height; 
bmpheight:=image1.height; 
bmpwidth:=image1.width; 
i:=0; 
while i< =bmpheight do 
begin 
j:=i; 
while j >0 do 
begin 
newbmp.canvas.copyrect(rect(0,j-1,bmpwidth,j), 
image1.canvas, 
rect(0,bmpheight-i+j-1,bmpwidth,bmpheight-i+j)); 
newbmp.canvas.copyrect(rect 
(0,bmpheight-j,bmpwidth,bmpheight-j+1), 
image1.canvas, 
rect(0,i-j,bmpwidth,i-j+1)); 
j:=j-2; 
end; 
form1.canvas.draw(120,100,newbmp); 
i:=i+2; 
end; 
newbmp.free; 
end; 
3.档次交错效果 
原理:同垂直交错效果原理一样,只是将分成两组后的图形分别由左右两端移进屏幕。 
次第算法: 
procedure tform1.button5click(sender: tobject); 
var 
newbmp:tbitmap; 
i,j,bmpheight,bmpwidth:integer; 
begin 
newbmp:= tbitmap.create; 
newbmp.width:=image1.width; 
newbmp.height:=image1.height; 
bmpheight:=image1.height; 
bmpwidth:=image1.width; 
i:=0; 
while i< =bmpwidth do 
begin 
j:=i; 
while j >0 do 
begin 
newbmp.canvas.copyrect(rect(j-1,0,j,bmpheight), 
image1.canvas, 
rect(bmpwidth-i+j-1,0,bmpwidth-i+j,bmpheight)); 
newbmp.canvas.copyrect(rect 
(bmpwidth-j,0,bmpwidth-j+1,bmpheight), 
image1.canvas, 
rect(i-j,0,i-j+1,bmpheight)); 
j:=j-2; 
end; 
form1.canvas.draw(120,100,newbmp); 
i:=i+2; 
end; 
newbmp.free; 
end; 
4.雨露作用 
原理:将暂存图形的最终一条扫描线,依序搬移到可视位图的率先条到最终一条扫描线,让此条扫描线在屏幕上留下它的轨道。接着再把暂存图形的倒数第二条扫描线,依序搬移到可视位图的首先条到尾数第二条扫描线。其他的扫描线依此类推。 
次第算法: 
procedure tform1.button3click(sender: tobject); 
var 
newbmp:tbitmap; 
i,j,bmpheight,bmpwidth:integer; 
begin 
newbmp:= tbitmap.create; 
newbmp.width:=image1.width; 
newbmp.height:=image1.height; 
bmpheight:=image1.height; 
bmpwidth:=image1.width; 
for i:=bmpheight downto 1 do 
for j:=1 to i do 
begin 
newbmp.canvas.copyrect(rect(0,j-1,bmpwidth,j), 
image1.canvas, 
rect(0,i-1,bmpwidth,i)); 
form1.canvas.draw(120,100,newbmp); 
end; 
newbmp.free; 
end; 
5.百叶窗效果 
原理:将位于暂存图形的多少分为若干组,然后逐一从第一组到最终一组搬移,首次每组各搬移第一条扫描线到可视位图的应和岗位,第二次搬移第二条扫描线,接着搬移第三条、第四条扫描线. 
次第算法: 
procedure tform1.button6click(sender: tobject); 
var 
newbmp:tbitmap; 
i,j,bmpheight,bmpwidth:integer; 
xgroup,xcount:integer; 
begin 
newbmp:= tbitmap.create; 
newbmp.width:=image1.width; 
newbmp.height:=image1.height; 
bmpheight:=image1.height; 
bmpwidth:=image1.width; 
xgroup:=16; 
xcount:=bmpheight div xgroup; 
for i:=0 to xcount do 
for j:=0 to xgroup do 
begin 
newbmp.canvas.copyrect(rect 
(0,xcount*j+i-1,bmpwidth,xcount*j+i), 
image1.canvas, 
rect(0,xcount*j+i-1,bmpwidth,xcount*j+i)); 
form1.canvas.draw(120,100,newbmp); 
end; 
newbmp.free; 
end; 
6.积木效果 
规律:是雨露效果的一种转移,不一致之处在于,积木效果每一回搬移的是一块图形,而不只是一根扫描线。 
先后算法: 
procedure tform1.button7click(sender: tobject); 
var 
newbmp:tbitmap; 
i,j,bmpheight,bmpwidth:integer; 
begin 
newbmp:= tbitmap.create; 
newbmp.width:=image1.width; 
newbmp.height:=image1.height; 
bmpheight:=image1.height; 
bmpwidth:=image1.width; 
i:=bmpheight; 
while i>0 do 
begin 
for j:=10 to i do 
begin 
newbmp.canvas.copyrect(rect(0,j-10,bmpwidth,j), 
image1.canvas, 
rect(0,i-10,bmpwidth,i)); 
form1.canvas.draw(120,100,newbmp); 
end; 
i:=i-10; 
end; 
newbmp.free; 
end; 
结束语 
上述图形展现效果均已上机通过。使用效率很好。
用Delphi落成图像放大镜
  向窗体上添加三个TImage组件,其中一个TImage组件的Name属性设置为Image1,它充当原图片显示的载体。另一个TImage组件的Name属性设置为Image2,它可以来得放大后的图像。添加零件后的窗体如图1所示。
 
图1 添加组件后的窗体

方法二:
代码:

方法二:
代码:

  本例的中坚是StretchBlt函数,利用StretchBlt函数完毕部分图像放大,响应代码如下:
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
 StretchBlt(Image2.Canvas.Handle,0,0,Image2.Width,Image2.Height,
 Image1.Canvas.Handle, X-20,Y-20,40,40,SRCCOPY);
 Image2.Refresh;
 Screen.Cursors[1]:=LoadCursorFromFile(’MAGNIFY.CUR’);
 Self.Cursor:=1;
end;

procedure TForm1.BitBtn4Click(Sender: TObject);

procedure TForm1.BitBtn4Click(Sender: TObject);

  程序首先会调用StretchBlt函数,以鼠标当前岗位作为主旨点,以边长为40选中Image1组件上的一些图像,并拓宽此部分图像到Image2组件上。然后通过调用Image2组件的Refresh方法以刷新Image2组件的显得。最终设置鼠标指针为新的形制。

var

var

  程序代码如下:
unit Unit1;
interface
uses

  p: pbyteArray;  //位指针

  p: pbyteArray;  //位指针

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
Dialogs, ExtCtrls, StdCtrls;

  x,y: integer;//x宽,y高

  x,y: integer;//x宽,y高

type
 TForm1 = class(TForm)
 Image1: TImage;
 Image2: TImage;
 procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,Y:
Integer);
 procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y:
Integer);
private
 { Private declarations }
public
 { Public declarations }
end;

  Bmp: TBitmap;//位图组件(TBitMap)

  Bmp: TBitmap;//位图组件(TBitMap)

var
 Form1: TForm1;
 implementation
 {$R *.dfm}
 procedure TForm1.Image1MouseMove(Sender:TObject;Shift:TShiftState;X,Y:
Integer);
 begin
  StretchBlt(Image2.Canvas.Handle,0,0,Image2.Width,Image2.Height,Image1.Canvas.Handle,
X-20,Y-20,40,40,SRCCOPY);
  Image2.Refresh;
  Screen.Cursors[1]:=LoadCursorFromFile(’MAGNIFY.CUR’);
  Self.Cursor:=1;
end;

  Gray: integer;//灰度值

  Gray: integer;//灰度值

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y:
Integer);
begin
 Screen.Cursors[1]:=crDefault;
 Self.Cursor:=1;
end;
end.

begin

begin

  保存文件,然后按F9键运行程序,程序运行结果如图2所示。
 
图2 程序运行结果

  Bmp := TBitmap.Create;//建立一个TBitmap

  Bmp := TBitmap.Create;//建立一个TBitmap

  放大图像是一个优质的看图软件必备的功用,本实例提供了一种更加省事易行的办法,不但代码数量少,而且进行成效高。

  Bmp.Assign(Form1.Image1.Picture.Bitmap);//将image图片转为位图方式

  Bmp.Assign(Form1.Image1.Picture.Bitmap);//将image图片转为位图格局

  Bmp.PixelFormat := pf24bit; //设为24位之彩色位图,PixelFormat
为位图的内存格式和颜料深浅,总共9个值

  Bmp.PixelFormat := pf24bit; //设为24位之彩色位图,PixelFormat
为位图的内存格式和颜料深浅,总共9个值

  for y := 0 to Bmp.Height-1 do

  for y := 0 to Bmp.Height-1 do

  begin

  begin

    p :=Bmp.ScanLine[y];//ScanLine方法用于获取像素颜色值

    p :=Bmp.ScanLine[y];//ScanLine方法用于获取像素颜色值

    for x:=0 to Bmp.Width-1 do

    for x:=0 to Bmp.Width-1 do

    begin

    begin

      Gray:=Max(p[3*x+2],p[3*x+1]);  //使用max函数旭定义Math单元

      Gray:=Max(p[3*x+2],p[3*x+1]);  //使用max函数旭定义Math单元

      Gray:=Max(Gray,p[3*x]);

      Gray:=Max(Gray,p[3*x]);

      p[3*x+2]:=byte(Gray);

      p[3*x+2]:=byte(Gray);

      p[3*x+1]:=byte(Gray);

      p[3*x+1]:=byte(Gray);

      p[3*x]:=byte(Gray);

      p[3*x]:=byte(Gray);

    end;

    end;

  end;

  end;

  image4.Picture.Bitmap := Bmp;

  image4.Picture.Bitmap := Bmp;

  Bmp.Free;//释放TBitmap

  Bmp.Free;//释放TBitmap

end;
原图:    图片 5  
处理后:图片 6 
 

end;
原图:    图片 7  
处理后:图片 8 
 

 方法三:**利用公式Y=0.299R+0.857G+0.113B**

 方法三:**运用公式Y=0.299R+0.857G+0.113B**

procedure TForm1.BitBtn4Click(Sender: TObject);

procedure TForm1.BitBtn4Click(Sender: TObject);

var

var

  p: pbyteArray;  //位指针

  p: pbyteArray;  //位指针

  x,y: integer;//x宽,y高

  x,y: integer;//x宽,y高

  Bmp: TBitmap;//位图组件(TBitMap)

  Bmp: TBitmap;//位图组件(TBitMap)

  Gray: integer;//灰度值

  Gray: integer;//灰度值

begin

begin

  Bmp := TBitmap.Create;//建立一个TBitmap

  Bmp := TBitmap.Create;//建立一个TBitmap

  Bmp.Assign(Form1.Image1.Picture.Bitmap);//将image图片转为位图形式

  Bmp.Assign(Form1.Image1.Picture.Bitmap);//将image图片转为位图方式

  Bmp.PixelFormat := pf24bit; //设为24位之彩色位图,PixelFormat
为位图的内存格式和颜料深浅,总共9个值

  Bmp.PixelFormat := pf24bit; //设为24位之彩色位图,PixelFormat
为位图的内存格式和颜色深浅,总共9个值

  for y := 0 to Bmp.Height-1 do

  for y := 0 to Bmp.Height-1 do

  begin

  begin

    p :=Bmp.ScanLine[y];//ScanLine方法用于获取像素颜色值

    p :=Bmp.ScanLine[y];//ScanLine方法用于获取像素颜色值

    for x:=0 to Bmp.Width-1 do

    for x:=0 to Bmp.Width-1 do

    begin

    begin

     
Gray:=round(p[3*x+2]*0.3+p[3*x+1]*0.59+p[3*x]*0.11);//公式Y=0.299R+0.857G+0.113B

     
Gray:=round(p[3*x+2]*0.3+p[3*x+1]*0.59+p[3*x]*0.11);//公式Y=0.299R+0.857G+0.113B

      p[3*x+2]:=byte(Gray);

      p[3*x+2]:=byte(Gray);

      p[3*x+1]:=byte(Gray);

      p[3*x+1]:=byte(Gray);

      p[3*x]:=byte(Gray);

      p[3*x]:=byte(Gray);

    end;

    end;

  end;

  end;

  image4.Picture.Bitmap := Bmp;

  image4.Picture.Bitmap := Bmp;

  Bmp.Free;//释放TBitmap

  Bmp.Free;//释放TBitmap

end;
原图:   图片 9
处理后:图片 10  

end;
原图:   图片 11
处理后:图片 12  

手续四:image图片的二值化
 

手续四:image图片的二值化
 

   
  在对图像二值化从前须要对图像举行灰度处理,二值化原理:通过设定阈值(threshold),把灰度图像成为仅用0或1来表示图像目标和背景,其中图像目标大多为数字,字母,设为1,;背景设为0。在位图中0对应0,1对应255,二值化方法很多,不过根本是在于对阈值的挑三拣四。

   
  在对图像二值化之前必要对图像举行灰度处理,二值化原理:通过设定阈值(threshold),把灰度图像成为仅用0或1来代表图像目标和背景,其中图像目的大多为数字,字母,设为1,;背景设为0。在位图中0对应0,1对应255,二值化方法很多,不过主假如介于对阈值的挑选。

     阈值的抉择关键分为两类:全局阈值和一些阈值。
     全局阈值是对所有图像选拔一个阈值举办分割,例如固定阈值法二值化、判断分析化二值化等;
     局地阈值是将图像分为几块,每个子块选用不一样的阈值;(具体有些阈值法能够活动百度,那里不必过多解释)
代码:

     阈值的选项关键分为两类:全局阈值和局地阈值。
     全局阈值是对一切图像采纳一个阈值进行私分,例如固定阈值法二值化、判断分析化二值化等;
     局地阈值是将图像分为几块,每个子块拔取差别的阈值;(具体有些阈值法可以自行百度,那里不必过多解释)
代码:

procedure TForm1.BitBtn4Click(Sender: TObject);

procedure TForm1.BitBtn4Click(Sender: TObject);

var

var

  p: pbyteArray;  //位指针

  p: pbyteArray;  //位指针

  x,y: integer;//x宽,y高

  x,y: integer;//x宽,y高

  Bmp: TBitmap;//位图组件(TBitMap)

  Bmp: TBitmap;//位图组件(TBitMap)

  Gray: integer;//灰度值

  Gray: integer;//灰度值

begin

begin

  Bmp := TBitmap.Create;//建立一个TBitmap

  Bmp := TBitmap.Create;//建立一个TBitmap

  Bmp.Assign(Form1.Image1.Picture.Bitmap);//将image图片转为位图形式

  Bmp.Assign(Form1.Image1.Picture.Bitmap);//将image图片转为位图情势

  Bmp.PixelFormat := pf24bit; //设为24位之彩色位图,PixelFormat
为位图的内存格式和颜料深浅,总共9个值

  Bmp.PixelFormat := pf24bit; //设为24位之彩色位图,PixelFormat
为位图的内存格式和颜色深浅,总共9个值

  for y := 0 to Bmp.Height-1 do

  for y := 0 to Bmp.Height-1 do

  begin

  begin

    p :=Bmp.ScanLine[y];//ScanLine方法用于获取像素颜色值

    p :=Bmp.ScanLine[y];//ScanLine方法用于获取像素颜色值

    for x:=0 to Bmp.Width-1 do

    for x:=0 to Bmp.Width-1 do

    begin

    begin

     
Gray:=round(p[3*x+2]*0.3+p[3*x+1]*0.59+p[3*x]*0.11);//公式Y=0.299R+0.857G+0.113B

     
Gray:=round(p[3*x+2]*0.3+p[3*x+1]*0.59+p[3*x]*0.11);//公式Y=0.299R+0.857G+0.113B

      //图像二值化

      //图像二值化

      if Gray > 120 then//阈值为120

      if Gray > 120 then//阈值为120

      begin

      begin

        p[3*x+2]:=255;

        p[3*x+2]:=255;

        p[3*x+1]:=255;

        p[3*x+1]:=255;

        p[3*x]:=255;

        p[3*x]:=255;

      end

      end

      else

      else

      begin

      begin

        p[3*x+2]:=0;

        p[3*x+2]:=0;

        p[3*x+1]:=0;

        p[3*x+1]:=0;

        p[3*x]:=0;

        p[3*x]:=0;

      end; 
//分割线————————————- 

      end; 
//分割线————————————- 

    end;

    end;

  end;

  end;

  image4.Picture.Bitmap := Bmp;

  image4.Picture.Bitmap := Bmp;

  Bmp.Free;//释放TBitmap

  Bmp.Free;//释放TBitmap

end;

end;

原图:
  图片 13
处理后:图片 14
从效益图可以见见,图像二值化就是设定一个阈值,然后判定每点的RGB值大于如故小于阈值,大于则为255即藏灰色,小于阈值则为0即白色。

原图:
  图片 15
处理后:图片 16
从功能图可以看看,图像二值化就是设定一个阈值,然后判定每点的RGB值大于仍旧小于阈值,大于则为255即青色,小于阈值则为0即白色。

 

 

qq:673890989  
 欢迎有趣味的同伙互换

qq:673890989  
 欢迎有趣味的小伙伴沟通

 

 

经验

经验

 

 

相关文章