zoukankan      html  css  js  c++  java
  • FlipReverseRotate Lab Report

    http://www.efg2.com/Lab/ImageProcessing/FlipReverseRotate.htm

    The purpose of this program, FlipReverseRotate.EXE, is to demonstrate how to

    flip (top-to-bottom) and/or
    reverse (left-to-right)

    a bitmap in memory and display the results on the screen.
    Three methods to flip/reverse are compared:

    Scanline, CopyRect, StretchBlt.

    In addition, a bitmap can be rotated any multiple of 90 degrees,
    namely 0, 90, 180, or 270 degrees counterclockwise, but only with the Scanline method.

    View Code
    // The FlipReverseRotate Library provides three functions to flip and/or
    // reverse a bitmap.  You can choose which approach you'd like to use from the
    // three methods to flip or reverse a bitmap:  ScanLine, CopyRect, StretchBlt.
    //
    // A "Flip" operation takes the top of an image to the bottom and the bottom of
    // the image to the top.  It is a reflection along a horizontal line in the
    // middle of an image.
    //
    // A "Reverse" operation takes the left of an image to the right and the right
    // of the image to the left.  It is a reflection along a vertical line in the
    // middle of an image.
    //
    // Any Flip/Reverse operation is commutative, i.e., the flip and reverse can
    // be performed in any order to get the same result.  A flip followed by a
    // reverse is the same as a reverse followed by a flip.
    //
    // A "rotate" operation spins an image 0, 90, 180 or 270 degrees around an
    // axis in the center of the image.
    //
    // A flip/reverse operation along with a rotation is not commutative in general.
    // A flip followed by a rotation will not always result in the same image as a
    // rotation followed by a flip.  The rotation here ALWAYS follows any flip and/or
    // reversal.
    //
    // The examples here are intended for use with bitmaps that have 24 bits/pixel.
    // Palettes may be lost on 256-color bitmaps.
    //
    // Copyright (C) 1998, Earl F. Glynn.  All Rights Reserved.
    // May be used freely for non-comercial use.
    
    unit FlipReverseRotateLibrary;
    
    interface
    
    uses
      Dialogs,
      Windows, // TRGBTriple (put here to avoid TBitmap conflict in Implementation)
      Graphics; // TBitmap
    
    // Flip/Reverse functions by Method
    function FlipReverseScanLine( const Flip, Reverse : BOOLEAN;
      const Bitmap : TBitmap ) : TBitmap;
    
    function FlipReverseCopyRect( const Flip, Reverse : BOOLEAN;
      const Bitmap : TBitmap ) : TBitmap;
    
    function FlipReverseStretchBlt( const Flip, Reverse : BOOLEAN;
      const Bitmap : TBitmap ) : TBitmap;
    
    // The Rotation function is only for the Scanline Method.
    // Note:  Windows NT supports a "plgblt" API call that can be used to rotate
    // images.
    function RotateScanline90( const angle : INTEGER; const Bitmap : TBitmap )
      : TBitmap;
    
    implementation
    
    uses
      Classes, // Rect
      SysUtils; // Exception
    
    const
      MaxPixelCount = 65536; // or some other arbitrarily large value
    
    type
      EBitmapError = class( Exception );
      TRGBArray = array [ 0 .. MaxPixelCount - 1 ] of TRGBTriple;
      pRGBArray = ^TRGBArray;
    
      /// ///////////////////////////////////////////////////////////////////////////
    
    function FlipReverseScanLine( const Flip, Reverse : BOOLEAN;
      const Bitmap : TBitmap ) : TBitmap;
    var
      i : INTEGER;
      j : INTEGER;
      RowIn : pRGBArray;
      RowOut : pRGBArray;
    begin
      if Bitmap.PixelFormat <> pf24bit then
        raise EBitmapError.Create( 'Can Flip/Reverse only 24-bit bitmap' );
    
      RESULT := TBitmap.Create;
      RESULT.Width := Bitmap.Width;
      RESULT.Height := Bitmap.Height;
      RESULT.PixelFormat := Bitmap.PixelFormat;
    
      for j := 0 to Bitmap.Height - 1 do
      begin
        RowIn := Bitmap.Scanline[ j ];
        if Flip then
          RowOut := RESULT.Scanline[ Bitmap.Height - 1 - j ]
        else
          RowOut := RESULT.Scanline[ j ];
    
        // Optimization technique:  Use two FOR loops so IF is outside of inner loop
        if Reverse then
        begin
          for i := 0 to Bitmap.Width - 1 do
            RowOut[ i ] := RowIn[ Bitmap.Width - 1 - i ]
        end
        else
        begin
          for i := 0 to Bitmap.Width - 1 do
            RowOut[ i ] := RowIn[ i ]
        end
    
      end
    end { FlipReverseScanLine };
    
    /// ///////////////////////////////////////////////////////////////////////////
    
    // This function implements a suggestion by David Ullrich in a July 25, 1997
    // post to comp.lang.pascal.delphi.misc.
    //
    // The Graphics.PAS unit shows that CopyRect calls the Windows StretchBlt API
    // function.
    function FlipReverseCopyRect( const Flip, Reverse : BOOLEAN;
      const Bitmap : TBitmap ) : TBitmap;
    var
      Bottom : INTEGER;
      Left : INTEGER;
      Right : INTEGER;
      Top : INTEGER;
    begin
      RESULT := TBitmap.Create;
      RESULT.Width := Bitmap.Width;
      RESULT.Height := Bitmap.Height;
      RESULT.PixelFormat := Bitmap.PixelFormat;
    
      // Flip Top to Bottom
      if Flip then
      begin
        // Unclear why extra "-1" is needed here.
        Top := Bitmap.Height - 1;
        Bottom := -1
      end
      else
      begin
        Top := 0;
        Bottom := Bitmap.Height
      end;
    
      // Reverse Left to Right
      if Reverse then
      begin
        // Unclear why extra "-1" is needed here.
        Left := Bitmap.Width - 1;
        Right := -1;
      end
      else
      begin
        Left := 0;
        Right := Bitmap.Width;
      end;
    
      RESULT.Canvas.CopyRect( Rect( Left, Top, Right, Bottom ), Bitmap.Canvas,
        Rect( 0, 0, Bitmap.Width, Bitmap.Height ) );
    end { FlipReverseCopyRect };
    
    /// ///////////////////////////////////////////////////////////////////////////
    
    function FlipReverseStretchBlt( const Flip, Reverse : BOOLEAN;
      const Bitmap : TBitmap ) : TBitmap;
    var
      Bottom : INTEGER;
      Left : INTEGER;
      Right : INTEGER;
      Top : INTEGER;
    begin
      RESULT := TBitmap.Create;
      RESULT.Width := Bitmap.Width;
      RESULT.Height := Bitmap.Height;
      RESULT.PixelFormat := Bitmap.PixelFormat;
    
      // Flip Top to Bottom
      if Flip then
      begin
        // Unclear why extra "-1" is needed here.
        Top := Bitmap.Height - 1;
        Bottom := -1
      end
      else
      begin
        Top := 0;
        Bottom := Bitmap.Height
      end;
    
      // Reverse Left to Right
      if Reverse then
      begin
        // Unclear why extra "-1" is needed here.
        Left := Bitmap.Width - 1;
        Right := -1;
      end
      else
      begin
        Left := 0;
        Right := Bitmap.Width;
      end;
    
      StretchBlt( RESULT.Canvas.Handle, Left, Top, Right - Left, Bottom - Top,
        Bitmap.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height, cmSrcCopy );
    end { FlipReverseStretchBlt };
    
    /// ///////////////////////////////////////////////////////////////////////////
    
    // Rotate 24-bits/pixel Bitmap any multiple of 90 degrees.
    function RotateScanline90( const angle : INTEGER; const Bitmap : TBitmap )
      : TBitmap;
    
    // These four internal functions parallel the four cases in rotating a
    // bitmap using the Pixels property.  See the RotatePixels example on
    // the Image Processing page of efg's Computer Lab for an example of the
    // use of the Pixels property (which is very slow).
    
    // A Bitmap.Assign could be used for a simple copy.  A complete example
    // using ScanLine is included here to help explain the other three cases.
      function SimpleCopy : TBitmap;
      var
        i : INTEGER;
        j : INTEGER;
        RowIn : pRGBArray;
        RowOut : pRGBArray;
      begin
        RESULT := TBitmap.Create;
        RESULT.Width := Bitmap.Width;
        RESULT.Height := Bitmap.Height;
        RESULT.PixelFormat := Bitmap.PixelFormat; // only pf24bit for now
    
        // Out[i, j] = In[i, j]
    
        for j := 0 to Bitmap.Height - 1 do
        begin
          RowIn := Bitmap.Scanline[ j ];
          RowOut := RESULT.Scanline[ j ];
    
          // Could optimize the following by using a function like CopyMemory
          // from the Windows unit.
          for i := 0 to Bitmap.Width - 1 do
          begin
            // Why does this crash with RowOut[i] := RowIn[i]?  Alignment?
            // Use this longer form as workaround.
            with RowOut[ i ] do
            begin
              rgbtRed := RowIn[ i ].rgbtRed;
              rgbtGreen := RowIn[ i ].rgbtGreen;
              rgbtBlue := RowIn[ i ].rgbtBlue;
            end
          end
        end
      end { SimpleCopy };
    
      function Rotate90DegreesCounterClockwise : TBitmap;
      var
        i : INTEGER;
        j : INTEGER;
        RowIn : pRGBArray;
      begin
        RESULT := TBitmap.Create;
        RESULT.Width := Bitmap.Height;
        RESULT.Height := Bitmap.Width;
        RESULT.PixelFormat := Bitmap.PixelFormat; // only pf24bit for now
    
        // Out[j, Right - i - 1] = In[i, j]
        for j := 0 to Bitmap.Height - 1 do
        begin
          RowIn := Bitmap.Scanline[ j ];
          for i := 0 to Bitmap.Width - 1 do
            pRGBArray( RESULT.Scanline[ Bitmap.Width - i - 1 ] )[ j ] := RowIn[ i ]
        end
      end { Rotate90DegreesCounterClockwise };
    
    // Could use Rotate90DegreesCounterClockwise twice to get a
    // Rotate180DegreesCounterClockwise.  Rotating 180 degrees is the same
    // as a Flip and Reverse
      function Rotate180DegreesCounterClockwise : TBitmap;
      var
        i : INTEGER;
        j : INTEGER;
        RowIn : pRGBArray;
        RowOut : pRGBArray;
      begin
        RESULT := TBitmap.Create;
        RESULT.Width := Bitmap.Width;
        RESULT.Height := Bitmap.Height;
        RESULT.PixelFormat := Bitmap.PixelFormat; // only pf24bit for now
    
        // Out[Right - i - 1, Bottom - j - 1] = In[i, j]
        for j := 0 to Bitmap.Height - 1 do
        begin
          RowIn := Bitmap.Scanline[ j ];
          RowOut := RESULT.Scanline[ Bitmap.Height - j - 1 ];
          for i := 0 to Bitmap.Width - 1 do
            RowOut[ Bitmap.Width - i - 1 ] := RowIn[ i ]
        end
    
      end { Rotate180DegreesCounterClockwise };
    
    // Could use Rotate90DegreesCounterClockwise three times to get a
    // Rotate270DegreesCounterClockwise
      function Rotate270DegreesCounterClockwise : TBitmap;
      var
        i : INTEGER;
        j : INTEGER;
        RowIn : pRGBArray;
      begin
        RESULT := TBitmap.Create;
        RESULT.Width := Bitmap.Height;
        RESULT.Height := Bitmap.Width;
        RESULT.PixelFormat := Bitmap.PixelFormat; // only pf24bit for now
    
        // Out[Bottom - j - 1, i] = In[i, j]
        for j := 0 to Bitmap.Height - 1 do
        begin
          RowIn := Bitmap.Scanline[ j ];
          for i := 0 to Bitmap.Width - 1 do
            pRGBArray( RESULT.Scanline[ i ] )[ Bitmap.Height - j - 1 ] := RowIn[ i ]
        end
      end { Rotate270DegreesCounterClockwise };
    
    begin
      if Bitmap.PixelFormat <> pf24bit then
        raise EBitmapError.Create( 'Can Rotate90 only 24-bit bitmap' );
    
      if ( angle >= 0 ) and ( angle mod 90 <> 0 ) then
        raise EBitmapError.Create
          ( 'Rotate90:  Angle not positive multiple of 90 degrees' );
    
      case ( angle div 90 ) mod 4 of
        0 :
          RESULT := SimpleCopy;
        1 :
          RESULT := Rotate90DegreesCounterClockwise;
        // Anticlockwise for the Brits
        2 :
          RESULT := Rotate180DegreesCounterClockwise;
        3 :
          RESULT := Rotate270DegreesCounterClockwise
      else
        RESULT := nil // avoid compiler warning
      end;
    
    end { RotateScanline90 };
    
    end.

  • 相关阅读:
    达梦常用命令
    sqlserver命令
    db2常用命令
    docker常用命令
    linux常用命令
    vim常用命令
    cpu、内存、io、内存、负载
    3.系统状态监控
    10 innodb之关键特性刷新邻接页
    9 innodb关键特性之自适应哈希索引03
  • 原文地址:https://www.cnblogs.com/shangdawei/p/3061584.html
Copyright © 2011-2022 走看看