3


1

GDI +でエッジをクリップせずに画像を回転させる最も速い方法は何ですか?

そうするためのいくつかのlooooongと空腹のアルゴリズムがありますが、まだ私は特に高速な何かを思い付かないか、見つけませんでした。

5 Answer


5


最も速い方法は、安全でない呼び出しを使用して、 `LockBits`を使用して画像メモリを直接操作することです。 怖いですが、とても簡単です。 LockBitsを検索すると、http://www.codeproject.com/KB/graphics/ImageRotationForCF.aspx [こちら]などのサンプルが多数見つかります。

興味深いのは:

BitmapData originalData = originalBitmap.LockBits(
     new Rectangle(0, 0, originalWidth, originalHeight),
     ImageLockMode.ReadOnly,
     PixelFormat.Format32bppRgb);

BitmapDataを取得したら、ピクセルを渡して、それらを新しいイメージにマップできます(再びLockBitsを使用)。 これは、 Graphics APIを使用するよりも大幅に高速です。


4


私がやったことは次のとおりです(膨大な量の継続的な調査と、TheCodeKingが提供する有用なリンクの後)。

public Image RotateImage(Image img, float rotationAngle)
    {
        // When drawing the returned image to a form, modify your points by
        // (-(img.Width / 2) - 1, -(img.Height / 2) - 1) to draw for actual co-ordinates.

        //create an empty Bitmap image
        Bitmap bmp = new Bitmap((img.Width * 2), (img.Height *2));

        //turn the Bitmap into a Graphics object
        Graphics gfx = Graphics.FromImage(bmp);

        //set the point system origin to the center of our image
        gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);

        //now rotate the image
        gfx.RotateTransform(rotationAngle);

        //move the point system origin back to 0,0
        gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);

        //set the InterpolationMode to HighQualityBicubic so to ensure a high
        //quality image once it is transformed to the specified size
        gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;

        //draw our new image onto the graphics object with its center on the center of rotation
        gfx.DrawImage(img, new PointF((img.Width / 2), (img.Height / 2)));

        //dispose of our Graphics object
        gfx.Dispose();

        //return the image
        return bmp;
    }

乾杯!


0


void Graphics.RotateTransform(float angle);

これにより、C#で画像が回転します。 代わりに何をしていますか?

私はGDI +をあまり試していません。 画像を描いた後は、必ず回転を逆にしてください。


0


この答えは、描画されるオフセットと回転された画像の両方を返します。角度をクリップすることなく、新しい画像をあるべきサイズに再作成することで機能します。 もともとは#C#IRCチャットルームとBloodyaugustのHisenburgによって書かれました。

   public static double NormalizeAngle(double angle)
    {
        double division = angle / (Math.PI / 2);
        double fraction = Math.Ceiling(division) - division;

        return (fraction * Math.PI / 2);
    }


    public static Tuple RotateImage(Image img, double rotationAngle)
    {

        double normalizedRotationAngle = NormalizeAngle(rotationAngle);

        double widthD = img.Width, heightD = img.Height;
        double newWidthD, newHeightD;



        newWidthD = Math.Cos(normalizedRotationAngle) * widthD + Math.Sin(normalizedRotationAngle) * heightD;
        newHeightD = Math.Cos(normalizedRotationAngle) * heightD + Math.Sin(normalizedRotationAngle) * widthD;

        int newWidth, newHeight;
        newWidth = (int)Math.Ceiling(newWidthD);
        newHeight = (int)Math.Ceiling(newHeightD);

        Size offset = new Size((newWidth - img.Width) / 2,(newHeight - img.Height) / 2);

        Bitmap bmp = new Bitmap(newWidth, newHeight);
        Graphics gfx = Graphics.FromImage(bmp);
        //gfx.Clear(Color.Blue);
        gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);
        gfx.RotateTransform((float)(rotationAngle / Math.PI * 180));
        gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);
        gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
        gfx.DrawImage(img, new PointF((bmp.Width / 2 - img.Width / 2), (bmp.Height / 2 - img.Height / 2)));
        gfx.Dispose();
        return new Tuple(bmp,offset);
    }


0


System.Drawing.Image imageToRotate = System.Drawing.Image.FromFile(imagePath);
switch (rotationAngle.Value)
{
    case "90":
        imageToRotate.RotateFlip(RotateFlipType.Rotate90FlipNone);
        break;
    case "180":
        imageToRotate.RotateFlip(RotateFlipType.Rotate180FlipNone);
        break;
    case "270":
        imageToRotate.RotateFlip(RotateFlipType.Rotate270FlipNone);
        break;
    default:
        throw new Exception("Rotation angle not supported.");
}
imageToRotate.Save(imagePath, ImageFormat.Jpeg);