主页 > 人工智能  > 

Lazarus旋转图片(TImage、TBitmap)

Lazarus旋转图片(TImage、TBitmap)

想用Lazarus旋转图片,在QT上轻松就能做到的事情,在lazarus上却没有标准实现,只能用其他方式。找了挺多帖子,有这三种有效的方案。

第一种:不依赖其他控件 procedure TMainForm.RotateImage(Bitmap: TBitmap); var NewBitmap: TBitmap; X, Y: integer; begin // 创建新的位图对象,用于存储旋转后的图片 NewBitmap := TBitmap.Create; try // 设置新位图的宽度和高度,这里交换原位图的宽度和高度 NewBitmap.Width := Bitmap.Height; NewBitmap.Height := Bitmap.Width; // 遍历原位图的每个像素 for Y := 0 to Bitmap.Height - 1 do for X := 0 to Bitmap.Width - 1 do // 将原位图的像素按照旋转规则复制到新位图中 NewBitmap.Canvas.Pixels[Bitmap.Height - Y - 1, X] := Bitmap.Canvas.Pixels[X, Y]; // 清空原位图 Bitmap.Canvas.FillRect(0, 0, Bitmap.Width, Bitmap.Height); // 复制旋转后的位图到原位图 Bitmap.Assign(NewBitmap); finally // 释放新位图对象 NewBitmap.Free; end; end;

问题是,速度太慢、内存开销较大,一张1080P的图片运行一次要耗费2秒钟左右,太慢了。

第二种:依赖 TBGRABitmap,使用 TBGRAAffineBitmapTransform 进行变换 procedure TMainForm.RotateImage; var BGRAImg: TBGRABitmap; Affine: TBGRAAffineBitmapTransform; Temp: TBGRABitmap; OldWidth, OldHeight: integer; begin // 检查 Image1 中是否有图片 if Image1.Picture.Bitmap = nil then Exit; OldWidth := Image1.Picture.Bitmap.Width; OldHeight := Image1.Picture.Bitmap.Height; // 创建 TBGRABitmap 对象,并将 Image1 中的图片转换为 TBGRABitmap BGRAImg := TBGRABitmap.Create(Image1.Picture.Bitmap); try // 创建仿射变换对象 Affine := TBGRAAffineBitmapTransform.Create(BGRAImg); try // 先将图像平移到原点 Affine.Translate(-BGRAImg.Width div 2, -BGRAImg.Height div 2); // 向右旋转 90 度 Affine.RotateDeg(90); // 再平移回原来的位置 Affine.Translate(BGRAImg.Height div 2, BGRAImg.Width div 2); // 创建临时的 TBGRABitmap 对象,用于存储旋转后的图像 Temp := TBGRABitmap.Create(BGRAImg.Height, BGRAImg.Width, BGRAWhite); try // 使用仿射变换填充临时图像 Temp.FillPolyAntialias([PointF(0, 0), PointF(Temp.Width, 0), PointF(Temp.Width, Temp.Height), PointF(0, Temp.Height)], Affine); Image1.Picture.Clear; // 调整 Image1 控件的大小以适应旋转后的图片 Image1.Width := OldHeight; Image1.Height := OldWidth; // 将旋转后的图像用Image1绘制出 Temp.Draw(Image1.Canvas, 0, 0); finally // 释放临时图像对象 Temp.Free; end; finally // 释放仿射变换对象 Affine.Free; end; finally // 释放 TBGRABitmap 对象 BGRAImg.Free; end; end;

尤其要注意:uses BGRATransform;

速度很快,和第一个比快了30倍左右。

第三种,使用 TBGRABitmap procedure TMainForm.RotateImage; var BGRAImg: TBGRABitmap; OldWidth, OldHeight: integer; begin // 检查 Image1 中是否有图片 if Image1.Picture.Bitmap = nil then Exit; // 记录原始图片的宽度和高度 OldWidth := Image1.Picture.Bitmap.Width; OldHeight := Image1.Picture.Bitmap.Height; // 创建 TBGRABitmap 对象,并将 Image1 中的图片转换为 TBGRABitmap BGRAImg := TBGRABitmap.Create(Image1.Picture.Bitmap); try if RotationDeg = 1 then begin BGRAReplace(BGRAImg, BGRAImg.RotateCW()); //右转90度 end; if RotationDeg = 2 then begin BGRAReplace(BGRAImg, BGRAImg.RotateUD()); //翻转180度 end; if RotationDeg = 3 then begin BGRAReplace(BGRAImg, BGRAImg.RotateCCW()); //左转90度 end; // 清空 Image1 原有的图片 Image1.Picture.Clear; // 调整 Image1 控件的大小以适应旋转后的图片 if (RotationDeg = 1) or (RotationDeg = 3) then begin Image1.Width := OldHeight; Image1.Height := OldWidth; end; if (RotationDeg = 2) or (RotationDeg = 0) then begin Image1.Width := OldWidth; Image1.Height := OldHeight; end; BGRAImg.Draw(Image1.Canvas, 0, 0); finally // 释放 TBGRABitmap 对象 BGRAImg.Free; end; end;

这个是我个人测试内存开销最小的一个,速度和第二个相当。几乎肉眼看不到延迟。

也是我最后采纳的一个方案。

标签:

Lazarus旋转图片(TImage、TBitmap)由讯客互联人工智能栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Lazarus旋转图片(TImage、TBitmap)