zoukankan      html  css  js  c++  java
  • delphi 图像旋转

    网络搜集的 觉得有用的拿去吧  速度不错呢

    //旋转90°
    procedure Rotate(Bitmap: TBitmap);
    type
      THelpRGB = packed record
        rgb: TRGBTriple;
        dummy: byte;
      end;
    
      pRGBArray = ^TRGBArray;
      TRGBArray = array[0..32767] of TRGBTriple;
    var
      aStream: TMemorystream;
      //内存流
      header: TBITMAPINFO;
      dc: hDC;
      P: ^THelpRGB;
      x, y, b, h: Integer;
      RowOut: pRGBArray;
    begin
      //创建内存流
      aStream := TMemoryStream.Create;
      //设置大小,必须是4的倍数
      aStream.SetSize(Bitmap.Height * Bitmap.Width * 4);
      with header.bmiHeader do //操作位图文件
      begin
        biSize := SizeOf(TBITMAPINFOHEADER); //大小
        biWidth := Bitmap.Width; //位图宽
        biHeight := Bitmap.Height; //位图高
        biPlanes := 1;
        biBitCount := 32;
        //无压缩
        biCompression := 0;
        biSizeimage := aStream.Size;
        biXPelsPerMeter := 1; //水平分辨率
        biYPelsPerMeter := 1; //竖直分辨率
        biClrUsed := 0;
        biClrImportant := 0;
      end;
      dc := GetDC(0);
      P := aStream.Memory;
      GetDIBits(dc, Bitmap.Handle, 0, Bitmap.Height, P, header, dib_RGB_Colors);
      ReleaseDC(0, dc);
      b := bitmap.Height; //源图高
      h := bitmap.Width; //源图宽
      //指定要创建的位图的大小尺寸
      bitmap.Width := b;
      bitmap.height := h;
      for y := 0 to (h - 1) do
      begin
        rowOut := Bitmap.ScanLine[y]; //获取新的位图信息
        P := aStream.Memory; //设置文件指针
        inc(p, y); //指针移位
        for x := 0 to (b - 1) do
        begin
          rowout[x] := p^.rgb; //进行数据转移
          inc(p, h);
        end;
      end;
      aStream.Free; //释放资源
    end;
    

    后面这个不好找 

    //反向旋转90°
    procedure Rotate2(aBitmap: TBitmap);
    var
      nIdx, nOfs,
      x, y, i, nMultiplier: integer;
      nMemWidth, nMemHeight, nMemSize, nScanLineSize: LongInt;
      aScnLnBuffer: PChar;
      aScanLine: PByteArray;
    begin
      nMultiplier := 3;
      nMemWidth := aBitmap.Height;
      nMemHeight := aBitmap.Width;
      //实际需要内存大小
      nMemSize := nMemWidth * nMemHeight * nMultiplier;
      //开辟内存
      GetMem(aScnLnBuffer, nMemSize);
      try
        //Scanline的长度
        nScanLineSize := aBitmap.Width * nMultiplier;
        //为ScanLine分配内存
        GetMem(aScanLine, nScanLineSize);
        try
          for y := 0 to aBitmap.Height - 1 do
          begin
            //进行数据块的移动
            Move(aBitmap.ScanLine[y]^, aScanLine^, nScanLineSize);
            for x := 0 to aBitmap.Width - 1 do
            begin
              nIdx := ((aBitmap.Width - 1) - x) * nMultiplier;
              nOfs := (x * nMemWidth * nMultiplier) + (y * nMultiplier);
              for i := 0 to nMultiplier - 1 do
                Byte(aScnLnBuffer[nOfs + i]) := aScanLine[nIdx + i];
            end;
          end;
          //宽和高交换开始,逆时针旋转
          aBitmap.Height := nMemHeight;
          aBitmap.Width := nMemWidth;
          for y := 0 to nMemHeight - 1 do
          begin
            //数据移动
            nOfs := y * nMemWidth * nMultiplier;
            Move((@(aScnLnBuffer[nOfs]))^, aBitmap.ScanLine[y]^, nMemWidth *
              nMultiplier);
          end;
        finally
          //释放内存aScanLine
          FreeMem(aScanLine, nScanLineSize);
        end;
      finally
        //释放内存aScnLnBuffer
        FreeMem(aScnLnBuffer, nMemSize);
      end;
    end;
    

      

      

  • 相关阅读:
    Go 语言机制之逃逸分析
    类型转换和类型断言
    浅析rune数据类型
    Go 文件操作(创建、打开、读、写)
    字符编码笔记:ASCII,Unicode 和 UTF-8
    cmd.exe启动参数详解
    linux下.so、.ko、.a的区别
    Python 和C#的交互
    Innodb表压缩过程中遇到的坑(innodb_file_format)
    更改mysql的加密方式和密码策略
  • 原文地址:https://www.cnblogs.com/doorsky/p/5596490.html
Copyright © 2011-2022 走看看