Добавление водяного знака к изображению в WP7 - PullRequest
1 голос
/ 14 марта 2012

Я пытаюсь создать приложение с водяным знаком, и мне нужно добавить текст к изображению, и я нашел это руководство, но я новичок в WP7, и кто-нибудь может мне сказать, как это использовать?

Вот какой код я получил от здесь :

public static class WriteableBitmapEx
{
    /// <summary>
    /// Creates a watermark on the specified image
    /// </summary>
    /// <param name="input">The image to create the watermark from</param>
    /// <param name="watermark">The text to watermark</param>
    /// <param name="color">The color - default is White</param>
    /// <param name="fontSize">The font size - default is 50</param>
    /// <param name="opacity">The opacity - default is 0.25</param>
    /// <param name="hasDropShadow">Specifies if a drop shadow effect must be added - default is true</param>
    /// <returns>The watermarked image</returns>
    public static WriteableBitmap Watermark(this WriteableBitmap input, string watermark, Color color = default(Color), double fontSize = 50, double opacity = 0.25, bool hasDropShadow = true)
    {
        var watermarked = GetTextBitmap(watermark, fontSize, color == default(Color) ? Colors.White : color, opacity, hasDropShadow);

        var width = watermarked.PixelWidth;
        var height = watermarked.PixelHeight;

        var result = input.Clone();

        var position = new Rect(input.PixelWidth - width - 20 /* right margin */, input.PixelHeight - height, width, height);
        result.Blit(position, watermarked, new Rect(0, 0, width, height));

        return result;
    }

    /// <summary>
    /// Creates a WriteableBitmap from a text
    /// </summary>
    /// <param name="text"></param>
    /// <param name="fontSize"></param>
    /// <param name="color"></param>
    /// <param name="opacity"></param>
    /// <param name="hasDropShadow"></param>
    /// <returns></returns>
    private static WriteableBitmap GetTextBitmap(string text, double fontSize, Color color, double opacity, bool hasDropShadow)
    {
        TextBlock txt = new TextBlock();
        txt.Text = text;
        txt.FontSize = fontSize;
        txt.Foreground = new SolidColorBrush(color);
        txt.Opacity = opacity;

        if (hasDropShadow) txt.Effect = new DropShadowEffect();

        WriteableBitmap bitmap = new WriteableBitmap((int)txt.ActualWidth, (int)txt.ActualHeight);
        bitmap.Render(txt, null);

        bitmap.Invalidate();

        return bitmap;
    }
}

Если я добавлю в модуль, я получу ошибки, как показано ниже: enter image description here

enter image description here

1 Ответ

3 голосов
/ 14 марта 2012

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

  1. Убедитесь, что ваш проект включает расширение WriteableBitmap из codeplex (или используйте NuGet, чтобы добавить его в свой проект): http://writeablebitmapex.codeplex.com/
  2. Получить BitmapImage откуда-то. (предположим, он называется originalBitmap)

  3. Преобразуйте его в WriteableBitmap.

    var myWritableBitmap = new WriteableBitmap(originalBitmap);

  4. Вызовите метод:

    var watermarkBitmap = WriteableBitmapEx.Watermark(myWriteableBitmap, "The Watermark");

  5. Делайте то, что вам нужно, с изображением с водяным знаком (сохраните его, отобразите его и т. Д.).

edit: пара модификаций.

  1. Удалить строку if (hasDropShadow) txt.Effect = new DropShadowEffect();, которая не поддерживается в WP7.

  2. В методе Watermark измените эту строку:

    var position = new Rect(input.PixelWidth - width - 20 /* right margin */, input.PixelHeight - height, width, height);
    

до:

    var position = new Rect(20, input.PixelHeight - height, width, height);

Тогда вам следует настроить следующее ( caveat emptor - это не рабочий код. Это код slapdash, предназначенный для того, чтобы помочь вам в этом. Может быть, вы избавитесь от тысячи жизней боли, если будете использовать это в производственном коде ):

XAML:

<phone:PhoneApplicationPage 
    x:Class="StackOWP7.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="72"/>
                <RowDefinition Height="72"/>
            </Grid.RowDefinitions>

            <Image x:Name="picture" Stretch="UniformToFill"/>
            <Button Grid.Row="1" Content="Choose Picture" Click="Button_Click"/>
            <Button Grid.Row="2" Content="Watermark Picture" Click="Button_Click_1"/>
        </Grid>
    </Grid>

</phone:PhoneApplicationPage>

и в CodeBehind:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var task = new PhotoChooserTask();

        task.Completed += (s, arg) =>
                              {
                                  if(arg.TaskResult == TaskResult.OK)
                                  {
                                      var bm = new BitmapImage(new Uri(arg.OriginalFileName));
                                      picture.Source = bm;
                                  }
                              };
        task.Show();

    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        var wb = new WriteableBitmap((BitmapSource) picture.Source);

        var watermarkedImage = wb.Watermark("watermark", Colors.White, fontSize:50, opacity:.8, hasDropShadow:false);

        picture.Source = watermarkedImage;

    }
...