Archives de février 2014

FIGlet.Net – Génération et OCR de Textes Art ASCII

Lors d’un challenge informatique qui avait pour but de répondre à un robot sur un canal IRC, j’ai dû développer un programme qui devait reconnaitre des textes aléatoires écrits en Art ASCII en moins d’une seconde et il dévait renvoyer le résultat sur le canal IRC. Cette technique d’écriture de texte était très répandue par le passé sur les mainframes, les BBS, puis sur beaucoup d’applications en mode texte ce qui est encore le cas pour les serveurs IRC.

Une librairie permettant d’écrire ces textes développée en C, existe pour les systèmes Unix . Elle définit un format de fichier de police de caractère. Ce programme est FIGlet et les fichiers de polices ont pour extension .flf .

Mon langage de prédilections étant le C#, j’ai donc développé une version FIGlet.Net et comme j’avais besoin pour ce challenge de lire ce type de texte, j’ai créé une fonction de reconnaissance de caractères des textes Art-ASCII.

Voici un exemple :

artascii

Et le code client, pour utiliser la librairie :

namespace FIGlet.Net
{
    public class SampleClient
    {
        public static void TestUsage()
        {
            var fig = new Figlet(); //font par défaut
            //Chargement d'une font spécifique au format Figlet
            //fig.LoadFont(@"D:\FIGLET\FONTS\standard.flf");

            //Génération et affichage du texte  Art ASCII
            var asciiart = fig.ToAsciiArt("Microsoft.Net");
            Console.WriteLine(asciiart);

            //Préparation d'un alphabet pour la reconnaissance de l'image Art ASCII
            fig.PrepareAlphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.");
            //Reconnaissance de l'image et affichage du texte trouvé
            var reconize = fig.ReconizeAsciiArt(asciiart);
            Console.WriteLine("Résultat OCR-ArtASCII: {0}",reconize);
            Console.ReadLine();
        }
    }
}

J’ai publié le code de ma librairie FIGlet.Net sur GitHub si vous etes intéressé c’est ici :  https://github.com/auriou/FIGlet

Publicités

, ,

Poster un commentaire

WPF : HighlightConverter (IMultiValueConverter)

Lorsque l’on met en place une zone de recherche, il est intéressant de mettre en surbrillance les zones qui correspondent dans le résultat de votre recherche.

Voiçi une interface que j’ai réalisée pour un projet :

HighlightConverter[1]

Mon treeView est bindé à une collection spécialisée “class TreeList<T> : ObservableCollection<TreeNode<T>>, INotifyPropertyChanged ” dans laquelle je manipule les propriétes pour ouvrir / fermer / cacher / afficher les noeuds de la treeview. Le binding est le  suivant.

<Style x:Key="TreeViewItemStyle" TargetType="{x:Type TreeViewItem}">
  <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
  <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
  <Setter Property="Visibility" Value="{Binding IsHidden, Converter={StaticResource ResourceKey=InverseBoolToVisibilityConverter}}" />

Le résultat d’une recherche sera un textBlock comprenant un champ de type Run avec un style différent pour identifier le texte trouvé.

Il sera donc nécessaire d’avoir 3 objets Run :     

– Start  :  début du résultat qui peut être vide,

– Find  :  partie du résulat comprenand le terme de la recherche, identifié en rouge,

– End   :  fin du résultat qui peut etre vide 

Comme il y à 2 binding pour déterminer le résultat à renvoyer, il faudra donc un converter Multi-valué

 

        <TextBlock>
          <TextBlock.Inlines>
            <Run>
              <Run.Text>
                <MultiBinding Converter="{StaticResource HighlightConverter}" ConverterParameter="Start">
                  <Binding Mode="OneWay" Path="DisplayText" />
                  <Binding ElementName="SearchBox"
                           Mode="OneWay"
                           Path="DataContext.SearchCompteGeneral" />
                </MultiBinding>
              </Run.Text>
            </Run>
            <Run Style="{DynamicResource HighlightStyle}">
              <Run.Text>
                <MultiBinding Converter="{StaticResource HighlightConverter}" ConverterParameter="Find">
                  <Binding Mode="OneWay" Path="DisplayText" />
                  <Binding ElementName="SearchBox"
                           Mode="OneWay"
                           Path="DataContext.SearchCompteGeneral" />
                </MultiBinding>
              </Run.Text>
            </Run>
            <Run>
              <Run.Text>
                <MultiBinding Converter="{StaticResource HighlightConverter}" ConverterParameter="End">
                  <Binding Mode="OneWay" Path="DisplayText" />
                  <Binding ElementName="SearchBox"
                           Mode="OneWay"
                           Path="DataContext.SearchCompteGeneral" />
                </MultiBinding>
              </Run.Text>
            </Run>
          </TextBlock.Inlines>
        </TextBlock>

 

