当前位置: 首页 > news >正文

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;

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

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

相关文章:

  • 我们来学HTTP/TCP -- 三次握手?
  • 2025 pwn_A_childs_dream
  • C++中 map的基本用法
  • 春招项目=图床+ k8s 控制台(唬人专用)
  • 委托构造函数与继承构造函数
  • nginx反向代理负载均衡
  • 数据结构 day02
  • 2024年度中国家居冠军榜公布,冠珠瓷砖荣获“行业领军品牌”
  • 深度学习(1)-简单神经网络示例
  • 力扣 乘积最大子数组
  • 【数据结构基础_链表】
  • 基因组数据分析中涉及基因结构的问题
  • 论文解读之DeepSeek R1
  • 【函数题】6-10 二分查找
  • 全方位探索DeepSeek
  • ROS turtlesim 无法通过 键盘控制 turtle 移动
  • DeepSeek与ChatGPT:AI语言模型的全面对决
  • 单链表的概念,结构和优缺点
  • 使用Python和OpenCV实现图像像素压缩与解压
  • Llama3.0论文学习笔记: The Llama 3 Herd of Models
  • 三大猪企4月生猪销量同比均增长,销售均价同比小幅下降
  • 新疆维吾尔自治区乌鲁木齐市米东区政协原副主席朱文智被查
  • 欧盟公布对美关税反制清单,瞄准美国飞机等产品
  • 巴基斯坦信德省卡拉奇发生爆炸
  • 菲护卫艇企图侵闯中国黄岩岛领海,南部战区:依法依规跟踪监视、警告驱离
  • 2025江西跨境电子商务发展交流会召开,探索行业发展新趋势