Search code examples
c#wpfuwpwindows-10-universalframeworkelement

Converting FrameworkElement to Jpeg in UWP


At the past, I can convert and save an usercontrol to an JPEG image with this code:

   private string CreateBitmapImage(FrameworkElement usefulData, string name) // Tekli görev kartını masaüstünde oluşturmak için, resim yaratma fonksiyonu.
    {

        try
        {
            string fullFileName = string.Empty;
            Size size = new Size(642, 416);
            usefulData.Measure(size);
            usefulData.Arrange(new Rect(size));

            var rtb = new RenderTargetBitmap((int)usefulData.ActualWidth, (int)usefulData.ActualHeight, 96, 96, PixelFormats.Pbgra32);
            rtb.Render(usefulData);
            var encoder = new JpegBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(rtb));

            SaveFileDialog dlg = new SaveFileDialog();
            dlg.Title = "Görev kartını nereye kaydetmek istersiniz ?";
            dlg.FileName = name; // Default file name
            dlg.DefaultExt = ".jpg"; // Default file extension
            dlg.Filter = "Resim Dosyası (.jpg)|*.jpg"; // Filter files by extension
            dlg.OverwritePrompt = true;

            var result = dlg.ShowDialog();
            if (result == true && dlg.CheckPathExists == true)
            {
                fullFileName = System.IO.Path.Combine(dlg.FileName);
                using (var filestream = new FileStream(fullFileName, FileMode.Create))
                {
                    encoder.Save(filestream);
                }
            }


            return fullFileName;
        }

        catch
        {
            MessageBox.Show("Tek görev kartını yaratırken bir hata oluştu.Lütfen yeniden deneyin.", "Hata", MessageBoxButton.OK, MessageBoxImage.Error);

            return "";
        }




    }

Now, I'm converting my WPF project to UWP. However, I cannot find how I convert and save an usercontrol to an Jpeg image in UWP. Can you help me please ?

Thanks.

Update: My UserControl in UWP. As I explained at bottom, I got an exception if I try render the user control:

<UserControl
x:Class="AYOS_IDPrinter_UWP.TaskCard"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AYOS_IDPrinter_UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="416"
d:DesignWidth="642" HorizontalAlignment="Center" VerticalAlignment="Center" RequestedTheme="Default">
<UserControl.Resources>
    <SolidColorBrush x:Key="AuSupportColor" Color="#FFE5C97C"/>
</UserControl.Resources>

<Border x:Name="OutSketch"  BorderThickness="2" BorderBrush="{StaticResource AuSupportColor}">
    <Grid x:Name="MainGrid" Background="White">

        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <Border x:Name="NeedleArea"  BorderThickness="0,0,0,2" Background="{StaticResource AUColor}" BorderBrush="{StaticResource AuSupportColor}">
            <TextBlock x:Name="Label" TextWrapping="Wrap" Text="İğne Alanı / Needle Area" Foreground="White" TextAlignment="Center" Margin="0" VerticalAlignment="Center" FontFamily="Noto Sans" FontWeight="Normal"/>

        </Border>
        <Grid x:Name="Values" HorizontalAlignment="Stretch" Margin="10,10,10,10" VerticalAlignment="Stretch" Grid.Row="2">

            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>

            <Grid x:Name="Header" Margin="0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="128"/>
                    <ColumnDefinition/>
                    <ColumnDefinition Width="128"/>
                </Grid.ColumnDefinitions>
                <Image x:Name="Logo1" Source="Images/AULogo.png" Margin="0" Grid.RowSpan="4" HorizontalAlignment="Center" VerticalAlignment="Center" Width="100" Height="100"/>
                <Image x:Name="Logo2" Source="Images/AnkudemLogo.png" Margin="0" Grid.RowSpan="4" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center" Width="100" Height="100"/>
                <TextBlock x:Name="Header_1" Grid.Column="1" Margin="0" TextWrapping="Wrap" Text="AYÖS" FontSize="28" TextAlignment="Center" FontWeight="Bold" Foreground="#FF284985" FontFamily="Noto Sans"/>
                <TextBlock x:Name="Header_2" Grid.Column="1" Margin="0" TextWrapping="Wrap" Text="SINAV GÖREV KARTI" FontSize="24" TextAlignment="Center" Grid.Row="1" Foreground="#FF284985" FontFamily="Noto Sans"/>
                <TextBlock x:Name="Header_3" Grid.Column="1" Margin="0" TextWrapping="Wrap" Text="EXAMINATION TASK CARD" FontSize="24" TextAlignment="Center" Grid.Row="2" Foreground="#FF284985" FontFamily="Noto Sans"/>
                <TextBlock x:Name="DateText" Grid.Column="1" Margin="0" TextWrapping="Wrap" FontSize="22" TextAlignment="Center" Grid.Row="3" Foreground="#FF284985" Text="28 Mayıs 2016 – May 28, 2016" FontFamily="Noto Sans"/>
            </Grid>
            <Grid x:Name="Data" Grid.Row="1" Margin="0,18,0,-17">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <TextBlock x:Name="NameText" Margin="0,10,0,0" TextWrapping="Wrap" FontSize="32" TextAlignment="Center" Foreground="Red" Text="BERK BABADOĞAN" FontWeight="Bold" FontFamily="Noto Sans"/>
                <TextBlock x:Name="TaskText" Margin="0,0,0,10" TextWrapping="Wrap" Text="Salon Başkanı" FontSize="28" TextAlignment="Center" Foreground="Black" Grid.Row="1" FontFamily="Noto Sans"/>
            </Grid>
            <Grid x:Name="Specs" Margin="10" Grid.Row="2">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <TextBlock x:Name="SpecsH_1" Margin="0,0,5,0" TextWrapping="Wrap" Text="Sınav Yeri / Exam Area: " FontSize="20" Foreground="#FF343434" FontStyle="Italic" FontWeight="Bold" VerticalAlignment="Center" FontFamily="Noto Sans"/>
                <TextBlock x:Name="SpecsH_2" Margin="0,0,5,0" TextWrapping="Wrap" Text="Salon Adı / Hall Name:" FontSize="20" Foreground="#FF343434" Grid.Row="1" FontStyle="Italic" FontWeight="Bold" VerticalAlignment="Center" FontFamily="Noto Sans"/>
                <TextBlock x:Name="SpecsH_3" Margin="0,0,5,0" TextWrapping="Wrap" Text="Salon No / Hall Number:" FontSize="20" Foreground="#FF343434" Grid.Row="2" FontStyle="Italic" FontWeight="Bold" VerticalAlignment="Center" FontFamily="Noto Sans"/>
                <TextBlock x:Name="AreaText" Margin="5,0,0,0" TextWrapping="Wrap" Text="İstanbul" FontSize="20" Foreground="#FF343434" FontStyle="Italic" Grid.Column="1" VerticalAlignment="Center" FontFamily="Noto Sans"/>
                <TextBlock x:Name="HallNameText" Margin="5,0,0,0" TextWrapping="Wrap" Text="A Blok 3. Kat Derslik 316" FontSize="20" Foreground="#FF343434" Grid.Row="1" FontStyle="Italic" Grid.Column="1" VerticalAlignment="Center" FontFamily="Noto Sans"/>
                <TextBlock x:Name="HallNoText" Margin="5,0,0,0" TextWrapping="Wrap" Text="340111" FontSize="20" Foreground="#FF343434" Grid.Row="2" FontStyle="Italic" Grid.Column="1" VerticalAlignment="Center" FontFamily="Noto Sans"/>
            </Grid>
        </Grid>


    </Grid>
</Border>

It is the code how I create an instance from my user control:

 var item = new TaskCard(Name_TextBox.Text.ToUpper() + " " + Surname_TextBox.Text.ToUpper(), Task_TextBox.Text, ExamArea_TextBox.Text, HallName_TextBox.Text,HallNumber_TextBox.Text,DateConverter.Get(Date_Picker.Date.ToString())); // Creating card. 
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();   
await renderTargetBitmap.RenderAsync(item); // Gives error here. 
var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();

Solution

  • I did some researches why I can't render a TargetBitmap from code. I found a reason at this link:

    You cannot save visual element which in code (offscreen) to image.

    So, I foluna a new way to render my code based user control. I created my user control via code like this:

      //Initializing task card.
                var item = new TaskCard(Name_TextBox.Text.ToUpper() + " " + Surname_TextBox.Text.ToUpper(), Task_TextBox.Text, ExamArea_TextBox.Text, HallName_TextBox.Text, HallNumber_TextBox.Text, DateConverter.Get(Date_Picker.Date.ToString())); // Creating card.
    

    After this, I added a custom popup-like element with this:

           <Border x:Name="RingBorder" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" BorderBrush="{ThemeResource SystemControlBackgroundBaseHighRevealBorderBrush}" BorderThickness="2,2,2,2" RequestedTheme="Default" Visibility="Collapsed" >
                <Grid x:Name="InnerGrid_Ring" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" RequestedTheme="Default" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="auto"/>
                        <RowDefinition Height="auto"/>
                    </Grid.RowDefinitions>
                    <Grid x:Name="WaiterRing_SecondRow" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch" Grid.Row="2">
    
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <TextBlock x:Name="LoadValue_Ring" Text="Lütfen bekleyin..." TextWrapping="Wrap" FontWeight="Normal" Margin="10,0,10,0" TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Stretch" Grid.Column="1" Style="{StaticResource TitleTextBlockStyle}" />
                        <ProgressRing x:Name="Waiter_Ring" HorizontalAlignment="Center" Margin="10,10,10,10" VerticalAlignment="Center" Foreground="{StaticResource AndroidGreen}" IsActive="True" Width="40" Height="40"/>
                    </Grid>
                    <Grid x:Name="CardViewerGrid_Ring" HorizontalAlignment="Center" Height="416" Margin="0,0,0,0" VerticalAlignment="Center" Width="642"/>
                </Grid>
            </Border>
    

    Lastly, I'm rendering the user control like this:

     //Converting UIelement to Rendered Bitmap
    
                    CardViewerGrid_Ring.Children.Add(item); // Adding card to canvas.
    
                    RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
    
                    await renderTargetBitmap.RenderAsync(CardViewerGrid_Ring); // Render canvas.
                    var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
    

    And, voila :)

    enter image description here