【问题标题】:Rotate photo with SkiaSharp使用 SkiaSharp 旋转照片
【发布时间】:2017-07-13 09:46:52
【问题描述】:

我正在尝试使用以下代码将 SkiaSharp 的照片旋转 90 度:

    public SKBitmap Rotate()
    {
        var bitmap = SKBitmap.Decode("test.jpg");
        using (var surface = new SKCanvas(bitmap))
        {
            surface.RotateDegrees(90, bitmap.Width / 2, bitmap.Height / 2);
            surface.DrawBitmap(bitmap.Copy(), 0, 0);
        }

        return bitmap;
     }

但是当我将位图保存到JPEG 文件时,它在图像的顶部和底部都有边距。

原图:http://imgur.com/pGAuko8。 旋转图片:http://imgur.com/bYxpmI7.

我做错了什么?

【问题讨论】:

标签: c# .net skiasharp


【解决方案1】:

你可能想做这样的事情:

public static SKBitmap Rotate()
{
    using (var bitmap = SKBitmap.Decode("test.jpg"))
    {
        var rotated = new SKBitmap(bitmap.Height, bitmap.Width);

        using (var surface = new SKCanvas(rotated))
        {
            surface.Translate(rotated.Width, 0);
            surface.RotateDegrees(90);
            surface.DrawBitmap(bitmap, 0, 0);
        }

        return rotated;
    }
}

造成这种情况(或您的未按预期工作)的原因是您正在旋转位图本身。您基本上已经拍摄了一张图像,然后在将其绘制到第一张图像上时制作了一个副本。因此,您仍然有下图中的边距。

我所做的是创建一个新的位图,然后将解码的位图绘制到上面。

第二个“问题”是您正在旋转图像,但您没有更改画布尺寸。如果位图为 50x100,然后旋转 90 度,则位图现在为 100x50。由于一旦创建位图,您实际上无法更改其尺寸,因此您必须创建一个新位图。您可以在输出图像中看到这一点,因为它实际上被裁剪了一点。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    Matthew 的解决方案也适用于我,但是当我尝试将位图旋转超过 90° 或 -90° 时出现问题(位图被绘制为“不显示”)。我强烈推荐使用这个solution。稍作修改的结果:

    public static SKBitmap Rotate(SKBitmap bitmap, double angle)
        {
            double radians = Math.PI * angle / 180;
            float sine = (float)Math.Abs(Math.Sin(radians));
            float cosine = (float)Math.Abs(Math.Cos(radians));
            int originalWidth = bitmap.Width;
            int originalHeight = bitmap.Height;
            int rotatedWidth = (int)(cosine * originalWidth + sine * originalHeight);
            int rotatedHeight = (int)(cosine * originalHeight + sine * originalWidth);
    
            var rotatedBitmap = new SKBitmap(rotatedWidth, rotatedHeight);
    
            using (var surface = new SKCanvas(rotatedBitmap))
            {
                surface.Translate(rotatedWidth / 2, rotatedHeight / 2);
                surface.RotateDegrees((float)angle);
                surface.Translate(-originalWidth / 2, -originalHeight / 2);
                surface.DrawBitmap(bitmap, new SKPoint());
            }
            return rotatedBitmap;
        }
    

    在我的情况下,当我需要在 Xamarin.iOS 平台上旋转图片时使用它(谁试过这个,知道),就像一个魅力。

    【讨论】:

    • 确保在开始旋转之前调用surface.Clear(),否则您可能会得到一些图像伪影。
    猜你喜欢
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-13
    • 2015-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多