600*600圆形
使用的RotateImage旋转锯齿比较明显
寻找无锯齿的图片中心旋转 方法(要可形成连续旋转)
使用的RotateImage旋转锯齿比较明显
寻找无锯齿的图片中心旋转 方法(要可形成连续旋转)
解决方案 »
- combobox中的值
- 用fastreport做报表,怎么画表格??
- 用hook拦截键盘输入,怎么判断左右shift,ctrl?
- 将ADODataset连接的表,转换成创建该表的sql语句。有什么好的思路!来者有分!
- 用Socket写的接收数据的服务器程序,为何一接收中文便显示乱码,客户端是用C#写的,发回客户端的中文可以正常被显示!!
- 三层结构数据更新问题,,急!!!
- 突发奇想,定义一个含4单独byte的Cardinal类型,梆!状墙了
- Delphi程序,在xp下打印不出来的问题怎么解决?
- 图片格式转换之——经典问题?谁能帮忙解决?
- sql语句的写法:如何从一个表中返回只有一条的记录?
- dbgrideh 中以哪种方式实现 动态模糊方式调取数据
- GID+ 加求助 path.warp
procedure DrawRotateAtBmp(FSrcBmp ,FDstBmp: TBitmap; FDstRect : TGpRectF; FRotate : Single ; bCreateMask : Boolean = True);
var aGpSrcBmp,aGpAASrcBmp : TGpBitmap;
Gd,aAAGd : TGpGraphics;
aMatrix : TGpMatrix;
FCenter : TGpPointF;
aAASrcBmp ,aAADstBmp,Bmp : TBitmap;
aAADstRect : TGpRectF;
i, j : Integer;
aMask : TBitmap;
pData,pMask : pByteArray;
begin
Bmp := TBitmap.Create;
Bmp.Assign(FDstBmp); aGpSrcBmp := TGpBitmap.Create(FSrcBmp.Handle,FSrcBmp.Palette); //转换为tgpbitmap
aAASrcBmp := TBitmap.Create;
aAASrcBmp.Width := FSrcBmp.Width * 4;
aAASrcBmp.Height := FSrcBmp.Height * 4;
aAASrcBmp.Canvas.CopyRect(aAASrcBmp.Canvas.ClipRect,FSrcBmp.Canvas,FSrcBmp.Canvas.ClipRect);
//将放大四倍后的原始图像转换为tgpbitmap对象
aGpAASrcBmp := TGpBitmap.Create(aAASrcBmp.Handle,aAASrcBmp.Palette);
//将目标图像放大四倍
aAADstBmp :=TBitmap.Create;
aAADstBmp.PixelFormat := FDstBmp.PixelFormat;
aAADstBmp.Width := FDstBmp.Width * 4 ;
aAADstBmp.Height := FDstBmp.Height * 4;
aAADstBmp.Canvas.CopyRect(aAADstBmp.Canvas.ClipRect,FDstBmp.Canvas,FDstBmp.Canvas.ClipRect); FCenter.X := Round(FDstRect.X + FDstRect.Width / 2); //旋转中心点 + FDispRect.X
FCenter.Y := Round(FDstRect.Y + FDstRect.Height / 2);
//按原始尺寸将fsrcbmp绘制到fdstbmp
try
Gd := TGpGraphics.Create(FDstBmp.Canvas.Handle);
aMatrix := TGpMatrix.Create;
aMatrix.RotateAt(FRotate,FCenter);
Gd.SetTransform(aMatrix); // aGpSrcBmp
Gd.DrawImage(aGpSrcBmp,FDstRect,0,0, aGpSrcBmp.Width,aGpSrcBmp.Height,utPixel);
finally
aMatrix.Free;
Gd.Free;
end;
if bCreateMask then
begin
//单独将原始图像ALPHA通道插值处理 ,保存旋转后的通道,如原始图像为24位,则不需要该操作
aMask := TBitmap.Create;
aMask.PixelFormat := pf32bit;
aMask.Width := FDstBmp.Width;
aMask.Height := FDstBmp.Height;
CreateAlpha(FSrcBmp,FDstBmp,FDstRect,FRotate,False);
aMask.Assign(FDstBmp);
end; FCenter.X := Round(FDstRect.X * 4 + FDstRect.Width * 4/ 2);
FDispRect.X * 4 + FDispRect.Y * 4 +
FCenter.Y := Round(FDstRect.Y * 4 + FDstRect.Height * 4/ 2);
with aAADstRect do
begin
x:=FDstRect.X * 4 ; Y := FDstRect.Y * 4; Width := FDstRect.Width * 4;
Height := FDstRect.Height * 4;
end;
//绘制全部放大四倍后的图像
try
aAAGd := TGpGraphics.Create(aAADstBmp.Canvas.Handle);
aMatrix := TGpMatrix.Create;
aMatrix.RotateAt(FRotate,FCenter);
aAAGd.SetTransform(aMatrix);
aAAGd.DrawImage(aGpAASrcBmp,aAADstRect,
0,0,aGpAASrcBmp.Width,aGpAASrcBmp.Height ,utPixel);
finally
aMatrix.Free;
aAAGd.Free;
end;
//按4倍插值进行位图反走样,注意必须是24位
//参数:1:按原始尺寸绘制后的图像;2:按放大四倍后绘制图像;3,4:原始目标图像大小
CreateAAImage(FDstBmp.Canvas.Handle,aAADstBmp.Canvas.Handle,4,FDstBmp.Width,FDstBmp.Height,FDstBmp.PixelFormat);
//将插值处理后的通道赋给目标图像,如fsrcbmp为24位,则无需要处理
if bCreateMask and (Assigned(aMask)) then
begin
for i := 0 to FDstBmp.Height - 1 do
begin
pData := FDstBmp.ScanLine[i];
pMask := aMask.ScanLine[i];
for j := 0 to FDstBmp.Width - 1 do
begin
pData[j * 4 + 3] := pMask[j * 4 + 3];
end;
end;
aMask.Free;
end;
FreeAndNil(aGpSrcBmp);
FreeAndNil(aGpAASrcBmp);
FreeAndNil(aAADstBmp);
FreeAndNil(aAASrcBmp);
FreeAndNil(Bmp);
end;procedure CreateAAImage(hAADC : HDC; hSrcDc : HDC; scale : Integer;aWidth ,aHeight : Integer ; pf : Graphics.TPixelFormat = pf24bit);
var hSrcBitmap,hAABitmap : HBITMAP;
srcWidth ,srcHeight ,srcPitch,srcSize : Integer;
dstWidth, dstHeight ,dstPitch,dstSize : Integer;
lpSrcBits ,lpDstBits: array of Byte;
gridSize : Integer;
resultRed, resultGreen, resultBlue,resultAlpha : Integer;
dstX, dstY, dstOffset : Integer;
srcX, srcY, srcOffset : Integer;
tmpX, tmpY, tmpOffset : Integer;
X,Y,i,j ,nType:Integer;
begin
case pf of
pf24bit : nType := 3;
pf32bit : nType := 4;
end;
srcWidth := scale * awidth;
srcHeight := scale * aHeight;
srcPitch := srcWidth * nType;
srcSize := srcHeight * srcPitch;
SetLength(lpSrcBits,srcSize);
hSrcBitmap := HBITMAP(GetCurrentObject(hSrcDc,OBJ_BITMAP));
GetBitmapBits(hSrcBitmap, srcSize, lpSrcBits);
dstWidth := aWidth;
dstHeight := aHeight;
dstPitch := dstWidth * nType;
dstSize := dstHeight * dstPitch;
SetLength(lpDstBits,dstSize);
hAABitmap := HBITMAP(GetCurrentObject(hAADC, OBJ_BITMAP));
GetBitmapBits(hAABitmap, dstSize, lpDstBits); gridSize := scale * scale;
dstX := 0; dstY := 0;
for y := 1 to dstHeight - 2 do
begin
dstX := 0; srcX := 0;
srcY := (y * scale) * srcPitch;
for X := 1 to dstWidth - 2 do
begin
srcX := (x * scale) * nType;
srcOffset := srcY + srcX;
resultRed := 0; resultGreen := 0;
resultBlue := 0; resultAlpha := 0;
tmpY := -srcPitch;
for i := 0 to scale - 1 do
begin
tmpX := -nType;
for j := 0 to scale - 1 do
begin
tmpOffset := tmpY + tmpX;
if nType = 4 then
resultAlpha := resultAlpha + lpSrcBits[srcOffset + tmpOffset + 3];
resultRed := resultRed + lpSrcBits[srcOffset + tmpOffset + 2];
resultGreen := resultGreen + lpSrcBits[srcOffset + tmpOffset + 1];
resultBlue := resultBlue + lpSrcBits[srcOffset + tmpOffset];
tmpX := tmpX + nType;
end;
tmpY := tmpY + srcPitch;
end;
dstOffset := dstY + dstX;
if nType = 4 then
lpDstBits[dstOffset + 3] := BYTE(Round(resultAlpha / gridSize));
lpDstBits[dstOffset + 2] := BYTE(Round(resultRed / gridSize));
lpDstBits[dstOffset + 1] := BYTE(Round(resultGreen / gridSize));
lpDstBits[dstOffset] := BYTE(Round(resultBlue / gridSize));
dstX := dstX + nType;
end;
dstY := dstY + dstPitch;
end;
SetBitmapBits(hAABitmap, dstSize, lpDstBits);
lpSrcBits := nil;
lpDstBits := nil;
end;procedure CreateAlpha(FSrcbmp,FDstBmp : TBitmap;FDstRect : TGpRectF;FRotate : Single;bCreateMask : Boolean = True);
var pDst,pSrc : pByteArray;
aMask,aDstMask : TBitmap;
i , j : Integer;
begin
aDstMask := TBitmap.Create;
aDstMask.PixelFormat := pf24bit;
aDstMask.Width := FDstBmp.Width;
aDstMask.Height := FDstBmp.Height;
aDstMask.Canvas.Brush.Color := clBlack;
aDstMask.Canvas.FillRect(aDstMask.Canvas.ClipRect);
aMask := TBitmap.Create;
aMask.PixelFormat := pf24bit;
aMask.Width := FSrcBmp.Width;
aMask.Height := FSrcBmp.Height;
for i := 0 to FSrcBmp.Height - 1 do
begin
pDst := aMask.ScanLine[i];
pSrc := FSrcBmp.ScanLine[i];
for j := 0 to FSrcBmp.Width - 1 do
begin
pDst[j * 3 ] := pSrc[j * 4 + 3];
pDst[j * 3 + 1] := pSrc[j * 4 + 3];
pDst[j * 3 + 2] := pSrc[j * 4 + 3];
end;
end;
DrawRotateAtBmp(aMask,aDstMask,FDstRect,FRotate,False);
for i := 0 to FDstBmp.Height - 1 do
begin
pDst := FDstBmp.ScanLine[i];
pSrc := aDstMask.ScanLine[i];
for j := 0 to FDstBmp.Width - 1 do
begin
pDst[j * 4 + 3] := pSrc[j * 3];
end;
end;
aDstMask.Free;
aMask.Free;
end;
procedure DrawRotateAtBmp(FSrcBmp ,FDstBmp: TBitmap; FDstRect : TGpRectF; FRotate : Single ; bCreateMask : Boolean = True);
var aGpSrcBmp,aGpAASrcBmp : TGpBitmap;
Gd,aAAGd : TGpGraphics;
aMatrix : TGpMatrix;
FCenter : TGpPointF;
aAASrcBmp ,aAADstBmp,Bmp : TBitmap;
aAADstRect : TGpRectF;
i, j : Integer;
aMask : TBitmap;
pData,pMask : pByteArray;
begin
Bmp := TBitmap.Create;
Bmp.Assign(FDstBmp); aGpSrcBmp := TGpBitmap.Create(FSrcBmp.Handle,FSrcBmp.Palette); //转换为tgpbitmap
aAASrcBmp := TBitmap.Create;
aAASrcBmp.Width := FSrcBmp.Width * 4;
aAASrcBmp.Height := FSrcBmp.Height * 4;
aAASrcBmp.Canvas.CopyRect(aAASrcBmp.Canvas.ClipRect,FSrcBmp.Canvas,FSrcBmp.Canvas.ClipRect);
//将放大四倍后的原始图像转换为tgpbitmap对象
aGpAASrcBmp := TGpBitmap.Create(aAASrcBmp.Handle,aAASrcBmp.Palette);
//将目标图像放大四倍
aAADstBmp :=TBitmap.Create;
aAADstBmp.PixelFormat := FDstBmp.PixelFormat;
aAADstBmp.Width := FDstBmp.Width * 4 ;
aAADstBmp.Height := FDstBmp.Height * 4;
aAADstBmp.Canvas.CopyRect(aAADstBmp.Canvas.ClipRect,FDstBmp.Canvas,FDstBmp.Canvas.ClipRect); FCenter.X := Round(FDstRect.X + FDstRect.Width / 2); //旋转中心点 + FDispRect.X
FCenter.Y := Round(FDstRect.Y + FDstRect.Height / 2);
//按原始尺寸将fsrcbmp绘制到fdstbmp
try
Gd := TGpGraphics.Create(FDstBmp.Canvas.Handle);
aMatrix := TGpMatrix.Create;
aMatrix.RotateAt(FRotate,FCenter);
Gd.SetTransform(aMatrix); // aGpSrcBmp
Gd.DrawImage(aGpSrcBmp,FDstRect,0,0, aGpSrcBmp.Width,aGpSrcBmp.Height,utPixel);
finally
aMatrix.Free;
Gd.Free;
end;
if bCreateMask then
begin
//单独将原始图像ALPHA通道插值处理 ,保存旋转后的通道,如原始图像为24位,则不需要该操作
aMask := TBitmap.Create;
aMask.PixelFormat := pf32bit;
aMask.Width := FDstBmp.Width;
aMask.Height := FDstBmp.Height;
CreateAlpha(FSrcBmp,FDstBmp,FDstRect,FRotate,False);
aMask.Assign(FDstBmp);
end; FCenter.X := Round(FDstRect.X * 4 + FDstRect.Width * 4/ 2);
FDispRect.X * 4 + FDispRect.Y * 4 +
FCenter.Y := Round(FDstRect.Y * 4 + FDstRect.Height * 4/ 2);
with aAADstRect do
begin
x:=FDstRect.X * 4 ; Y := FDstRect.Y * 4; Width := FDstRect.Width * 4;
Height := FDstRect.Height * 4;
end;
//绘制全部放大四倍后的图像
try
aAAGd := TGpGraphics.Create(aAADstBmp.Canvas.Handle);
aMatrix := TGpMatrix.Create;
aMatrix.RotateAt(FRotate,FCenter);
aAAGd.SetTransform(aMatrix);
aAAGd.DrawImage(aGpAASrcBmp,aAADstRect,
0,0,aGpAASrcBmp.Width,aGpAASrcBmp.Height ,utPixel);
finally
aMatrix.Free;
aAAGd.Free;
end;
//按4倍插值进行位图反走样,注意必须是24位
//参数:1:按原始尺寸绘制后的图像;2:按放大四倍后绘制图像;3,4:原始目标图像大小
CreateAAImage(FDstBmp.Canvas.Handle,aAADstBmp.Canvas.Handle,4,FDstBmp.Width,FDstBmp.Height,FDstBmp.PixelFormat);
//将插值处理后的通道赋给目标图像,如fsrcbmp为24位,则无需要处理
if bCreateMask and (Assigned(aMask)) then
begin
for i := 0 to FDstBmp.Height - 1 do
begin
pData := FDstBmp.ScanLine[i];
pMask := aMask.ScanLine[i];
for j := 0 to FDstBmp.Width - 1 do
begin
pData[j * 4 + 3] := pMask[j * 4 + 3];
end;
end;
aMask.Free;
end;
FreeAndNil(aGpSrcBmp);
FreeAndNil(aGpAASrcBmp);
FreeAndNil(aAADstBmp);
FreeAndNil(aAASrcBmp);
FreeAndNil(Bmp);
end;procedure CreateAAImage(hAADC : HDC; hSrcDc : HDC; scale : Integer;aWidth ,aHeight : Integer ; pf : Graphics.TPixelFormat = pf24bit);
var hSrcBitmap,hAABitmap : HBITMAP;
srcWidth ,srcHeight ,srcPitch,srcSize : Integer;
dstWidth, dstHeight ,dstPitch,dstSize : Integer;
lpSrcBits ,lpDstBits: array of Byte;
gridSize : Integer;
resultRed, resultGreen, resultBlue,resultAlpha : Integer;
dstX, dstY, dstOffset : Integer;
srcX, srcY, srcOffset : Integer;
tmpX, tmpY, tmpOffset : Integer;
X,Y,i,j ,nType:Integer;
begin
case pf of
pf24bit : nType := 3;
pf32bit : nType := 4;
end;
srcWidth := scale * awidth;
srcHeight := scale * aHeight;
srcPitch := srcWidth * nType;
srcSize := srcHeight * srcPitch;
SetLength(lpSrcBits,srcSize);
hSrcBitmap := HBITMAP(GetCurrentObject(hSrcDc,OBJ_BITMAP));
GetBitmapBits(hSrcBitmap, srcSize, lpSrcBits);
dstWidth := aWidth;
dstHeight := aHeight;
dstPitch := dstWidth * nType;
dstSize := dstHeight * dstPitch;
SetLength(lpDstBits,dstSize);
hAABitmap := HBITMAP(GetCurrentObject(hAADC, OBJ_BITMAP));
GetBitmapBits(hAABitmap, dstSize, lpDstBits); gridSize := scale * scale;
dstX := 0; dstY := 0;
for y := 1 to dstHeight - 2 do
begin
dstX := 0; srcX := 0;
srcY := (y * scale) * srcPitch;
for X := 1 to dstWidth - 2 do
begin
srcX := (x * scale) * nType;
srcOffset := srcY + srcX;
resultRed := 0; resultGreen := 0;
resultBlue := 0; resultAlpha := 0;
tmpY := -srcPitch;
for i := 0 to scale - 1 do
begin
tmpX := -nType;
for j := 0 to scale - 1 do
begin
tmpOffset := tmpY + tmpX;
if nType = 4 then
resultAlpha := resultAlpha + lpSrcBits[srcOffset + tmpOffset + 3];
resultRed := resultRed + lpSrcBits[srcOffset + tmpOffset + 2];
resultGreen := resultGreen + lpSrcBits[srcOffset + tmpOffset + 1];
resultBlue := resultBlue + lpSrcBits[srcOffset + tmpOffset];
tmpX := tmpX + nType;
end;
tmpY := tmpY + srcPitch;
end;
dstOffset := dstY + dstX;
if nType = 4 then
lpDstBits[dstOffset + 3] := BYTE(Round(resultAlpha / gridSize));
lpDstBits[dstOffset + 2] := BYTE(Round(resultRed / gridSize));
lpDstBits[dstOffset + 1] := BYTE(Round(resultGreen / gridSize));
lpDstBits[dstOffset] := BYTE(Round(resultBlue / gridSize));
dstX := dstX + nType;
end;
dstY := dstY + dstPitch;
end;
SetBitmapBits(hAABitmap, dstSize, lpDstBits);
lpSrcBits := nil;
lpDstBits := nil;
end;procedure CreateAlpha(FSrcbmp,FDstBmp : TBitmap;FDstRect : TGpRectF;FRotate : Single;bCreateMask : Boolean = True);
var pDst,pSrc : pByteArray;
aMask,aDstMask : TBitmap;
i , j : Integer;
begin
aDstMask := TBitmap.Create;
aDstMask.PixelFormat := pf24bit;
aDstMask.Width := FDstBmp.Width;
aDstMask.Height := FDstBmp.Height;
aDstMask.Canvas.Brush.Color := clBlack;
aDstMask.Canvas.FillRect(aDstMask.Canvas.ClipRect);
aMask := TBitmap.Create;
aMask.PixelFormat := pf24bit;
aMask.Width := FSrcBmp.Width;
aMask.Height := FSrcBmp.Height;
for i := 0 to FSrcBmp.Height - 1 do
begin
pDst := aMask.ScanLine[i];
pSrc := FSrcBmp.ScanLine[i];
for j := 0 to FSrcBmp.Width - 1 do
begin
pDst[j * 3 ] := pSrc[j * 4 + 3];
pDst[j * 3 + 1] := pSrc[j * 4 + 3];
pDst[j * 3 + 2] := pSrc[j * 4 + 3];
end;
end;
DrawRotateAtBmp(aMask,aDstMask,FDstRect,FRotate,False);
for i := 0 to FDstBmp.Height - 1 do
begin
pDst := FDstBmp.ScanLine[i];
pSrc := aDstMask.ScanLine[i];
for j := 0 to FDstBmp.Width - 1 do
begin
pDst[j * 4 + 3] := pSrc[j * 3];
end;
end;
aDstMask.Free;
aMask.Free;
end;
GDI
我不会把四周搞透明