基于Delphi的一种Blob图像数据的处理方法
delphi实现bmp与jpg图像相互转换及位图大小调整

delphi实现bmp与jpg图像相互转换及位图大小调整delphi实现bmp与jpg图像相互转换及位图大小调整摘要:本文介绍了如何通过delphi编码实现bmp格式图像与jpeg格式图像的相互转换以及bmp格式图像的大小的调整。
在图片处理操作中使用了几个api函数,其算法同样适用于其他编程语言。
关键词:图形转换、图片调整在很多MIS系统或者其他管理信息系统中,有需要用户上传照片到数据库等对图片的操作,根据系统需求不同,可能需要对这些照片进行格式转换或者大小的调整。
这里有三个在MIS系统或者其他管理信息系统中比较常用的图片处理过程,与大家分享。
1、 Bmp格式转换位jpg(jpeg)格式。
进程:Image_BitmapToJPeg实现bmp格式图片到Jpg(jpeg)格式图片的转换,如下:{参数介绍:FileName:要转换的位图的路径及名称SaveFileName:转换后生成 jpg图形的路径及名称}Procedure Image_BitmapT oJPeg(Const FileName: String;Sav eFileName:String=''); VarBitmap: TBitmap; //定义变量JPeg: TJPegImage; //所属unit是:Jpeg,需要在项目的uses 中加入Jpeg Begin TryBitmap := TBitmap.Create; //创建位图资源Bitmap.LoadFromFile(FileName); //根据传入的参数载入位图资源 JPeg := TJPegImage.Create; //创建jpeg资源JPeg.Assign(Bitmap); //把bitmap中的图像资源拷贝到jpeg对象中IF Trim(SaveFileName)='' Then //如果传入的目的地址为空,按原名保存(扩展名改变) JPeg.SaveToFile(ChangeFileExt(FileName, '.jpg')) Else //按参数指定的名称保存jpg图片 JPeg.SaveToFile(SaveFileName);FinallyFreeAndNil(Bitmap); //释放资源 FreeAndNil(JPeg); //释放资源 End; End;从上面的代码及其注释中我们可以看出程序思路,首先分别定义并创建bmp对象Bitmap和jpeg对象JPeg,然后在Bitmap对象载入位图后,把Bitmap中的图像资源复制到Jpeg中,最后把Jpeg保存到磁盘并释放创建的对象。
delphi中处理sqlserver中的image、text字段

delphi中处理sqlserver中的image、text字段下面通过详细的例子来讲述如何在delphi中处理sql server中的image、text字段。
因为实际开发的需要,我们需要处理的是text类型的字段,包括读和写。
网上很多相关的文章都是讲述的对image的读写操作,下面首先介绍如何将图象存储在sql server的image字段。
其中DataMConn为一个针对数据库操作的单元,放置一个ADOConnection,一个ADOQuery //image to database procedure TfrmText.Button1Click(Sender: TObject);varbm:tbitmap;ms:TMemoryStream;beginms:=TMemoryStream.Create;bm:=TBitmap.Create;bm.Assign(image1.Picture.Bitmap);bm.SaveToStream(ms);with DataMConn.ADOQHistory dobeginClose;SQL.Clear;SQL.Add('INSERT INTO Package(PackageID,TempPackage) VALUES(:x,:y)');Parameters.ParamByName('y').LoadFromStream(ms,ftBlob);Parameters.ParamByName('x').Value := 'aaaaa';ExecSQL;end;end;//show imageprocedure TfrmText.Button2Click(Sender: TObject);varStream:TStream;bm:tbitmap;beginwith DataMConn.ADOQHistory dobeginClose;SQL.Clear;SQL.Add('SELECT * FROM Package WHERE packageID= ''aaaaa''');TryOpen;stream := DataMConn.ADOQHistory.CreateBlobStream(FieldByName('T em pPackage'),bmRead);bm:=TBitmap.Create;bm.LoadFromStream(stream);image2.Picture.bitmap.Assign(bm);stream.Free;exceptbeginShowMessage('Error!');Exit;end;end;//tryend;end;下面的两个例子是如何处理text类型的字段,其中读取的时候,利用了一个TDBMemo控件,来加载读取的流数据,然后赋值给一个WideString类型的变量str//text to streamprocedure TfrmText.Button3Click(Sender: TObject);varstr : WideString;ss:TStringStream;i : integer;beginstr := 'sstrstrststrstrststrstrstrsttrstrstrrstrstr';for i := 1 to 10000 dobeginstr := str + 'sstrstrststrstrststrstrstrsttrstrstrrstrstr'; //43万多个字节end;str := str + 'E';ss := TStringStream.Create(str);//bm:=TBitmap.Create;//bm.Assign(image1.Picture.Bitmap);//bm.SaveToStream(ms);with DataMConn.ADOQHistory dobeginClose;SQL.Clear;SQL.Add('INSERT INTO tPackage(PackageID,TempPackage) VALUES(:x,:y)');Parameters.ParamByName('y').LoadFromStream(ss,ftMemo);Parameters.ParamByName('x').Value := 'aaaaa';ExecSQL;end;end;//read text to a TDBMemoprocedure TfrmText.Button4Click(Sender: TObject);varstream : TStream;str : WideString;beginwith DataMConn.ADOQHistory dobeginClose;SQL.Clear;SQL.Add('SELECT TempPackage FROM tPackage WHERE packageID= ''aaaaa''');Open;if not IsEmpty thenbeginStream := DataMConn.ADOQHistory.CreateBlobStream(FieldByName('T em pPackage'),bmRead);stream.Position := 0;AMemo.Lines.LoadFromStream(stream);stream.Free;end;end;end;//下面是把text字段的数据内容直接读到一个WideString中,而不通过TDBMemo,因为在实际中,不知道何种原因,线程读到数据后,只能在第一次处理时正常,然后再用鼠标点应用程序,程序就停了……who knows the reason , pls tell me & 3ksprocedure TfrmText.Button5Click(Sender: TObject);varBuffer: PChar;MemSize: Integer;Stream: TStream;str : WideString;beginwith DataMConn.ADOQHistory dobeginClose;SQL.Clear;SQL.Add('SELECT TempPackage FROM tPackage WHERE packageID= ''aaaaa''');Open;if not IsEmpty thenbeginStream := DataMConn.ADOQHistory.CreateBlobStream(FieldByName('T em pPackage'),bmRead);tryMemSize := Stream.Size;Inc(MemSize); //Make room for the buffer's null terminator.Buffer := AllocMem(MemSize); //Allocate the memory.tryStream.Read(Buffer^, MemSize); //Read TempPackage field into buffer.str := Buffer;finallyFreeMem(Buffer, MemSize);end;finallyStream.Free;end;end;end;end;如何用流的方法向SQLServer数据库中读写blob的image字段varTempStream: TMemoryStream;begin//ReadTempStream := TMemoryStream.Create;tryTBlobField(FieldByName('ImageField')).SaveToStream; TempStream.Position := 0;Memo1.Lines.LoadFromStream(TempStream);FinallyTempStream.Free;end;//WriteTempStream := TMemoryStream.Create;tryMemo1.Lines.SaveToStream(TempStream);//Image1.Picture.Bitmap.LoadFromStream(TempStream); TBlobField(FieldByName('ImageField')).LoadFromStream; FinallyTempStream.Free;end;end;varaStream1 : TStream;jpg : tjpegimage; //在uses 加入 jpeg,db 单元插入jpg := tjpegimage.Create();trydm.Query_image.open;dm.query_image.insert;aStream1 := dm.query_image.CreateBlobStream(dm.query_image.FieldByNa me('content'),bmReadWrite);jpg.LoadFromFile(name);jpg.SaveToStream(aStream1);aStream1.Free;dm.query_image.Post;finallyjpg.Free;end;取出if dm.query_image.State <> dsBrowse then exit;if dm.query_image.FieldByName('content').IsNull then Exit; //判断状态,content是我表里存放jpeg的fielddm.query_image.open;aStream1 := dm.query_image.CreateBlobStream(dm.query_image.FieldByNa me('content'), bmRead);tryaStream1.Position := 0;jpg:= tjpegimage.Create();tryjpg.LoadFromStream(aStream1);jpg.SaveToFile(ipath); //ipath:string 存放路径与文件名finallyjpg.Free;end;finallyaStream1.Free;end;end;文件写入字段:SQLstr:='INSERT INTO 表名(...,Image字段名,...)VALUES (...,:Image,...)';Query.SQL.Add(SQLstr);Query.SQL.ParamByName('Image').LoadFromFile(图象文件名);Query.ExecSQL;从字段写入文件:SQLstr:='SELECT ...,Image字段名,... FROM 表名 WHERE...';Query.Close;Query.SQL.Clear;Query.SQL.Add(SQLstr);Query.Open;(Query.FieldByName(Image字段名) as TBlobField).SaveToFile(文件名);//或TBlobField(Query.FieldByName(Image字段名)).SaveToFile(文件名);向SQL Server插入带有Image字段的记录向SQL Server插入记录相信大家都会做,但是如果表中带有Image字段就不好弄了,这里有一个例子,非常安全,同时也向大家展示动态生成控件的技巧!在SQL Server中建立TEST表,两个字段,id varchar(10),photo image(16);procedure TForm1.BitBtn1Click(Sender: TObject);beginopenpicturedialog1.execute;image1.picture.loadfromfile(openpicturedialog1.filename);end;procedure TForm1.BitBtn2Click(Sender: TObject);vargraphic1:Timage;begingraphic1:=Timage.Create(self);graphic1.picture.loadfromfile(openpicturedialog1.filename);table1.Open;table1.insert;table1.fieldbyname(’id’).asstring:=’121’;table1.fields[1].assign(graphic1.Picture);table1.post;table1.close;graphic1.free;end;显示可用:DBIMAGE控件显示!DELPHI存取JPEG文件到SQL Server数据库unit Unit1;interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,ExtCtrls, DBCtrls, Grids, DBGrids, Db, ADODB,jpeg, StdCtrls,dbtables;{一定要USES JPEG单元,使能存储JPG文件格式}typeTForm1 = class(TForm)DataSource1: TDataSource;ADOQuery1: TADOQuery;DBGrid1: TDBGrid;DBNavigator1: TDBNavigator;Image1: TImage;savebutton: TButton;showbutton: TButton;OpenDialog1: TOpenDialog;ADOQuery1id: TIntegerField;ADOQuery1pic: TBlobField;procedure savebuttonClick(Sender: TObject);procedure showbuttonClick(Sender: TObject);procedure DBNavigator1Click(Sender: TObject; Button: TNavigateBtn);private{ Private declarations }public{ Public declarations }end;varForm1: TForm1;implementation{$R *.DFM}function JpegStartsInBlob(PicField:TBlobField):integer;varghy: TADOBlobstream;buffer:Word;hx: string;beginResult := -1;ghy := TADOBlobstream.Create(PicField, bmRead);trywhile (Result = -1) and (ghy.Position + 1 < ghy.Size) dobeginghy.ReadBuffer(buffer, 1);hx:=IntToHex(buffer, 2);if hx = ’FF’ then b eginghy.ReadBuffer(buffer, 1);hx:=IntToHex(buffer, 2);if hx = ’D8’ then Result := ghy.Position - 2else if hx = ’FF’ thenghy.Position := ghy.Position-1;end; //ifend; //whilefinallyghy.Freeend; //tryend;procedure TForm1.savebuttonClick(Sender: TObject);varpicstream:tadoblobstream;beginadoquery1.edit;picstream:=tadoblobstream.Create(tblobfield(adoquery1.fie lds[1]),bmWrite);if form1.opendialog1.execute thenbeginpicstream.LoadFromFile(opendialog1.filename);picstream.Position:=0;adoquery1.edit;tblobfield(adoquery1.Fields[1]).loadfromstream(picstream);adoquery1.post;end;end;procedure TForm1.showbuttonClick(Sender: TObject);varghy:TADOBlobstream;pic:tjpegimage;beginghy := TADOBlobstream.Create(Adoquery1pic, bmRead);tryghy.Seek(JpegStartsInBlob(Adoquery1pic),soFromBeginning );Pic:=TJpegImage.Create;tryPic.LoadFromStream(ghy);Image1.Picture.Graphic:=Pic;finallyPic.Free;end;finallyghy.Freeend;end;procedure TForm1.DBNavigator1Click(Sender: TObject; Button: TNavigateBtn);beginif button in [nbFirst, nbPrior, nbNext, nbLast] thenshowbutton.Click;end;end.如果数据库中要存储的是BMP文件,则在procedure TForm1.showbuttonClick(Sender: TObject);过程中代码更改如下即可存储显示BMP文件格式的操作。
Delphi基本图像处理方法.

