3

Я пытаюсь поместить водяной знак на изображение, сделанное моим приложением. Самый простой способ, который я мог бы подумать, - использовать FrameworkElement для создания слоев, а затем использовать RenderTargetBitmap для создания отмеченного водой изображения.Приложение для Windows Store - RenderTargetBitmap, создающее растровое изображение неправильного размера

Вот образец моего XAML.

<ScrollViewer x:Name="Zoom" Grid.Column="1" HorizontalScrollMode="Enabled" VerticalScrollMode="Enabled" VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Hidden" ZoomMode="Enabled"> 
     <Border x:Name="BgBorder"> 
      <Grid x:Name="ImageGird" SizeChanged="ImageGird_SizeChanged"> 
       <Grid x:Name="CaptureGird"> 
        <Image x:Name="CapturedImage" Stretch="None" Source="ms-appx:///Assets/Photo.jpg" /> 
        <StackPanel x:Name="Watermark" VerticalAlignment="Top" HorizontalAlignment="Left" Background="#6FFFFFFF" Margin="10"> 
         <TextBlock Text="Name" Foreground="Black" Margin="10,2.5,10,2.5" /> 
         <TextBlock Text="12345" Foreground="Black" Margin="10,2.5,10,2.5"/> 
         <TextBlock Text="54321" Foreground="Black" Margin="10,2.5,10,2.5" /> 
        </StackPanel> 
       </Grid> 
      </Grid> 
     </Border> 
    </ScrollViewer> 

Благодаря разрешению изображений они нуждаются в этом, заворачивают в ScrollViewer так что он может быть увеличенным, однако при попытке создать растровое изображение этого изображения, используя код, приведенный ниже, тонированное растровое изображение меньше, чем выход FrameworkElement

private async void Button_Click(object sender, RoutedEventArgs e) 
{ 
    try 
    { 
     var displayI = DisplayInformation.GetForCurrentView(); 
     var renderTargetBitmap = new RenderTargetBitmap(); 
     await renderTargetBitmap.RenderAsync(ImageGird, (int)ImageGird.ActualWidth, (int)ImageGird.ActualHeight); 
     IBuffer pixels = await renderTargetBitmap.GetPixelsAsync(); 
     CapturedImage2.Source = renderTargetBitmap; 

     Debug.WriteLine("Button_Click: ImageGrid: " + ImageGird.ActualWidth + "x" + ImageGird.ActualHeight + " RenderTargetBitmap: " + renderTargetBitmap.PixelWidth + "x" + renderTargetBitmap.PixelHeight); 
    } 
    catch (Exception) 
    { 
    } 
} 

отладочная

Button_Click: ImageGrid: 5344x3008 RenderTargetBitmap: 4096x2306 

Может кто-нибудь сказать мне, почему тонированное растровый гораздо меньше, чем фактическое Ele Я его создаю?

Также есть лучший способ для нанесения водяного знака изображения?

ответ

1

Благодаря @ A.J.Bauer, указывающему на Win2D, мне удалось решить проблему довольно элегантно.

/// <summary> 
    /// Create a watermarked image from an image stream 
    /// </summary> 
    /// <param name="sender">Jpeg image stream.</param> 
    private async Task<ImageSource> CreateWaterMarkedImage(IRandomAccessStream stream) 
    { 
     // Ensure our stream is at the beginning. 
     stream.Seek(0); 
     // Create our Win2D in memory renderer. 
     CanvasDevice device = CanvasDevice.GetSharedDevice(); 
     CanvasRenderTarget offscreen = new CanvasRenderTarget(device, (float)ImageGird.ActualWidth, (float)ImageGird.ActualHeight, 96); 
     // Create our Win2D bitmap 
     CanvasBitmap bmp = await CanvasBitmap.LoadAsync(offscreen, stream, 96); 
     // Create a text formatter for our watermark 
     var format = new CanvasTextFormat() 
     { 
      FontSize = 40, 
      HorizontalAlignment = CanvasHorizontalAlignment.Left, 
      VerticalAlignment = CanvasVerticalAlignment.Top, 
      WordWrapping = CanvasWordWrapping.Wrap, 
      FontFamily = "Arial", 
      FontWeight = FontWeights.SemiBold 
     }; 
     // Get a Win2D drawing session instance 
     using (CanvasDrawingSession ds = offscreen.CreateDrawingSession()) 
     { 
      // Layer our resulting Watermarked image. 
      ds.DrawImage(bmp); 
      // Create the Win2D text layout so we can get the bounds. 
      var tl = new CanvasTextLayout(ds, "Name\r\n12345\r\n54321", format, 1000, 1000); 
      // Create a background for the text 
      ds.FillRectangle(10, 10, (float)tl.DrawBounds.Width + 20f, (float)tl.DrawBounds.Height + 20f, new Color() { A = 0x6F, R = 0xFF, G = 0xFF, B = 0xFF }); 
      // Add the text layout. 
      ds.DrawTextLayout(tl, 10, 10, Colors.Black); 
      // Clear up the memory. 
      tl.Dispose(); 
     } 

     // Create our bitmap so we can return an ImageSource 
     BitmapImage im = new BitmapImage(); 
     using (InMemoryRandomAccessStream oStream = new InMemoryRandomAccessStream()) 
     { 
      // Save the Win2D canvas renderer a stream. 
      await offscreen.SaveAsync(oStream, CanvasBitmapFileFormat.Jpeg, 1.0f); 
      stream.Seek(0); 
      // Stream our Win2D pixels into the Bitmap 
      await im.SetSourceAsync(oStream); 
      Debug.WriteLine("CreateWaterMarkedImage: ImageGrid: " + ImageGird.ActualWidth + "x" + ImageGird.ActualHeight + " Bitmap: " + im.PixelWidth + "x" + im.PixelHeight); 
     } 
     // Tidy Up. 
     format.Dispose(); 
     bmp.Dispose(); 
     offscreen.Dispose(); 
     device.Dispose(); 
     return im; 
    } 

Полученный отладочный документ дает мне.

CreateWaterMarkedImage: ImageGrid: 5344x3008 Bitmap: 5344x3008 

И если установить отображается источник в ImageUIElement водяными изображения.

CapturedImage2.Source = await CreateWaterMarkedImage(photoStream); 

Этот пример очень адаптированной к моим потребностям, однако каждый должен иметь возможность легко адаптировать его, если вы используете элементы управления Win2D XAML.

1

ActualWidth и ActualHeight - рассчитанные значения. Поэтому, особенно для сетки, имеет смысл, что эти значения могут меняться сверхурочно. Я предполагаю, что когда вы устанавливаете источник изображения, что фактическая ширина и высота пересчитываются.

Я думаю, что вы должны иметь возможность сделать панель стека дочерним элементом изображения и поместить ее относительно родительского изображения, это заставило бы ее работать с переменными размерами изображения. Вы также можете попробовать установить некоторые ограничения на сетку и использовать их для определения размера растрового изображения вместо фактической ширины/высоты.

1

Havel a Посмотрите на Win2D и используйте экранный чертеж.

+0

Это выглядит интересно. Я проверю это, я удивлен, что не наткнулся на эту библиотеку. – Ne0

+0

Btw: Галерея примеров также доступна в магазине Windows 10. Поиск: Win2D –

 Смежные вопросы

  • Нет связанных вопросов^_^