Как захватить повернутое изображение для потоковой передачи?

#uwp #image-rotation #rendertargetbitmap

#uwp #изображение-вращение #rendertargetbitmap

Вопрос:

Я использую элемент управления изображением 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);
  

Перед получением потока:
введите описание изображения здесь

После получения потока

введите описание изображения здесь

Мое требование: введите описание изображения здесь

Ответ №1:

Вы могли бы разрешить Image управление внутри панели, такой как StackPanel или Grid , и преобразовать панель, которая включает ваше повернутое изображение, в поток, используя класс 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;
    }
  

Обратите внимание, вам нужно повернуть изображение вокруг его центра с CenterX помощью и CenterY как 0 и UIElement.RenderTransformOriginal как (0,5, 0,5) для простого вычисления.

Комментарии:

1. Как добавить изображение внутри сетки? Размер изображения и размер сетки различны.

2. Я обновляю ответ, и, возможно, вы могли бы проверить обновление, чтобы узнать, решает ли оно ваш вопрос.

3. Спасибо.. Это частично соответствует моим требованиям. Как получить поток повернутого изображения, только в настоящее время я получаю поток панели? Я добавил изображения.

4. Я обновляю ответ, и, возможно, вы могли бы проверить обновление, чтобы увидеть, соответствует ли оно вашим требованиям.