Sunday, 19 November 2017

C# How to: Image Transform Rotate

public static Bitmap RotateImage(this Bitmap sourceBitmap, 
                                       double degreesBlue,
                                      double degreesGreen,
                                        double degreesRed)
{
    BitmapData sourceData =
               sourceBitmap.LockBits(new Rectangle(0, 0,
               sourceBitmap.Width, sourceBitmap.Height),
               ImageLockMode.ReadOnly,
               PixelFormat.Format32bppArgb);

   
    byte[] pixelBuffer = new byte[sourceData.Stride *
                                  sourceData.Height];

   
    byte[] resultBuffer = new byte[sourceData.Stride *
                                   sourceData.Height];

   
    Marshal.Copy(sourceData.Scan0, pixelBuffer, 0,
                               pixelBuffer.Length);

   
    sourceBitmap.UnlockBits(sourceData);

   
    //Convert to Radians
    degreesBlue = degreesBlue * Math.PI / 180.0;
    degreesGreen = degreesGreen * Math.PI / 180.0;
    degreesRed = degreesRed * Math.PI / 180.0;

 
    //Calculate Offset in order to rotate on image middle
    int xOffset = (int )(sourceBitmap.Width / 2.0);
    int yOffset = (int )(sourceBitmap.Height / 2.0);

   
    int sourceXY = 0;
    int resultXY = 0;

   
    Point sourcePoint = new Point();
    Point resultPoint = new Point();

   
    Rectangle imageBounds = new Rectangle(0, 0, 
                            sourceBitmap.Width, 
                           sourceBitmap.Height);

   
    for (int row = 0; row < sourceBitmap.Height; row++)
    {
        for (int col = 0; col < sourceBitmap.Width; col++)
        {
            sourceXY = row * sourceData.Stride + col * 4;

   
            sourcePoint.X = col;
            sourcePoint.Y = row;

   
            if (sourceXY >= 0 && sourceXY + 3 < pixelBuffer.Length)
            {
                //Calculate Blue Rotation

                   
                resultPoint = sourcePoint.RotateXY(degreesBlue, 
                                             xOffset, yOffset);

   
                resultXY = (int)(Math.Round(
                      (resultPoint.Y * sourceData.Stride) + 
                      (resultPoint.X * 4.0)));

   
                if (imageBounds.Contains(resultPoint) && 
                                      resultXY >= 0)
                {
                    if (resultXY + 6 < resultBuffer.Length)
                    {
                        resultBuffer[resultXY + 4] = 
                             pixelBuffer[sourceXY];

   
                        resultBuffer[resultXY + 7] = 255;
                    }

   
                    if (resultXY + 3 < resultBuffer.Length)
                    {
                        resultBuffer[resultXY] = 
                         pixelBuffer[sourceXY];

   
                        resultBuffer[resultXY + 3] = 255;
                    }
                }

   
                //Calculate Green Rotation

   
                resultPoint = sourcePoint.RotateXY(degreesGreen,
                                             xOffset, yOffset);

   
                resultXY = (int)(Math.Round(
                      (resultPoint.Y * sourceData.Stride) +
                      (resultPoint.X * 4.0)));

   
                if (imageBounds.Contains(resultPoint) && resultXY >= 0)
                {
                    if (resultXY + 6 < resultBuffer.Length)
                    {
                        resultBuffer[resultXY + 5] = 
                         pixelBuffer[sourceXY + 1];

   
                        resultBuffer[resultXY + 7] = 255;
                    }

   
                    if (resultXY + 3 < resultBuffer.Length)
                    {
                        resultBuffer[resultXY + 1] = 
                         pixelBuffer[sourceXY + 1];

   
                        resultBuffer[resultXY + 3] = 255;
                    }
                }

   
                //Calculate Red Rotation

   
                resultPoint = sourcePoint.RotateXY(degreesRed,
                                             xOffset, yOffset);

   
                resultXY = (int)(Math.Round(
                      (resultPoint.Y * sourceData.Stride) +
                      (resultPoint.X * 4.0)));

   
                if (imageBounds.Contains(resultPoint) && resultXY >= 0)
                {
                    if (resultXY + 6 < resultBuffer.Length)
                    {
                        resultBuffer[resultXY + 6] = 
                         pixelBuffer[sourceXY + 2];

                        resultBuffer[resultXY + 7] = 255;
                    }

   
                    if (resultXY + 3 < resultBuffer.Length)
                    {
                        resultBuffer[resultXY + 2] = 
                         pixelBuffer[sourceXY + 2];

   
                        resultBuffer[resultXY + 3] = 255;
                    }
                }
            }
        }
    }

   
    Bitmap resultBitmap = new Bitmap(sourceBitmap.Width,
                                     sourceBitmap.Height);

   
    BitmapData resultData =
               resultBitmap.LockBits(new Rectangle (0, 0,
               resultBitmap.Width, resultBitmap.Height),
               ImageLockMode.WriteOnly,
               PixelFormat.Format32bppArgb);

   
    Marshal.Copy(resultBuffer, 0, resultData.Scan0,
                               resultBuffer.Length);

   
    resultBitmap.UnlockBits(resultData);

   
    return resultBitmap;
}

No comments:

Post a Comment