问题来源
群友提问,如何将一定区域内图像进行放大。
特定区域图像放大
思路
使用StretchBlt函数进行图像缩放,这里函数结构为:
function StretchBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc, SrcWidth, SrcHeight: Integer; Rop: DWORD): BOOL;
DestDC: HDC; //为句柄类型,为目标画布句柄
X, Y, Width, Height: Integer;//X,Y为目标画布起始坐标。Width, Height为目标画布宽高。
SrcDC: HDC;//为句柄类型,图像源画布句柄。
XSrc, YSrc, SrcWidth, SrcHeight: Integer;//XSrc, YSrc为源画布起始坐标。SrcWidth, SrcHeight: Integer;为源图像宽高。
Rop: DWORD;//为DWORD类型,为图像载入模式,模式参数为常量。
- 由此函数可得代码写法如下:
procedure TForm1.Big(x, y: integer); var Bmp1, bmp2: TBitmap; begin Bmp1 := TBitmap.Create; bmp2 := TBitmap.Create; bmp2.Width := 300; bmp2.Height := 300; Bmp1.Assign(Image1.Picture.Graphic); StretchBlt(bmp2.Canvas.Handle, 0, 0, 300, 300, Bmp1.Canvas.Handle, x - 40, y - 40, 40, 40, SRCCOPY); Image3.Picture.Assign(bmp2); end;
- 源画布为image,并在image的OnMouseMove事件写下:
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin Big(X, Y); end;
- 实际效果如下:
- 其中 Rop: DWORD;参数有如下常量值可供选择,作为不同的显示处理结果:
编译类型 参数常量 16进制常量 指定结果
{$EXTERNALSYM SRCCOPY} | SRCCOPY | $00CC0020 | dest = source |
---|---|---|---|
{$EXTERNALSYM SRCPAINT} | SRCPAINT | $00EE0086 | dest = source OR dest |
{$EXTERNALSYM SRCAND} | SRCAND | $008800C6 | dest = source AND dest |
{$EXTERNALSYM SRCINVERT} | SRCINVERT | $00660046 | dest = source XOR dest |
{$EXTERNALSYM SRCERASE} | SRCERASE | $00440328 | dest = source AND (NOT dest ) |
{$EXTERNALSYM NOTSRCCOPY} | NOTSRCCOPY | $00330008 | dest = (NOT source) |
{$EXTERNALSYM NOTSRCERASE} | NOTSRCERASE | $001100A6 | dest = (NOT src) AND (NOT dest) |
{$EXTERNALSYM MERGECOPY} | MERGECOPY | $00C000CA | dest = (source AND pattern) |
{$EXTERNALSYM MERGEPAINT} | MERGEPAINT | $00BB0226 | dest = (NOT source) OR dest |
{$EXTERNALSYM PATCOPY} | PATCOPY | $00F00021 | dest = pattern |
{$EXTERNALSYM PATPAINT} | PATPAINT | $00FB0A09 | dest = DPSnoo |
{$EXTERNALSYM PATINVERT} | PATINVERT | $005A0049 | dest = pattern XOR dest |
{$EXTERNALSYM DSTINVERT} | DSTINVERT | $00550009 | dest = (NOT dest) |
{$EXTERNALSYM BLACKNESS} | BLACKNESS | $00000042 | dest = BLACK |
{$EXTERNALSYM WHITENESS} | WHITENESS | $00FF0062 | dest = WHITE |
方法拓展
根据区域选择图像进行裁切,并放大选定区域图像
思路
定义全局变量,获取鼠标起点坐标
var
x0, y0: integer;
在image1的OnMouseDown事件中写下获取起点坐标的代码
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
x0 := X;
y0 := Y;
end;
在image1的OnMouseUp事件中写下以下代码,获得鼠标弹起时鼠标坐标的同时,将图像获取到bmp中装载,并进行处理后显示到image2和image3
procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
Bmp1, Bmp2: TBitmap;
drc, rc: TRect;
bmp4: TBitmap;
x1, y1: Integer;
begin
//显示裁切部分到image1
Image2.Picture := nil;
Image3.Picture := nil;
Bmp1 := TBitmap.Create;
Bmp1.Assign(Image1.Picture.Graphic);
rc := Rect(x0, y0, X, Y);
drc := Rect(0, 0, X - x0, Y - y0);
image2.Canvas.CopyRect(drc, Bmp1.Canvas, rc);
//将裁切部分放大显示到image3
bmp2 := TBitmap.Create;
bmp2.Width := 300;
bmp2.Height := 300;
if (X - x0) > (Y - y0) then
begin
x1 := 300;
y1 := Trunc((Y - y0) / (X - x0) * 300);
end
else if (X - x0) < (Y - y0) then
begin
y1 := 300;
x1 := Trunc((X - x0) / (Y - y0) * 300);
end;
StretchBlt(bmp2.Canvas.Handle, 0, 0, x1, y1, Bmp1.Canvas.Handle,x0, y0, X - x0, Y - y0,SRCCOPY);
Image3.Picture.Assign(bmp2);
Bmp1.Free;
bmp2.Free;
end;
实际效果如下: