分享一个浏览图片的类。GDI+的一个应用

kuangning 2012-03-28 11:02:01
前几天有人做了个360的界面 他说自己的没立体感。我叫他用GDI+画一个半透明的边框 他好像没理会。
故今天心血来潮 写了个浏览文件夹图片的类。给大家分享
借助gdi+库(该库的delphi单元在本站有下载,“阿发伯”提供)和Tpaintbox
下面是代码

unit fuImageListView;

interface

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

const
imgRectWidth = 110;
imgRectHeight = 150;
imgWidth = 60;
imgHeight =90;
ImgOffSetX = (imgRectWidth - imgWidth) div 2;
ImgOffsetY = 6;

type
PImageItem=^TImageItem;
TImageItem=record
fileName:string;
Rect:TRect;
ImgRect:TRect;
RGN:HRGN;
Name:string;
end;

TImageListView=class
private
FPaintBox: TPaintBox;
FLookDir: string;
FList : TList;
FFocusItem:PImageItem;
FSelectItem:PImageItem;
procedure SetLookDir(const Value: string);
function getCount: Integer;
function GetItems(index: Integer): PImageItem;
procedure SetFocusItem(const Value: PImageItem);
procedure SetSelectItem(const Value: PImageItem);
protected
procedure DrawImageList;
procedure DrawImage(const G:TGpGraphics;const P:PImageItem);
procedure PaintBoxPaint(Sender: TObject);
procedure PaintBoxMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure PaintBoxMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
function GetFocusItem(const X,Y : Integer):PImageItem;

public
property PaintBox : TPaintBox read FPaintBox;
constructor Create(const aPaintBox:TPaintBox);
destructor Destroy; override;
property LookDir : string read FLookDir write SetLookDir;
property Count : Integer read getCount;
procedure Delete(const Index:Integer);
procedure Clear;
property Items[index:Integer]: PImageItem read GetItems;
property FocusItem:PImageItem read FFocusItem write SetFocusItem;
property SelectItem:PImageItem read FSelectItem write SetSelectItem;
end;



implementation

uses
Math;

{ TImageListView }

procedure FillRectangle(const GDIgraphics:TGPGraphics;const X1,Y1:Integer;const X2:Integer;const Y2:Integer;
const Color:TColor;const penWidth:Integer ; const FillMode:Boolean;
const AlphaBlendValue:Byte );
var
SB: TGPSolidBrush;
P:TGpPen;
gdiColor:Cardinal;
left,right,top, bottom:Integer;
begin
left := min(X1,X2);
right := Max(x1,X2);
top := min (Y1,Y2);
bottom := Max(Y1,Y2) ;
gdiColor := ARGBFromTColor(Color);
gdiColor := (gdiColor and $FFFFFF) or (AlphaBlendValue shl 24);
try
GDIgraphics.SmoothingMode:= smAntiAlias;
if FillMode then
begin
SB := TGPSolidBrush.Create(gdiColor);
try
GDIgraphics.FillRectangle(sb,left,top,right-left,bottom-top);
except

end;
SB.Free;
end else
begin
P := TGpPen.Create(gdiColor,penWidth);
try
GDIgraphics.DrawRectangle(P,left,top,right-left,bottom-top);
except

end;

p.Free;
end;
except

end;

end;

procedure TImageListView.Clear;
begin
while Count>0 do
Delete(0);
end;

constructor TImageListView.Create(const aPaintBox: TPaintBox);
begin
FPaintBox := aPaintBox;
aPaintBox.OnPaint := PaintBoxPaint;
aPaintBox.OnMouseMove := PaintBoxMouseMove;
aPaintBox.OnMouseDown := PaintBoxMouseDown;
FList := TList.Create;
if FPaintBox.Parent <> nil then
FPaintBox.Parent.DoubleBuffered := True;
end;

procedure TImageListView.Delete(const Index: Integer);
var
P:PImageItem;
begin
P := Flist.Items[index];
DeleteObject(p.RGN);
Dispose(P);
Flist.Delete(index);
end;

destructor TImageListView.Destroy;
begin
Clear;
Flist.Free;
inherited;
end;

procedure TImageListView.DrawImage(const G: TGpGraphics; const P: PImageItem);
var
image : TGpImage;
rt: TGPRectF;
aZoom:Real;
strFormat: TGpStringFormat;
font: TGpFont;
rect1 :TGpRectF;
begin
image := TGpImage.Create(p.fileName);
if image.Width * image.Height >0 then
begin
g.InterpolationMode := imHighQualityBicubic;

aZoom := Min( imgWidth/image.Width,imgHeight/image.Height);
rt.Width :=image.Width*aZoom;
rt.Height :=image.Height*azoom;
rt.X := (imgWidth-image.Width*aZoom) / 2 + p.ImgRect.Left;
rt.Y := (imgHeight-image.Height*aZoom) / 2 +p.ImgRect.top;
g.DrawImage(image,rt, 0, 0, image.Width, image.Height, utPixel);
try


font := TGpFont.Create('arial', 10, []);
strFormat := TGpStringFormat.Create([]);
strFormat.Alignment := saCenter;
// strFormat.

// g.DrawString(p.Name, font, Brushs[$99000000],p.Rect.Left+imgRectWidth /2, p.Rect.Bottom-20, strFormat);
rect1.X :=p.Rect.Left;
rect1.Y := p.Rect.Bottom-55;
rect1.Width :=imgRectWidth-4;
rect1.Height := 55;

g.DrawString(p.Name, font, Brushs[$F0000000], rect1, strFormat)

except

end;
if Assigned(font) then

font.Free;
if Assigned(strFormat) then

strFormat.Free;

if FocusItem= P then
begin
FillRectangle(G, p.Rect.Left+2,p.Rect.Top+2,
p.Rect.Right-2,p.Rect.Bottom-2,RGB(209,229,252),1,True,20); //画半透明填充框
FillRectangle(G, p.Rect.Left+2,p.Rect.Top+2,
p.Rect.Right-2,p.Rect.Bottom-2,RGB(209,229,252),1,False,$FF); //画不透明外框
end;
if FSelectItem=p then
begin
FillRectangle(G, p.Rect.Left+2,p.Rect.Top+2,
p.Rect.Right-2,p.Rect.Bottom-2,RGB(32,97,193),1,True,20); //画半透明填充框
FillRectangle(G, p.Rect.Left+2,p.Rect.Top+2,
p.Rect.Right-2,p.Rect.Bottom-2,RGB(32,97,193),1,False,120); //画半透明外框
end;
end;
image.Free;

end;

procedure TImageListView.DrawImageList;
var
RowCount,ColCount:Integer;
P:PImageItem;
K:Integer;
I , J :Integer;

begin
if Assigned(FPaintBox) then
begin
ColCount := (FPaintBox.Width -25) div imgRectWidth;
if ColCount > 0 then
begin
RowCount := Flist.Count div ColCount;
if Flist.Count mod ColCount<>0 then
Inc(RowCount);
FPaintBox.Height := RowCount* imgRectHeight;

K := 0 ;
for I:= 0 to RowCount - 1 do
for J := 0 to ColCount - 1 do
begin
P := Flist.Items[K];
P^.Rect.Left := J*imgRectWidth;
P^.Rect.Top := I*imgRectHeight;
p^.Rect.Right := P^.Rect.Left + imgRectWidth;
p^.Rect.Bottom := P^.Rect.Top + imgRectHeight;
P^.ImgRect := Rect(P^.Rect.Left+ImgOffSetX,P^.Rect.Top + ImgOffsetY,
P^.Rect.Right-ImgOffSetX,P^.Rect.Bottom - ImgOffsetY) ;
P^.RGN := CreateRectRgn(P^.ImgRect.Left,P^.ImgRect.Top,P^.ImgRect.Right,P^.ImgRect.Bottom );
Inc(K);
if K>=Flist.Count then
Break;
end;

end;
end;
end;

function TImageListView.getCount: Integer;
begin
Result := FList.Count;
end;

function TImageListView.GetFocusItem(const X, Y: Integer): PImageItem;
var
I:Integer;
begin
Result := nil;
for I := 0 to FList.Count - 1 do
begin
if ptinregion(Items[i].RGN,X,Y) then
begin
Result :=Items[i];
Break;
end;

end;

end;

function TImageListView.GetItems(index: Integer): PImageItem;
begin
Result := FList.Items[index];
end;



procedure TImageListView.PaintBoxMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
SelectItem:= GetFocusItem(x,y);
end;

procedure TImageListView.PaintBoxMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);

begin
FocusItem:= GetFocusItem(x,y);


end;


procedure TImageListView.PaintBoxPaint(Sender: TObject);
var
G: TGpGraphics;
I:Integer;
begin
G := TGpGraphics.Create(FPaintBox.Canvas.Handle);
for I := 0 to FList.Count - 1 do
DrawImage(G,FList.Items[i]);


G.Free;
end;

procedure TImageListView.SetFocusItem(const Value: PImageItem);
begin
if FFocusItem <> Value then
begin
FFocusItem := Value;
FPaintBox.Repaint;
end;


end;

procedure TImageListView.SetLookDir(const Value: string);
var
SearchRec : TSearchRec;
Attr : integer;
Found : integer;
ExtFileName:string;
temstr:string;
P:PImageItem;
begin
FLookDir := Value;
Clear;
temstr:=Value+ '*.*';
Attr := faAnyFile;
Found := FindFirst(temstr, Attr, SearchRec);
while Found = 0 do
begin
ExtFileName:=LowerCase(ExtractFileExt(SearchRec.Name));
if (ExtFileName= '.bmp') or (ExtFileName= '.jpg') or ((ExtFileName= '.jpeg')) then
begin
New(P);
P^.fileName := FLookDir+SearchRec.Name;
P^.Name := SearchRec.Name;
FList.Add(P)
end;
Found := FindNext(SearchRec);
end;
FindClose(SearchRec);
DrawImageList;
end;

procedure TImageListView.SetSelectItem(const Value: PImageItem);
begin
if FSelectItem <> Value then
begin
FSelectItem := Value;
FPaintBox.Repaint;
end;

end;

end.




调用的时候很简单,窗体上方一个TScrollBox然后在里面放一个TPaintBox设置PaintBox的Align为altop
创建上面的类,并设置LOOKDIR属性,就能看见图片信息,选中和Focus看看效果
...全文
264 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
山东蓝鸟贵薪 2012-04-08
  • 打赏
  • 举报
回复
将代码打包传上来吧
学习学习
山东蓝鸟贵薪 2012-04-08
  • 打赏
  • 举报
回复
分享呀,谢谢了,学习中
kuangning 2012-04-03
  • 打赏
  • 举报
回复
我是用的阿法伯的 gdi+库
D2007
yygtpynn 2012-04-01
  • 打赏
  • 举报
回复
刚才的问题解决了,是因为fuImageListView单元没有引用GdiPlusIntf单元,楼主是怎么编译通过的呢?
出现另外一个问题,设置LOOKDIR属性后在执行drawimage时报AV错误,这里看不懂了。
能否把你的代码发到我邮箱 32700064@qq.com
yygtpynn 2012-04-01
  • 打赏
  • 举报
回复
请教楼主 在D哪个版本下开发的?
我试了在 D7和D2007编译时提示
smAntiAlias 、TGPRectF和imHighQualityBicubic没有声明
lqfcu2 2012-03-30
  • 打赏
  • 举报
回复
看来都是想看效果图的啊~~哈哈,
kuangning 2012-03-30
  • 打赏
  • 举报
回复
如上。。图。
刚看见 版主删除几个人的留言,也不知道他们说了什么
kuangning 2012-03-30
  • 打赏
  • 举报
回复

一剑飘雪 2012-03-30
  • 打赏
  • 举报
回复
我也希望看到一个效果图
呵呵
oushengfen 2012-03-30
  • 打赏
  • 举报
回复
效果图,呵呵。。。。。。。。。。。。。。。
ccrun.com 2012-03-29
  • 打赏
  • 举报
回复
配个效果图就更好了。

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