none
Dessiner une forme sur une image RRS feed

  • Question

  • Bonjour,

    Dans le cadre d'un projet d'une application pour tablette Windows 8, je dois récupérer une photo et permettre à l'utilisateur d'entourer (forme libre) une zone de la photo. J'ai réussi à récupérer la photo et à l'afficher grâce à un composant Image.

    Le problème maintenant est que je ne sais pas du tout comment faire pour entourer une zone sur une image. De plus je dois ensuite enregistrer la photo avec la zone entourer. Il s'agit de mon premier projet en programmation sur tablette Windows 8 mais je connais assez bien la programmation C#.

    Voici le code que j'utilise pour afficher la photo à l'écran:

    woundExam = (WoundExam)e.Parameter; // récupération de l'objet contenant ma photo
    BitmapImage bitmapImage = new BitmapImage(woundExam.UriPhoto); // création d'un bitmapImage pour l'affichage à partir de l'URI
    imgViewer.Source = bitmapImage; // affichage de la photo

    Merci d'avance pour votre aide.

    samedi 6 avril 2013 14:29

Réponses

Toutes les réponses

  • Salut, moi je placerai un canvas sur ton image... et ainsi tu peux dessiner tout ce que tu veux. Attention à préciser que ton Canvas ai bien un Background="Transparent" sinon il ne dessinera rien (y'a une histoire comme ça).  j'ai fais ça dans mon app DrawPlan
    http://msdn.microsoft.com/en-us/library/cc189073(v=vs.95).aspx

    Christophe http://www.peug.net http://www.sodeasoft.com


    • Modifié Christophe PeuMVP samedi 6 avril 2013 14:45
    • Marqué comme réponse Zosso dimanche 7 avril 2013 12:51
    samedi 6 avril 2013 14:43
  • Bonjour,

    Merci pour ta réponse. Cela me donne un bon début pour ce que je veux faire. Le lien que tu m'as fourni m'as donné quelques idées à appliquer.

    Lorsque j'aurai une solution à mon problème, je la partagerai volontiers.

    dimanche 7 avril 2013 12:53
  • Avec un petit temps de retard, je mets ma solution à disposition:

    private void cnvDrawArea_PointerMoved(object sender, PointerRoutedEventArgs e) { if (isPressed) { // obtain the current position of the contact Windows.UI.Input.PointerPoint pp = e.GetCurrentPoint(cnvDrawArea); Point point = new Point(pp.Position); // it needs two points: the current and the previous point if (area.NumberOfPoint > 0) { SolidColorBrush scbArea = new SolidColorBrush(Windows.UI.Colors.Red); Line lineArea = new Line(); lineArea.Fill = scbArea; lineArea.Stroke = scbArea; lineArea.StrokeThickness = 5; lineArea.X1 = area.LastPoint.X; lineArea.Y1 = area.LastPoint.Y; lineArea.X2 = point.X; lineArea.Y2 = point.Y; cnvDrawArea.Children.Add(lineArea); } area.Add(point); } } private void cnvDrawArea_PointerPressed(object sender, PointerRoutedEventArgs e) { isPressed = true; } private void cnvDrawArea_PointerReleased(object sender, PointerRoutedEventArgs e) { isPressed = false; }

    private void cnvDrawArea_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
    {
        isPressed = false;
        // clear the draw area
        cnvDrawArea.Children.Clear();
        area.Clear();
    }

    L'objet area est un objet de type Surface que j'ai défini moi-même pour stocker mes points, un simple tableau de Point peut le remplacer.

    cnvDrawArea est un contrôleur Canvas que j'ai inséré dans ma vu via le XAML.

    Afin d'effacer les dessins, j'ai utilisé le double tap.

    En principe, cette solution doit gérer les écrans tactiles et les écrans normaux (avec une souris) grâce au booléen isPressed.

    Si vous avez des questions, n'hésitez pas. Je vous aiderai dans la mesure du possible.

    mardi 4 juin 2013 12:33
  • Bonsoir,
    tout d'abord désolé de faire remonter ce sujet qui remonte à déjà un an, mais j'aurai besoin de rapides conseils.

    J'ai pour projet personnel de créer une application dans laquelle on pourrait ouvrir une photo puis y entourer des zones et laisser des commentaires. (cela se rapproche beaucoup de ce que vous avez fait en somme)

    Un grand merci d'abord pour avoir mis votre solution à disposition, cependant je manque d'expérience et de savoir-faire pour réussir à faire fonctionner celle-ci chez moi. J'ai de solides bases en programmation mais c'est la premiere fois que je m'attaque au XAML.

    J'utilise visual studio pour cela, et j'aurais aimé savoir comment faire pour faire fonctionner une application similaire à la votre.

    Pourriez-vous me donner un coup de main?

    Cordialement, 
    Bob V

    vendredi 16 mai 2014 19:11
  • Bonjour Bob,

    Inutile de t'excuser, si j'ai mis ma solution en ligne c'est pour qu'elle serve à quelqu'un :-)

    Pour faire ce que tu veux, il me semble nécessaire que tu comprennes bien comment fonctionne le contrôleur Canvas et comment l'utiliser autant en XAML qu'en C# (ou autre langage). Lors de mes recherches, ces pages m'avaient bien aidé: 

    Classe Canvas: http://msdn.microsoft.com/fr-fr/library/system.windows.controls.canvas(v=vs.110).aspx

    Exemple d'utilisation: http://msdn.microsoft.com/en-us/library/ms745163(v=vs.110).aspx

    Pour le XAML, il s'agit d'une variante de Microsoft du XML. Ils l'ont optimisé pour la création d'interface graphique. La logique est la même. Il n'y a rien de compliqué, en quelques tutos tu devrais vite comprendre. Là encore les pages de docs msdn.microsoft.com... sont très utiles et bien faites. Le contenu est très fourni.

    Pour un exemple de Canvas sur une image, voici un petit bout de code:

    <Page
        x:Class="perriard_zosso_epatient_windows8.ExamPhotoView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:perriard_zosso_epatient_windows8"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
        
        <Grid Background="LightGray">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
    
            <StackPanel x:Name="pnlWoundArea" Background="White" Grid.Column="1" Grid.Row="1" Margin="0,10">
                <TextBlock x:Name="txtWoundAreaText" Foreground="Black" Margin="10,0,10,0" VerticalAlignment="Center" Grid.ColumnSpan="3" Grid.Row="1" Grid.Column="1" Style="{StaticResource MainTextStyle}"/>
            </StackPanel>
            <Image x:Name="imgPhoto" MaxWidth="544" MaxHeight="408" Grid.Column="1" Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            <Canvas x:Name="cnvDrawArea" Grid.Column="1" Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Transparent"/>
        </Grid>
    </Page>

    Ce qu'il faut retenir de ce bout de XAML c'est que le Canvas et l'Image sont indépendant. Ils sont placés dans la même grille du tableau défini par le layout Grid (il permet de découper ton interface graphique en une grille pour disposer facilement les éléments de l'interface). La taille de la case occupé dépendant de Image et Canvas s'adapte à cette taille. De plus Canvas à un fond transparent.

    Il faut aussi cerner les différentes problématiques de ton projet:

    1) récupérer la photo (source puis bitmap, logique d'application)

    2) afficher la photo (contrôleur Image, déclarer en XAML, interface)

    3) déclarer ta zone de dessin (contrôleur Canvas, déclarer en XAML, interface)

    4) définir les moyens de dessin, tactile ou pas car ça influence les événements à utiliser pour le canvas, mon code gère les deux.

    5) dessiner un point car le tracé sera en fait une suite de points reliés (logique d'application et interface)

    6) récupérer le point et le stocker pour pouvoir redessiner le tracé plus tard (logique d'application et modèle de données

    7) lier la photo aux commentaires et à la collection de point (une classe conviendra parfaitement, modèle de données)

    Tout ça fait une masse de code. Pour que je puisse plus t'aider il faudrait me dire sur lequel (lesquels) de ces points tu voudrais des conseils.

    Salutations,

    Pascal

    samedi 17 mai 2014 19:52