简体   繁体   English

Xamarin 旋转摄像头拍摄的图像

[英]Xamarin Rotate Image Captured With Camera

I'm trying to get an image in skiasharp that's left rotated by 90 degrees to be centered and fit perfectly on the canvas.我试图在skiasharp中获得一个图像,该图像左旋转90度以居中并完全适合canvas。 I've tried 2 ways.我尝试了2种方法。 My own custom way, and another one that seems like a popular solution but maybe I'm not understanding how it works correctly?我自己的自定义方式,以及另一种似乎很流行的解决方案,但也许我不明白它是如何正常工作的?

  1. My own way.我自己的方式。

Here is the code:这是代码:

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" is a bitmap that was retrieved in a separate function. “m_bm”是在单独的 function 中检索到的 bitmap。 That function is:即 function 是:

// 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;

I only put 85 instead of 90 because I wanted to visually see it getting closer but when I do that, it goes off screen.我只放了 85 而不是 90,因为我想在视觉上看到它越来越近,但是当我这样做时,它会离开屏幕。 I'm coming from a game programming background so this is normally solved with getting the width of whatever we're working with (like the player in the game) and adding that to the x position, and boom.我来自游戏编程背景,所以这通常可以通过获取我们正在使用的任何东西的宽度(比如游戏中的玩家)并将其添加到 x position 和繁荣来解决。 But with Xamarin, didn't work.但是对于 Xamarin,没有用。 That's my own attempt.这是我自己的尝试。 Then I hit the internet of course to find help, and a different implementation was given to me.然后我当然上网寻求帮助,并给了我一个不同的实现。

  1. Popular solution .流行的解决方案

See here for this popular solution and it's the FIRST answer to this users question.请参阅此处了解这个流行的解决方案,这是对这个用户问题的第一个答案。 The code I used is SLIGHTLY different because I didn't see the point in returning an image in that users function.我使用的代码略有不同,因为我没有看到用户 function 返回图像的意义。 Here it is:这里是:

        // 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);
            }
        }

I'm drawing the bitmap with the canvas and I thought that would work because testing it in other code samples it did exactly that, so I definitely am not rotating properly or something?我正在用 canvas 绘制 bitmap 并且我认为这会起作用,因为在其他代码示例中测试它确实做到了,所以我肯定没有正确旋转或什么?

The link that @Cheesebaron gave me in the reply to the original post ended up working out. @Cheesebaron 在回复原帖时给我的链接最终成功了。 But a new issue arises but I'll google that myself.但是出现了一个新问题,但我会自己用谷歌搜索。 Here's my own code:这是我自己的代码:

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;
        }
    }
}

} }

The main portion of code that matters is the rotate function which was this one here: Link .重要的代码的主要部分是旋转 function ,这里是这个: Link

Thanks to everyone that replied.感谢所有回复的人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM