【问题标题】:Xamarin Rotate Image Captured With CameraXamarin 旋转使用相机捕获的图像
【发布时间】:2021-05-11 14:48:21
【问题描述】:

我正在尝试在skiasharp 中获得一张左旋转90 度以居中并完全适合画布的图像。我尝试了2种方法。我自己的自定义方式,以及另一种似乎很流行的解决方案,但也许我不明白它是如何正常工作的?

  1. 我自己的方式。

代码如下:

SKSurface surf = e.Surface;
SKCanvas canvas = surf.Canvas;
SKSize size = canvasView.CanvasSize;
canvas.Clear();

SKRect rect = SKRect.Create(0.0f, 0.0f, size.Height, size.Width);
canvas.RotateDegrees(85);
canvas.DrawBitmap(m_bm, rect);

“m_bm”是在单独函数中检索的位图。该函数是:

// Let user take a picture.
var result = await MediaPicker.CapturePhotoAsync(new MediaPickerOptions
{
   Title = "Take a picture"
});

// Save stream.
var stream = await result.OpenReadAsync();

// Create the bitmap.
m_bm = SKBitmap.Decode(stream);

// Set to true because the image will be prepared soon.
m_displayedImage = true;

我只放了 85 而不是 90,因为我想在视觉上看到它越来越近,但是当我这样做时,它会离开屏幕。我来自游戏编程背景,所以这通常通过获取我们正在使用的任何东西的宽度(比如游戏中的玩家)并将其添加到 x 位置和繁荣来解决。但是对于 Xamarin,没有用。这是我自己的尝试。然后我当然上网寻求帮助,并给了我一个不同的实现。

  1. 流行的解决方案

请参阅here 了解这个流行的解决方案,这是对这个用户问题的第一个答案。我使用的代码略有不同,因为我没有看到在该用户函数中返回图像的意义。这里是:

        // Save stream.
        var stream = await result.OpenReadAsync();

        using (var bitmap = SKBitmap.Decode(stream))
        {
            var rotated = new SKBitmap(bitmap.Height, bitmap.Width);

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

我正在用画布绘制位图,我认为这会起作用,因为在其他代码示例中测试它确实做到了,所以我肯定没有正确旋转或其他什么?

【问题讨论】:

  • 在第二个示例中,rotated 是您修改后的位图。当 using 语句完成时,它将超出范围。您是否正在做任何事情来保留或返回修改后的位图?
  • 嗯,这对 using 语句很有意义。我使用它的方式与我发布的链接不同:stackoverflow.com/questions/45077047/…。我很困惑,因为我认为调用表面的 SKCanvas 会绘制我的位图,它会很好。
  • 那只是你在内存中创建的一个SKCanvas对象,它与设备显示无关
  • 有趣。所以我会尝试将位图保存在一个单独的变量中,然后调用该函数让它保存编辑的位图,最后在函数“OnCanvasViewPaintSurface”中绘制新的编辑位图。
  • @OmarMoodie 你好,如果你已经解决了,记得在有时间的时候把解决方案写在答案中。

标签: c# android ios xamarin mobile


【解决方案1】:

@Cheesebaron 在回复原帖时给我的链接最终成功了。但是出现了一个新问题,但我会自己用谷歌搜索。这是我自己的代码:

namespace BugApp
{


public partial class MainPage : ContentPage
{
    // Save bitmaps for later use.
    static SKBitmap m_bm;
    static SKBitmap m_editedBm;

    // Boolean for displaying the image captured with the camera.
    bool m_displayedImage;
    
    public MainPage()
    {
        // Set to explicit default values to always be in control of the assignments.
        m_bm = null;
        m_editedBm = null;

        // No picture has been taken yet.
        m_displayedImage = false;

        InitializeComponent();
    }

    // Assigned to the button in the xaml page.
    private async void SnapPicture(Object sender, System.EventArgs e)
    {
        // Let user take a picture.
        var result = await MediaPicker.CapturePhotoAsync(new MediaPickerOptions
        {
            Title = "Take a picture"
        });

        // Save stream.
        var stream = await result.OpenReadAsync();

        // Create the bitmap.
        m_bm = SKBitmap.Decode(stream);

        // Get the rotated image.
        m_editedBm = Rotate();

        // Set to true because the image will be prepared soon.
        m_displayedImage = true;
    }

    public static SKBitmap Rotate()
    {
        using (var bitmap = m_bm)
        {
            var rotated = new SKBitmap(bitmap.Height, bitmap.Width);

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

            return rotated;
        }
    }

    private void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs e)
    {
        if(m_bm != null && m_displayedImage == true)
        {
            e.Surface.Canvas.Clear();

            // Draw in a new rect space.
            e.Surface.Canvas.DrawBitmap(m_editedBm, new SKRect(0.0f, 0.0f, 300.0f, 300.0f));

            // ---Testing.
            // e.Surface.Canvas.DrawBitmap(m_editedBm, new SKRect(112, 238, 184, 310), new SKRect(0, 0, 9, 9));
            
            // Avoid having this function launch again for now.
            m_displayedImage = false;
        }
    }
}

}

重要的代码部分是旋转函数,这里是这个函数:Link

感谢所有回复的人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 2012-12-16
    • 1970-01-01
    相关资源
    最近更新 更多