Maintenant le code du converter multi-valué :

 

public class HighlightConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var value = System.Convert.ToString(values[0]);
        var terms = System.Convert.ToString(values[1]);
        var param = System.Convert.ToString(parameter);

        if (!string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(terms))
        {
            if (value.ToLower().Contains(terms.ToLower()))
            {
                var findIndex = value.ToLower().IndexOf(terms.ToLower(), System.StringComparison.Ordinal);
                switch (param)
                {
                    case "Start":
                        return value.Substring(0, findIndex);
                    case "Find":
                        return value.Substring(findIndex, terms.Length);
                    case "End":
                        return value.Substring(findIndex + terms.Length);
                }
            }
        }
        if (param == "Start")
        {
            return value;
        }
        return "";
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        return null;
    }
}

 

Le code Xaml avec la treeVIew:

<Grid x:Name="GridSearchCompte" Grid.Row="1">
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
  </Grid.RowDefinitions>
  <TextBox Name="SearchBox"
           Margin="5,2"
           HorizontalAlignment="Stretch"
           VerticalAlignment="Stretch"
           Text="{Binding Path=SearchCompteGeneral,
                            Delay=700,
                            Mode=TwoWay,
                            UpdateSourceTrigger=PropertyChanged}"
           controls:TextboxHelper.ClearTextButton="True"
           controls:TextboxHelper.Watermark="Recherche rubrique">
    <TextBox.Style>
      <Style BasedOn="{StaticResource SearchMetroTextBox}" TargetType="{x:Type TextBox}">
        <Style.Triggers>
          <Trigger Property="controls:TextboxHelper.HasText" Value="True">
            <Setter Property="controls:TextboxHelper.ButtonTemplate" Value="{DynamicResource ChromelessButtonTemplate}" />
          </Trigger>
        </Style.Triggers>
      </Style>
    </TextBox.Style>
  </TextBox>
  <TextBlock Grid.Row="1"
             Margin="5,0"
             HorizontalAlignment="Right"
             FontSize="12"
             Foreground="{DynamicResource ColorBleu}"
             Text="{Binding TreeRubriques.SelectedItem}" />
  <TreeView Name="TreeViewGeneral"
            Grid.Row="2"
            ItemContainerStyle="{DynamicResource TreeViewItemStyle}"
            ItemsSource="{Binding Path=TreeRubriques}">
    <TreeView.ItemTemplate>
      <HierarchicalDataTemplate ItemsSource="{Binding Children}">
        <TextBlock>
          <TextBlock.Inlines>
            <Run>
              <Run.Text>
                <MultiBinding Converter="{StaticResource HighlightConverter}" ConverterParameter="Start">
                  <Binding Mode="OneWay" Path="DisplayText" />
                  <Binding ElementName="SearchBox"
                           Mode="OneWay"
                           Path="DataContext.SearchCompteGeneral" />
                </MultiBinding>
              </Run.Text>
            </Run>
            <Run Style="{DynamicResource HighlightStyle}">
              <Run.Text>
                <MultiBinding Converter="{StaticResource HighlightConverter}" ConverterParameter="Find">
                  <Binding Mode="OneWay" Path="DisplayText" />
                  <Binding ElementName="SearchBox"
                           Mode="OneWay"
                           Path="DataContext.SearchCompteGeneral" />
                </MultiBinding>
              </Run.Text>
            </Run>
            <Run>
              <Run.Text>
                <MultiBinding Converter="{StaticResource HighlightConverter}" ConverterParameter="End">
                  <Binding Mode="OneWay" Path="DisplayText" />
                  <Binding ElementName="SearchBox"
                           Mode="OneWay"
                           Path="DataContext.SearchCompteGeneral" />
                </MultiBinding>
              </Run.Text>
            </Run>
          </TextBlock.Inlines>
        </TextBlock>
      </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
  </TreeView>
</Grid>

,

Poster un commentaire

%d blogueurs aiment cette page :