【问题标题】:How to capture the rotated image to stream?如何捕获旋转的图像进行流式传输?
【发布时间】:2020-11-18 18:43:20
【问题描述】:

我正在使用 UWP 图像控件。

我通过应用旋转变换(角度 = 45)将图像旋转了 45 度,现在我想将渲染的旋转图像转换为流。所以我尝试了 RenderTargetBitmap 来捕获图像,但它不起作用。它返回实际图像而不是旋转图像。请对此提出任何建议。

        var rendererShapeViewBitmap = new RenderTargetBitmap();
        InMemoryRandomAccessStream renderedStream = new InMemoryRandomAccessStream();
        await rendererShapeViewBitmap.RenderAsync(editorImage);
        BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, renderedStream);
        IBuffer pixelBuffer = await rendererShapeViewBitmap.GetPixelsAsync();
        encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied,
           (uint)rendererShapeViewBitmap.PixelWidth, (uint)rendererShapeViewBitmap.PixelHeight, 96, 96, pixelBuffer.ToArray());
        await encoder.FlushAsync();
        renderedStream.Seek(0);

获取流之前:

获取流后

我的要求:

【问题讨论】:

    标签: uwp image-rotation rendertargetbitmap


    【解决方案1】:

    您可以让Image 控制在StackPanelGrid 等面板中,并使用RenderTargetBitmap 类将包含旋转图像的面板转换为流。

    更新:

    Grid 的大小将适应Image 控件的大小,如果图像旋转,Grid 的大小总是大于Image 控件的大小。

    您可以查看以下代码作为示例。

    <Grid x:Name="panel">
        <Image Source="Assets/YourImage.png"  Width="300" Height="300"
           x:Name="image" Margin="10">
            <Image.RenderTransform>
                <RotateTransform Angle="45" CenterX="150" CenterY="150"/>
            </Image.RenderTransform>
        </Image>
    </Grid>
    

    代码隐藏

    private async void button_Click(object sender, RoutedEventArgs e)
    {
        var renderShapeViewBitmap = new RenderTargetBitmap();
        InMemoryRandomAccessStream renderedStream = new InMemoryRandomAccessStream();
        await renderShapeViewBitmap.RenderAsync(panel);
        BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, renderedStream);
        IBuffer pixelBuffer = await renderShapeViewBitmap.GetPixelsAsync();
        encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied,
            (uint)renderShapeViewBitmap.PixelWidth, (uint)renderShapeViewBitmap.PixelHeight,
                96, 96, pixelBuffer.ToArray());
        await encoder.FlushAsync();
        renderedStream.Seek(0);
    }
    

    更新:

    RenderTargetBitmap 使用Image 控件捕获的图像流不包含旋转信息。因此,不能只获取旋转后的图像流。

    您可以检查以下代码作为解决方法:

        <Grid x:Name="panel" Background="Green" >
            <Image Source="Assets/2211.png"   Width="300" 
               x:Name="image" RenderTransformOrigin="0.5,0.5">
                <Image.RenderTransform>
                    <RotateTransform Angle="45" CenterX="0" CenterY="0"/>
                </Image.RenderTransform>
            </Image>
        </Grid>
    

    代码隐藏:

        private async void button_Click(object sender, RoutedEventArgs e)
        {
            var width = panel.Width;
            var height = panel.Height;
             
    //We can calculate the grid’size based on the size of image. Change the size of grid to wrap the image, then capture the grid which just surrounds the image
            panel.Height = image.ActualWidth / Math.Sqrt(2) + image.ActualHeight / Math.Sqrt(2);
            panel.Width = image.ActualWidth / Math.Sqrt(2) + image.ActualHeight / Math.Sqrt(2); 
            var renderShapeViewBitmap = new RenderTargetBitmap();
            InMemoryRandomAccessStream renderedStream = new InMemoryRandomAccessStream();
            await renderShapeViewBitmap.RenderAsync(panel);
            BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, renderedStream);
            IBuffer pixelBuffer = await renderShapeViewBitmap.GetPixelsAsync();
            encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied,
                (uint)renderShapeViewBitmap.PixelWidth, (uint)renderShapeViewBitmap.PixelHeight,
                96, 96, pixelBuffer.ToArray());
            await encoder.FlushAsync();
            renderedStream.Seek(0);
           ……
            //panel.Width = width;  //If you want the panel to remain the original size, you can use the two line code.
            //panel.Height = height;
        }
    

    注意,您需要将rotate your image around its centerCenterXCenterY 作为0UIElement.RenderTransformOriginal 作为(0.5,0.5) 进行简单计算。

    【讨论】:

    • 如何在网格内添加图片?图像大小和网格大小不同。
    • 我更新了答案,也许你可以检查更新,看看它是否解决了你的问题。
    • 谢谢.. 部分满足我的要求。如何仅在当前获取面板流时获取旋转的图像流?我已经添加了图片。
    • 我更新了答案,也许您可​​以检查更新,看看它是否符合您的要求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多