本文实例汇总了Delphi基本图像处理方法。
分享给大家供大家参考。
具体分析如下: //浮雕 procedureEmboss(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]; 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 thenSrcRGB1 := 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; 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 div45+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 >= 45and (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; procedureEmboss(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; //反色 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 beginPRGB^.rgbtRed :=not PRGB^.rgbtRed ; PRGB^.rgbtGreen :=not PRGB^.rgbtGreen; PRGB^.rgbtBlue :=not PRGB^.rgbtBlue; Inc(PRGB; end; end; end; //曝光 procedure Exposure(Bmp:TBitmap; var i, j: integer; PRGB: pRGBTriple; beginBmp.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 thenPRGB^.rgbtGreen :=not PRGB^.rgbtGreen; if PRGB^.rgbtBlue<128 thenPRGB^.rgbtBlue :=not PRGB^.rgbtBlue; Inc(PRGB; end; end; end; //模糊 procedure Blur(SrcBmp:TBitmap; var i, j:Integer; SrcRGB:pRGBTriple; SrcNextRGB:pRGBTriple; SrcPreRGB:pRGBTriple; Value:Integer; procedure IncRGB; begin Inc(SrcPreRGB;Inc(SrcRGB; Inc(SrcNextRGB; end; procedure DecRGB; begin Inc(SrcPreRGB,-1;Inc(SrcRGB,-1; Inc(SrcNextRGB,-1; end; 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] elseSrcNextRGB:=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 thenIncRGB;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; //锐化 procedureSharpen(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; [图像的旋转和翻转] 以下代码用ScanLine配合指针移动实现,用于24位色! //旋转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 beginrowOut := Bmp.ScanLine[i]; Inc(rowOut,Height - j; rowOut^ := rowIn^; Inc(rowIn; end;end; Bitmap.Assign(Bmp; end; //旋转180度 procedure Rotate180(constBitmap: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; //旋转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; //任意角度 functionRotateBitmap(Bitmap:TBitmap;Angle:Integer;BackColor:TColor:TBitmap; vari,j,iOriginal,jOriginal,CosPoint,SinPoint : integer; RowOriginal,RowRotated : pRGBTriple; SinTheta,CosTheta : Extended; AngleAdd : integer; beginResult:=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 beginSinPoint:=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-1and (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; //水平翻转 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; //垂直翻转 procedureFlipVert(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 beginrowIn := 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; [亮度、对比度、饱和度的调整] 以下代码用ScanLine配合指针移动实现! function Min(a, b: integer: integer; begin if a < b then result := a else result := b; end; function Max(a, b: integer: integer; begin if a > b then result := a else result := b; end; //亮度调整 procedure BrightnessChange(constSrcBmp,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; //对比度调整 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; ifSrcRGB.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 thenDestRGB.rgbtBlue := Max(128, SrcRGB.rgbtBlue + ValueChange elseDestRGB.rgbtBlue := Min(128, SrcRGB.rgbtBlue - ValueChange; end; Inc(SrcRGB; Inc(DestRGB; end; end; end; //饱和度调整 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; //RGB调整 procedureRGBChange(SrcBmp,DestBmp:TBitmap;RedChange,GreenChange,BlueChange:integer; var SrcRGB, DestRGB: pRGBTriple; i,j:integer; begin for i := 0 to SrcBmp.Height- 1 dobegin 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; if GreenChange> 0 then DestRGB.rgbtGreen :=Min(255, SrcRGB.rgbtGreen + GreenChange else DestRGB.rgbtGreen := Max(0, SrcRGB.rgbtGreen + GreenChange; 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; [颜色调整] //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 forX := 0 to (Bitmap.Width - 1 do begin Color := PRGB^.rgbtRed; PRGB^.rgbtRed := PRGB^.rgbtBlue; PRGB^.rgbtBlue := Color; Inc(PRGB; 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; 绘图区-即窗口显示图像的区域,亦可为全屏幕(在全屏幕下绘图的效果比一般窗口下好)中心点-即要绘图区显示的中心点在原始图像的坐标(声明:这个概念特别重要)先说说图像的放大,要放大一张图片,我们一般的做法是直接放大图像,但本文介绍的方法仅放大我们能够看到的部分,放大分两种情况,一种是放大后比绘图区还要小,这种情况没什么好说,当然是显示全部的图像;第二种是放大后的图像比绘图区大,这才是我们今天要讨论的重点话题,这种情况下我们先要确定图像放大后的大小,然后根据“中心点”计算在原始图像的位置和大小,最后把截取的图像放大到绘图区。
Delphi数据库应用程序开发中图像数据的存取技术

Delphi提供了数据访问(DataAccess)和数据控制(DataControls)的可视化控件,能够方便快捷地产生具有良好界面且功能强大的数据库应用程序。
对于涉及图像数据(含Graphic字段)的数据库应用程序,如人事管理信息系统等,图像数据的存取技术是一个关键。
然而,有关Delphi下图象的存取,特别是图像的保存方面的技术各种资料上很少提及。
下面,笔者结合一个简单的例子来说明。
一、图像数据的保存1.创建一个含有Graphic字段的数据库列表。
在WindowsISQ(或Databasedesktop)下createdatabasemydb.gdbcreatetablemyfrieds (namevarchar(15)notnull,telephonevarchar(12),addressvarchar(30),zipvarchar(8),picturevarchar(15),imageblob);其中,picture字段用于保存图像的名称(包括路径),image(Graphic字符)则用于存储图像,其数据类型为“blob”。
2.建立窗体(如图1所示),设置窗体中各控件的属性。
该窗体的主要功能是将某人信息进行编辑和保存。
需要注意的图像保存所用的图像框必须用TImage而不能用TDBIm age,编辑框宜用Tedit而不宜用TDBEdit,这一点与图像的读取恰好相反。
其中,各主要控件的属性设置如下:Datasource1.Dataset:=table1;Table1.Databasename:=mydb.gdb;Table1.Tablename:=myfriends;Table1.active:=true;其他诸如Caption之类的属性设置不再叙述。
3.数据处理程序的建立。
(1)图像(.bmp文件)打开的处理。
procedureTForm1.pictopenbtnClick(Sender:TObject);beginopendialog1.execute;image1.picture.loadfromfile(opendialog1.filename);end;(2)图像保存的处理。
Delphi图像处理之图像二值化

Delphi图像处理之图像⼆值化-----------开发环境D7---效果图-------只提供参考----------------unit开始1unit Unit1;23interface45uses6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,7 Dialogs, ExtCtrls, StdCtrls, ExtDlgs;89type10 ThresholdValueArray=array of array of Byte ;11 TForm1 = class(TForm)12 Button1: TButton;13 Button2: TButton;14 Image1: TImage;15 Image2: TImage;16 OpenPictureDialog1: TOpenPictureDialog;17 Label1: TLabel;18 Button4: TButton;19 Label2: TLabel;20 EditX: TEdit;21 EditY: TEdit;22 Label3: TLabel;23 Label4: TLabel;24 Label5: TLabel;25 Label6: TLabel;26 Label7: TLabel;27procedure Button1Click(Sender: TObject);28procedure Button2Click(Sender: TObject);29procedure Button4Click(Sender: TObject);30procedure EditXChange(Sender: TObject);31private32function GetThresholdValue(sBmp: TBitmap; sX,sY: Byte): ThresholdValueArray;33function GetThresholdArrayGray(const sArray:ThresholdValueArray; sStartX, sEndX, sStartY, sEndY: word): Byte; 34{ Private declarations }35public36{ Public declarations }37end;3839var40 Form1: TForm1;4142implementation4344{$R *.dfm}4546procedure TForm1.Button1Click(Sender: TObject);47begin48if OpenPictureDialog1.Execute then49begin50 Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);51 Label1.Caption:='图⽚宽x⾼:'+inttostr(Image1.Picture.Width)+'x'+inttostr(Image1.Picture.Height);52end;53end;5455procedure TForm1.Button2Click(Sender: TObject);56const57 vThresholdValue:Byte=128;58var59 vP:PByteArray;60 x,y:Integer;61 vBmp:TBitmap;62 vGray:Integer;63begin64if Image1.Picture.Graphic =nil then65begin66 ShowMessage('没有图⽚!');67 Exit;68end;69 vBmp:=TBitmap.Create;70 vBmp.Assign(Image1.Picture.Bitmap);71 vBmp.PixelFormat:=pf24bit;72for y:=0to vBmp.Height-1do73begin74 vP:=vBmp.ScanLine[y];75for x:=0to vBmp.Width-1do76begin77 vGray:=(77*vP[3*x+2] + 149*vP[3*x+1] + 29*vP[3*x]) shr8;78if vGray>vThresholdValue then79begin80 vP[3*x+2]:=255;81 vP[3*x+1]:=255;82 vP[3*x]:=255;83end84else85begin86 vP[3*x+2]:=0;87 vP[3*x+1]:=0;88 vP[3*x]:=0;89end;90end;91end;92 Image2.Picture.Assign(vBmp);93 vBmp.Free;94end;9596function TForm1.GetThresholdArrayGray(const sArray: ThresholdValueArray; sStartX,97 sEndX, sStartY, sEndY: word): Byte;98var99 vGraySum:DWORD;100 i,j:Word;101begin102 Result:=128;//默认返回128103if sArray=nil then104 Exit;105 vGraySum:=0;106for i:=sStartX-1to sEndX-1do107begin108for j:=sStartY-1to sEndY-1do109begin110 vGraySum:=vGraySum+sArray[i,j];111end;112end;113 Result:=Round(vGraySum/((sEndX-sStartX+1)*(sEndY-sStartY+1)));114end;115116function TForm1.GetThresholdValue(sBmp: TBitmap; sX,117 sY: Byte): ThresholdValueArray;118119var120 i,j,x,y,vGray:Word;121 vLengthX,vLengthY,vModX,vModY:Word;122 vP:PByteArray;123 vBitmapGrayArray:ThresholdValueArray;124 vResultGrayArray:ThresholdValueArray;125begin126 Result:=nil;127if sBmp=nil then128 Exit;129if sX=0then130 sX:=1;131if sY=0then132 sY:=1;133 setlength(vBitmapGrayArray,sBmp.Width);134for i:=0to sBmp.Width-1do135begin136 setlength(vBitmapGrayArray[i],sBmp.Height);137end;138 SetLength(vResultGrayArray,sX);139for i:=0to sX-1do140begin141 SetLength(vResultGrayArray[i],sY);142end;143144for y:=0to sBmp.Height-1do145begin146 vP:=sBmp.ScanLine[y];147for x:=0to sBmp.Width-1do148begin149 vGray:=(77*vP[3*x+2] + 149*vP[3*x+1] + 29*vP[3*x]) shr8;150 vBitmapGrayArray[x,y]:=vGray;151end;152end;153 vLengthX:=sBmp.width div sX;154 vLengthY:=sBmp.Height div sY;155 vModX:=sBmp.width mod sX;156 vMody:=sBmp.Height mod sY;157for i:=0to sX-1do//⼩块158begin159for j:=0to sY-1do//⼩块160begin161if i<>sX-1then162begin163 vResultGrayArray[i,j]:=GetThresholdArrayGray(vBitmapGrayArray,vLengthX*i+1,vLengthX*i+vLengthX,vLengthY*j+1,vLengthY*j+vLengthY);164end165else//最后⼀列166begin167 vResultGrayArray[i,j]:=GetThresholdArrayGray(vBitmapGrayArray,vLengthX*i+1,vLengthX*i+vLengthX+vModX,vLengthY*j+1,vLengthY*j+vLengthY+vModY); 168end;169173 Result:=vResultGrayArray;174//数组释放175for i:=0to sBmp.Width-1do176begin177 setlength(vBitmapGrayArray[i],0);178end;179 setlength(vBitmapGrayArray,0);180end;181182procedure TForm1.Button4Click(Sender: TObject);183var184 vP:PByteArray;185 x,y:Integer;186 vBmp:TBitmap;187 vGray:Integer;188 vLengthX, vLengthY, vModX, vModY,vRowMod,vColMod: Word;189 vX,vY:Byte;190 vGrayArray:ThresholdValueArray;191 vRow,vCol:byte;192begin193if Image1.Picture.Graphic =nil then194begin195 ShowMessage('没有图⽚!');196 Exit;197end;198 vX:=StrToIntDef(editX.Text ,3);199 vY:=StrToIntDef(editY.Text ,3);200201//暂时最多分成255*255块202if (vX<1) or (vX>255) or (vY<1) or (vY>255) then203begin204 MessageBox(Handle,PChar('X和Y的范围:1到255; 请输⼊在这个范围内的数字!'),PChar(Application.Title),MB_ICONEXCLAMATION); 205 Exit;206end;207 Label6.Caption:='总块数:'+inttostr(vX*vY);208 vBmp:=TBitmap.Create;209 vBmp.Assign(Image1.Picture.Bitmap);210 vBmp.PixelFormat:=pf24bit;211212 vGrayArray:=GetThresholdValue(vBmp,vX,vY);213for y:=0to vBmp.Height-1do214begin215 vP:=vBmp.ScanLine[y];216 vRow:=y div vLengthY;217 vRowMod:=y div vLengthY;218if vRow<vY then219begin220if vRowMod>0then221 vRow:=vRow+1;222end;223for x:=0to vBmp.Width-1do224begin225 vCol:=x div vLengthx;226 vColMod:=x div vLengthx;227if vCol<vX then228begin229if vColMod>0then230 vCol:=vCol+1;231end;232 vGray:=(77*vP[3*x+2] + 149*vP[3*x+1] + 29*vP[3*x]) shr8;233if vGray>vGrayArray[vCol,vRow] then234begin235 vP[3*x+2]:=255;236 vP[3*x+1]:=255;237 vP[3*x]:=255;238end239else240begin241 vP[3*x+2]:=0;242 vP[3*x+1]:=0;243 vP[3*x]:=0;244end;245end;246end;247 Image2.Picture.Assign(vBmp);248 vBmp.Free;249end;250251procedure TForm1.EditXChange(Sender: TObject);252begin253 Label6.Caption:='总块数:'+inttostr(StrToIntDef(EditX.Text ,0)*strtointDef(EditY.Text,0));--------unit结束--------Form开始1object Form1: TForm12 Left = 5133 Top = 3264 Width = 9105 Height = 5286 Caption = 'Form1'7 Color = clBtnFace8 Font.Charset = DEFAULT_CHARSET9 Font.Color = clWindowText10 Font.Height = -1111 = 'MS Sans Serif'12 Font.Style = []13 OldCreateOrder = False14 PixelsPerInch = 9615 TextHeight = 1316object Image1: TImage17 Left = 818 Top = 1619 Width = 42520 Height = 33721 Center = True22 Proportional = True23 Stretch = True24end25object Image2: TImage26 Left = 44827 Top = 1628 Width = 42529 Height = 33730 Center = True31 Proportional = True32 Stretch = True33end34object Label1: TLabel35 Left = 1636 Top = 36037 Width = 38538 Height = 2539 AutoSize = False40 Caption = '图⽚宽x⾼:'41end42object Label2: TLabel43 Left = 52844 Top = 36045 Width = 27346 Height = 1347 Alignment = taCenter48 AutoSize = False49 Caption = '按块求出阈值'50end51object Label3: TLabel52 Left = 45753 Top = 38154 Width = 7355 Height = 1356 Caption = '输⼊X x Y块:'57end58object Label4: TLabel59 Left = 53360 Top = 38161 Width = 2462 Height = 1363 Alignment = taRightJustify64 AutoSize = False65 Caption = 'X:'66end67object Label5: TLabel68 Left = 62069 Top = 38070 Width = 2171 Height = 1772 Alignment = taRightJustify73 AutoSize = False74 Caption = 'Y:'75end76object Label6: TLabel77 Left = 70478 Top = 38379 Width = 18580 Height = 1381 AutoSize = False82 Caption = '总块数:'83end84object Label7: TLabel85 Left = 51286 Top = 44087 Width = 37788 Height = 4589 AutoSize = False90 Caption = '理应是块数分的越多,越准确!本⼈这个呈抛物线的感觉,'#13#10'有⼀个最优的块数,算了先不找原因了,抛砖引⽟,哈哈哈'91 WordWrap = True92end93object Button1: TButton94 Left = 1695 Top = 41696 Width = 16197 Height = 2598 Caption = 'Button1_加载图⽚'99 TabOrder = 0100 OnClick = Button1Click101end102object Button2: TButton103 Left = 232104 Top = 416105 Width = 177106 Height = 25107 Caption = 'Button2_⼆值化_默认阈值'108 TabOrder = 1109 OnClick = Button2Click110end111object Button4: TButton112 Left = 560113 Top = 407114 Width = 297115 Height = 25116 Caption = 'Button4_分块求平均阈值,按块⼆值化'117 TabOrder = 2118 OnClick = Button4Click119end120object EditX: TEdit121 Left = 567122 Top = 378123 Width = 49124 Height = 21125 ImeName = '中⽂(简体) - 搜狗拼⾳输⼊法'126 TabOrder = 3127 Text = 'EditX'128 OnChange = EditXChange129end130object EditY: TEdit131 Left = 649132 Top = 379133 Width = 47134 Height = 21135 ImeName = '中⽂(简体) - 搜狗拼⾳输⼊法'136 TabOrder = 4137 Text = 'EditY'138 OnChange = EditXChange139end140object OpenPictureDialog1: TOpenPictureDialog141 Filter = 'Bitmaps (*.bmp)|*.bmp'142 Left = 72143 Top = 368144end145end------------Form结束。
delphi sqlite3_columnblob 的用法

