вращение изображения меняет разрешение и четкость - PullRequest
1 голос
/ 01 декабря 2010

Для поворота изображения используйте приведенный ниже код.

Проблема в том, что разрешение изображения становится низким, а изображение становится неясным.

Как мне избежать этой проблемы?

private Bitmap rotateImage(Bitmap b, float angle)
{
    //create a new empty bitmap to hold rotated image
    Bitmap returnBitmap = new Bitmap(b.Width, b.Height);
    //make a graphics object from the empty bitmap
    Graphics g = Graphics.FromImage(returnBitmap);
    //move rotation point to center of image
    g.TranslateTransform((float)this.Width / 2, (float)this.Height / 2);
    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
    //rotate
    g.RotateTransform(angle);
    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
    g.TranslateTransform(-(float)this.Width / 2, -(float)this.Height / 2);
    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
    //draw passed in image onto graphics object
    g.DrawImage(b, new Point(0, 0));
    g.Dispose();
    return returnBitmap;
}

Ответы [ 3 ]

4 голосов
/ 01 декабря 2010

Повторные повороты приведут к снижению качества, поскольку повторные интерполяции влияют на изображение.Лучший способ избежать этого - вращать исходное изображение только один раз.Если вы строите систему, в которой изображение поворачивается несколько раз, просто поверните исходное изображение на общую величину вращения, вместо того чтобы каждый раз поворачивать маленькое дельта-вращение на уже повернутое изображение.

3 голосов
/ 01 декабря 2010

У меня есть метод, который я использую для вращения, и он работает без существенного снижения качества изображения (которое я видел).

public static Bitmap RotateImage(Image image, float angle)
        {
            if(image == null)
                throw new ArgumentNullException("image");

            const double pi2 = Math.PI / 2.0;


            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



            double adjacentTop, oppositeTop;
            double adjacentBottom, oppositeBottom;


            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))
            {

                Point [] points;

                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;
        }
1 голос
/ 28 сентября 2013

пример кода с RotateFlip:

Bitmap bitmap1;

private void InitializeBitmap()
{
    try
    {
        bitmap1 = (Bitmap)Bitmap.FromFile(@"C:\test.bmp");
        PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
        PictureBox1.Image = bitmap1;
    }
    catch(System.IO.FileNotFoundException)
    {
        MessageBox.Show("There was an error." + 
            "Check the path to the bitmap.");
    }


}

private void Button1_Click(System.Object sender, System.EventArgs e)
{

    if (bitmap1 != null)
    {
        bitmap1.RotateFlip(RotateFlipType.Rotate180FlipNone);
        PictureBox1.Image = bitmap1;
    }

}

Указывает угол поворота изображения и ось, используемую для переворачивания изображения. http://msdn.microsoft.com/en-us/library/system.drawing.rotatefliptype.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...