首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

VC 图片旋转难题 ! 求(还可加分)!

2012-04-22 
VC 图片旋转难题 ! 求高手指点(还可加分)!!用StretchBlt函数实现将图片旋转90度和270度,请高手指点,详细说

VC 图片旋转难题 ! 求高手指点(还可加分)!!
用StretchBlt函数实现将图片旋转90度和270度,请高手指点,详细说明!
如果有其它函数也可;请详细说明一下,谢谢!

[解决办法]
旋转得自己做把
[解决办法]

C/C++ code
// RotateDIB - Create a new bitmap with rotated image// Returns  - Returns new bitmap with rotated image// hDIB   - Device-independent bitmap to rotate// fDegrees  - Angle of rotation in degree// clrBack  - Color of pixels in the resulting bitmap that do//     not get covered by source pixelsHDIB RotateDIB(HDIB hDIB, double fDegrees, COLORREF clrBack){ WaitCursorBegin(); // Get source bitmap    ec
[解决办法]


这里有代码下载。
[解决办法]
C/C++ code
函数:  TransparentBit 解释:  BOOL TransparentBit(HDC hdc,  //目标DCint nXOriginDest, //目标X偏移int nYOriginDeST, //目标Y偏移int nWidthDest, //目标宽度int nHeightDest, //目标高度HDC hdcSrc, //源DCint nXOriginSrc, //源X起点int nYOriginSrc, //源Y起点int nWidthSrc, //源高度int nHeightSrc, //源高度UINT crTransparent //透明色,COLORREF类型)函数:  LoadImage 解释:  从磁盘文件或者可执行文件资源中加载一个Windows位图 函数:  LoadImage 解释:  HANDLE LoadImage(HINSTANCE hInstance, LPCTSTR lpszName,UINT uType,int cxDesired,int cyDesired,UINT fuLoad);
[解决办法]
漏了链接地址了
http://www.codeproject.com/KB/graphics/rotatebyshear.aspx

[解决办法]
探讨
我可以用StretchBlt函数实现180度的旋转,不是图片的镜像哦,
所以我觉得90度应该也可以吧


[解决办法]
C/C++ code
 
/// <summary>
    /// Creates a new Image containing the same image only rotated
    /// </summary>
    /// <param name="image">The <see cref="System.Drawing.Image"/> to rotate </param>
    /// <param name="angle">The amount to rotate the image, clockwise, in degrees </param>
    /// <returns>A new <see cref="System.Drawing.Bitmap"/> that is just large enough
    /// to contain the rotated image without cutting any corners off. </returns>
    /// <exception cref="System.ArgumentNullException">Thrown if <see cref="image"/> is null. </exception>
    public static Bitmap RotateImage(Image image, float angle)
    {
      if(image == null)
        throw new ArgumentNullException("image");

      const double pi2 = Math.PI / 2.0;

      // Why can't C# allow these to be const, or at least readonly
      // *sigh*  I'm starting to talk like Christian Graus :omg:
      double oldWidth = (double) image.Width;
      double oldHeight = (double) image.Height;
     
      // Convert degrees to radians
      double theta = ((double) angle) * Math.PI / 180.0;
      double locked_theta = theta;

      // Ensure theta is now [0, 2pi)
      while( locked_theta < 0.0 )
        locked_theta += 2 * Math.PI;

      double newWidth, newHeight;
      int nWidth, nHeight; // The newWidth/newHeight expressed as ints



      Explaination of the calculations#region Explaination of the calculations
      /**//*
      * The trig involved in calculating the new width and height
      * is fairly simple; the hard part was remembering that when
      * PI/2 <= theta <= PI and 3PI/2 <= theta < 2PI the width and
      * height are switched.
      *
      * When you rotate a rectangle, r, the bounding box surrounding r
      * contains for right-triangles of empty space.  Each of the
      * triangles hypotenuse's are a known length, either the width or
      * the height of r.  Because we know the length of the hypotenuse
      * and we have a known angle of rotation, we can use the trig
      * function identities to find the length of the other two sides.
      *
      * sine = opposite/hypotenuse
      * cosine = adjacent/hypotenuse
      *
      * solving for the unknown we get
      *
      * opposite = sine * hypotenuse
      * adjacent = cosine * hypotenuse
      *
      * Another interesting point about these triangles is that there
      * are only two different triangles. The proof for which is easy
      * to see, but its been too long since I've written a proof that
      * I can't explain it well enough to want to publish it. 
      *
      * Just trust me when I say the triangles formed by the lengths
      * width are always the same (for a given theta) and the same
      * goes for the height of r.
      *
      * Rather than associate the opposite/adjacent sides with the
      * width and height of the original bitmap, I'll associate them
      * based on their position.
      *
      * adjacent/oppositeTop will refer to the triangles making up the
      * upper right and lower left corners
      *
      * adjacent/oppositeBottom will refer to the triangles making up
      * the upper left and lower right corners
      *
      * The names are based on the right side corners, because thats
      * where I did my work on paper (the right side).
      *
      * Now if you draw this out, you will see that the width of the
      * bounding box is calculated by adding together adjacentTop and
      * oppositeBottom while the height is calculate by adding
      * together adjacentBottom and oppositeTop.
      */
      #endregion

      double adjacentTop, oppositeTop;
      double adjacentBottom, oppositeBottom;

      // We need to calculate the sides of the triangles based
      // on how much rotation is being done to the bitmap.
      //  Refer to the first paragraph in the explaination above for
      //  reasons why.
      if( (locked_theta >= 0.0 && locked_theta < pi2) ||
        (locked_theta >= Math.PI && locked_theta < (Math.PI + pi2) ) )


      {
        adjacentTop = Math.Abs(Math.Cos(locked_theta)) * oldWidth;
        oppositeTop = Math.Abs(Math.Sin(locked_theta)) * oldWidth;

        adjacentBottom = Math.Abs(Math.Cos(locked_theta)) * oldHeight;
        oppositeBottom = Math.Abs(Math.Sin(locked_theta)) * oldHeight;
      }
      else
      {
        adjacentTop = Math.Abs(Math.Sin(locked_theta)) * oldHeight;
        oppositeTop = Math.Abs(Math.Cos(locked_theta)) * oldHeight;

        adjacentBottom = Math.Abs(Math.Sin(locked_theta)) * oldWidth;
        oppositeBottom = Math.Abs(Math.Cos(locked_theta)) * oldWidth;
      }
     
      newWidth = adjacentTop + oppositeBottom;
      newHeight = adjacentBottom + oppositeTop;

      nWidth = (int) Math.Ceiling(newWidth);
      nHeight = (int) Math.Ceiling(newHeight);

      Bitmap rotatedBmp = new Bitmap(nWidth, nHeight);

      using(Graphics g = Graphics.FromImage(rotatedBmp))
      {
        // This array will be used to pass in the three points that
        // make up the rotated image
        Point [] points;

        /**//*
        * The values of opposite/adjacentTop/Bottom are referring to
        * fixed locations instead of in relation to the
        * rotating image so I need to change which values are used
        * based on the how much the image is rotating.
        *
        * For each point, one of the coordinates will always be 0,
        * nWidth, or nHeight.  This because the Bitmap we are drawing on
        * is the bounding box for the rotated bitmap.  If both of the
        * corrdinates for any of the given points wasn't in the set above
        * then the bitmap we are drawing on WOULDN'T be the bounding box
        * as required.
        */
        if( locked_theta >= 0.0 && locked_theta < pi2 )
        {
          points = new Point[] {
                      new Point( (int) oppositeBottom, 0 ),
                      new Point( nWidth, (int) oppositeTop ),
                      new Point( 0, (int) adjacentBottom )
                    };

        }
        else if( locked_theta >= pi2 && locked_theta < Math.PI )
        {
          points = new Point[] {
                      new Point( nWidth, (int) oppositeTop ),
                      new Point( (int) adjacentTop, nHeight ),
                      new Point( (int) oppositeBottom, 0 )           
                    };


        }
        else if( locked_theta >= Math.PI && locked_theta < (Math.PI + pi2) )
        {
          points = new Point[] {
                      new Point( (int) adjacentTop, nHeight ),
                      new Point( 0, (int) adjacentBottom ),
                      new Point( nWidth, (int) oppositeTop )
                    };
        }
        else
        {
          points = new Point[] {
                      new Point( 0, (int) adjacentBottom ),
                      new Point( (int) oppositeBottom, 0 ),
                      new Point( (int) adjacentTop, nHeight )   
                    };
        }

        g.DrawImage(image, points);
      }

      return rotatedBmp;
    }


[解决办法]
一、首先介绍Graphics的两个函数,
RotateTransform:将整个坐标系逆时针旋转一定角度
TranslateTransform:将整个坐标系偏移到某个位置
本例要实现的功能是在指定位置上旋转图片,首先需要将整个坐标系偏移到指定位置,在进行坐标系的旋转,在函数使用上应先旋转在偏移(与我们想象的相反),代码如下
myGraphics.RotateTransform(angle,MatrixOrderAppend);
myGraphics.TranslateTransform(pnt.x,pnt.y,MatrixOrderAppend);
将图片画在pnt处,图片的中心点在rect1矩形的中心,DrawImage时坐标为图片在原坐标系的坐标减去坐标系的偏移
myGraphics.DrawImage(pImg,- rect1.Width(),- rect1.Height()/2,rect1.Width(), rect1.Height());
myGraphics.ResetTransform(); //将坐标系复位
二、还有一种方法可实现图形的旋转功能,那就是将所绘制的图形放入GraphicsPath中,然后设置图形变换矩阵,例子如下:
C/C++ code
Graphics* g;GraphicsPath myGraphicsPath(FillModeAlternate);       int offsetrx=m_EllipseData.point1.x -origin.X;       int offsetry=m_EllipseData.point1 .y -origin.Y;RectF myRectangle(offsetrx,offsetry ,m_EllipseData.point2.x-m_EllipseData.point1.x,m_EllipseData.point2.y-m_EllipseData.point1 .y   );              myGraphicsPath.AddEllipse (myRectangle);              Matrix* myPathMatrix=new Matrix();              myPathMatrix->Rotate(nRotateAngle, MatrixOrderAppend);              myPathMatrix->Translate(origin.X,origin.Y,MatrixOrderAppend );              myGraphicsPath.Transform(myPathMatrix);              g->FillPath(&myBrush, &myGraphicsPath); 

热点排行