delphi sqlite3_columnblob 的用法Delphi 中的 SQLite3_ColumnBlob 函数用于获取指定行列的数据,并以 BLOB 类型返回。
函数定义如下:function sqlite3_columnblob(stmt: Psqlite3_stmt;iCol: Integer): Pointer;参数说明:- stmt: 指向已经执行的 SQL 语句的 sqlite3_stmt 对象的指针。
- iCol: 要获取数据的列索引。
索引从0开始计数。
返回值是一个指向 BLOB 数据的指针,或者如果列包含NULL 值,则返回 nil。
以下是一个示例代码,演示了如何使用 SQLite3_ColumnBlob 函数来获取 BLOB 数据:```delphivarstmt: Psqlite3_stmt;blobData: Pointer;blobLen: Integer;begin// Prepare the SQL statementsqlite3_prepare_v2(DatabaseHandle, 'SELECT blob_column FROM my_table', -1, @stmt, nil);// Step through the result set and fetch the blob datawhile sqlite3_step(stmt) = SQLITE_ROW dobegin// Get the blob data and its length using SQLite3_ColumnBlob and SQLite3_ColumnBytes functionsblobData := sqlite3_columnblob(stmt, 0);blobLen := sqlite3_columnbytes(stmt, 0);// Process the blob data// ...// Release the blob memory if necessarysqlite3_free(blobData);end;// Finalize the statementsqlite3_finalize(stmt);end;```注意:完成对 BLOB 数据的处理后,如果内存不再使用,需要调用 sqlite3_free 函数手动释放 BLOB 内存空间。
delphi createbolbstream 用法

delphi createbolbstream 用法Delphi CreateBlobStream 用法1. CreateBlobStream 方法概述•TDataSet类中的CreateBlobStream方法可用于创建一个用于读取、写入、编辑和保存二进制大对象(BLOB)字段的流。
2. CreateBlobStream 方法参数•Field:指定要处理的字段对象。
•Mode:指定流的访问模式,可使用bmRead(只读)、bmWrite (只写)、bmReadWrite(读写)和bmAppend(追加)等模式。
3. 使用 CreateBlobStream 读取 BLOB 字段procedure ReadBlobField(Field: TBlobField);varStream: TStream;Buffer: TBytes;beginStream := (Field, bmRead);trySetLength(Buffer, );(Buffer[0], );// 使用 Buffer 对象处理 BLOB 数据// ...finally;end;end;代码解释:•首先,通过CreateBlobStream方法创建一个只读的流对象,并传入要处理的Field和bmRead模式。
•然后,利用 `获取 BLOB 字段的大小,并根据其大小设置Buffer` 的长度。
•使用 `将 BLOB 数据读取到Buffer` 中,从而可以对其进行处理。
4. 使用 CreateBlobStream 写入 BLOB 字段procedure WriteBlobField(Field: TBlobField; const B uffer: TBytes);varStream: TStream;beginStream := (Field, bmReadWrite);try(Buffer[0], Length(Buffer));finally;end;end;代码解释:•类似于读取 BLOB 字段的示例,这次使用CreateBlobStream 方法创建一个读写的流对象,并传入要处理的Field和bmReadWrite模式。
基于DELPHI的图象压缩处理

JPEG的编码流程图: JPG的解码流程图: JPEG的解码流程图: 的解码流程图
BMP转换为JPEG: BMP转换为JPEG: 转换为
先设计好闪现窗体(窗体名字为flashform), 先设计好闪现窗体(窗体名字为flashform),但是保 flashform),但是保 存单元文件时,我用的是Flash,并运行, Flash,并运行 存单元文件时,我用的是Flash,并运行,直至看到了 效果 然后将Form1修改为Main,将单元文件由Unit1.pas 然后将Form1修改为Main,将单元文件由Unit1.pas修 Form1修改为Main,将单元文件由Unit1.pas修 Radar.pas,再运行 看到效果后,可以运行一下, 再运行, 改为 Radar.pas,再运行,看到效果后,可以运行一下, 再看看有没有闪现窗体和刚才设计的各种组件。 再看看有没有闪现窗体和刚才设计的各种组件。雷 达图像处理===图标为雷达图===成功!===== ===图标为雷达图===成功!=====我为各 达图像处理===图标为雷达图===成功!=====我为各 个菜单加了图标, panel设计的工具栏 设计的工具栏, 个菜单加了图标,用panel设计的工具栏,不加状态栏 了==== 接着就设计About对话框,然后运行看效果( 接着就设计About对话框,然后运行看效果(当然要 About对话框 在主窗体的相关按钮上添加相应的代码) 在主窗体的相关按钮上添加相应的代码),另外还要 在该对话框上添加关闭的代码
2. 霍夫曼编码压缩 3. LZW压缩方法 LZW压缩方法 4. 算术压缩方法
DCT压缩算法分析与实现 DCT压缩算法分析与实现
系统模块总图: 系统模块总图:
DCT压缩算法: DCT压缩算法: 压缩算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
的 , 方 面 由 于 D l i D iae组 件 不 能 显 示 一 eh 中 b g p m
0 引 言
目前 , 开发 数 据 库应 用 程 序 不 仅 仅 需 要 处 理
Je pg格式 图片【 ; 一方 面 Bo 另 l b以二 进制 形式 存 储 , 占容量 较大 , 以数据 库将是 一个存 储 大量 所 所
行 速度 。
文 本或数 字数 据 , 多数 时候 数 据 库 同 时需 要 处 大 理 大量 的图像 数 据 。与 数据 库 中 的文 本 一样 , 数 据 库 中的图片就 必 须频 繁 的被 显 示 。D l i 有 e h具 p
强 大的数 据库 功能 , 常被 用来 开发 数 据 库 应 用 经 程序 。
c mp tr ,w ih b n s c n e in e t lh n i g aa p o e sn , r d c s te c n u t n o y t m e o u es hc r g o v ne c o Dep ii ma e d t r si g e u e h o s mp i f s se r — i c o s u c sa d i rv st e s e . o r e mp o e h p d n e Ke r s Dep ;B o ;i g a a y wo d : l h i l b ma e d t
由于 图片在 D l i e h 数据库 中都是 以 Bo p l b格 式存储
收稿 日期 :09—1 — 0 20 1 3 作者简介 : 胡开明( 94 17 一 ) 男 , , 湖南常德人 , 讲师 , 硕士。
了一定 的限制 , 文 在此 提 出一种 Bo 本 l b图像数 据
的处理 方 法 , 能够 解 决 D l i 处理 图像 数据 时 eh在 p
(e r e m urcn , ag n S ga Vciaa c iloe , a u u g n 22) Dp t noC p eSec G n o ns n o t ln T h c l e h g n a d g 11 am tf o t i e u d g o h ao d e naC l S o a G n o 5 6 n g
据时要 占用大量系统资源 , 影响运行速度的问题 , 章提 出了一 种 Bo 文 l b图像数 据的处理方法 , 以解决 D l 可 e—
pi h 在处理图像数据时受到的限制 , D lh 在处理 图像数据时更加方便 , 使 e i p 同时减少系统资源 的耗 费 , 提高运 行速度。
关 键词 : e h;l ; Dl iB b图像数据 p o
中图分类 号 :P 1 T31
文献标 识码 : A
Bl b I a e Da a Pr c s i g M e h d Ba e n Dep i o m g t o e sn t o sd o lh
HU K i n C N in u W NG Y xa amig HE Ja h a A u in
fl t dslyp t e i e r a adta dt dsl k s pa o o s m rsucs f cn es e a s o i a iu s t j gf m t n t a i a t e u tf yt ore et gt p do i p cr whp o h a pya l s e e a i h e f
第2 6卷
第 1 期
黄
石
理
工
学
院
学
报
V0l2 No _6 .1 Fe b 2 0 01
21 00年 2月
J RNAL OF HUA OU NGS NS l U E OFTE HN OG HII T T T C OL Y
文章编 号 :0 8— 2 5 2 1 0 — 0 2— 4 1 0 8 4 (0 0) 1 0 1 0
信息 的格式 文 件 。 当我 们 使 用 T b al 件 来 连 接 e组 数据库 时 , 操作 的对 象是 整个表 , 不管 表 内的数 据 是否是 所 需 要 的 , 户 所 得 的 数 据 都 是 未 经 “ 用 筛 选 ” 。这 样 , 的[ 将耗 费大 量 的 系统资 源 , 响 运 影
基 于 D lh 的一 种 Bo e i p l b图像 数 据 的处 理 方 法
胡开 明 陈建华 王玉贤
( 广东 松 山职 业技 术 学院 计 算机 系 , 广东 韶 关 522 ) 116
摘 要 : 为解决 Dl i b a 不能显示 Je 格式的图片, e h 中D i g p me pg 同时系统在显示数据表中的 B b图像字段数 l o
Ab t a t T i p p rp t o w r lb i g aa p o e sn t o o v h r b e e p i h t i g sr c : hs a e u sfr ad a B o ma e d t rc s ig me h d t s le t e p o lmsi D l h a ma e o n t Db
受 到 的 限制 , D lh 在 处理 图像数 据 时 更加 方 使 e i p
便。
第1 期
胡开明 陈建华
王玉贤 : 基于 D lh 的一种 Bo e i p lb图像数据的处理方法
l i p
在 处理 图像 时 , 种 类 型 的 图 片 格 式 是 可 利 几 用 的 , 常用 的格 式 包 括 Je 最 pg和 B p m 。其 中 Je pg 已被广 泛 接 受 , 为其 所 需 的 数 据 存 储 量 很 小 。 因