locked
Limite de CameraCaptureTask RRS feed

  • Question

  • Bonjour,

     

    J'utilise actuellement l'appareil photo pour localiser une forme géométrique dans l'espace et j'ai un petit soucis de performance. J'aurai aimé savoir si il est possible (d'après mes recherches non, mais une petite confirmation ne fait pas de mal) de pouvoir configurer la résolution et/ou l'effet de l'appareil photo ?

     

    Si ce n'est pas le cas, était-il possible d'ajouter un cadre et/ou un cible à l'écran de l'appareil photo afin de "forcer" l'utilisateur à centrer la forme dans la photo et ainsi pouvoir découper la photo avant de la traiter ??

     

    Car actuellement les appareils de test prennent par défaut des photos couleurs en 3264x2448 qui sont traités en intégralité plusieurs fois dont 1 pour le passage en N&B.

     

    De plus, j'effectue un pré-traitement pour gérer l'orientation de la photo et avoir un rendu correcte. J'utilise cette méthode : http://timheuer.com/blog/archive/2010/09/23/working-with-pictures-in-camera-tasks-in-windows-phone-7-orientation-rotation.aspx

    Cependant, elle est assez lourde et lors de test de prise de photo classique (donc test uniquement sur la bonne orientation de l'image) après la prise de photo le temps d'affichage est supérieur à 1 seconde oO. Est-il possible d'améliorer ce résultat ?

     

    Je vous remercie par avance.

    vendredi 22 juillet 2011 07:34

Réponses

  • Bonjour, sous la version actuelle (Nodo) :

     

    >J'aurai aimé savoir si il est >possible (d'après mes recherches non, mais une petite confirmation ne fait pas de mal) de pouvoir configurer la résolution et/ou l'effet de l'appareil photo ?

    Pas possible actuellement

     

    >Si ce n'est pas le cas, était-il possible d'ajouter un cadre et/ou un cible à l'écran de l'appareil photo afin de "forcer" l'utilisateur à centrer la forme dans la photo et ainsi pouvoir découper la photo avant de la traiter ??

    CameraCaptureTask est comme son nom l'indique, une tache, ton application laisse la main complètement à l'application APN, il est impossible d'ajouter quoique ce soit (sous mango, tu pourras gérer la caméra directement depuis ton app)

     

    Pour l"histoire de la durée, il faudrait voir ton code pour te répondre

     

     


    WP addict
    • Proposé comme réponse rudyhuynMVP samedi 23 juillet 2011 21:19
    • Marqué comme réponse Sebastien.F lundi 25 juillet 2011 11:15
    samedi 23 juillet 2011 21:10
  • il suffit que tu fusionnes tes deux traitements pour avoir de meilleur performance, tu crées deux writeablebitmap que tu parcours entièrement, tu peux ne faire qu'une seule passe et gagner quasiment 50% de temps !

    de plus en sortant le switch case de ta boucle, tu auras de meilleurs perfs

     

     private WriteableBitmap RotateAndGray(Stream stream, int angle)
      {
       stream.Position = 0;
       if (angle % 90 != 0 || angle < 0) throw new ArgumentException();
       
       BitmapImage bitmap = new BitmapImage();
       bitmap.SetSource(stream);
       WriteableBitmap wbSource = new WriteableBitmap(bitmap);
       var pixelWidth = wbSource.PixelWidth;
       var pixelHeight = wbSource.PixelHeight;
       WriteableBitmap wbTarget = null;
       if (angle % 180 == 0)
       {
        wbTarget = new WriteableBitmap(pixelWidth, pixelHeight);
       }
       else
       {
        wbTarget = new WriteableBitmap(pixelHeight, pixelWidth);
       }
    
       angle = angle % 360;
       if (angle == 0)
       {
        for (int x = 0; x < pixelWidth; x++)
        {
         for (int y = 0; y < pixelHeight; y++)
         {
          wbTarget.Pixels[y + x * pixelWidth] = ToGray(wbSource.Pixels[x + y * pixelWidth]);
    
         }
        }
       }
       else if (angle == 90)
       {
        for (int x = 0; x < pixelWidth; x++)
        {
         for (int y = 0; y < pixelHeight; y++)
         {
          wbTarget.Pixels[(pixelHeight - y - 1) + x * wbTarget.PixelWidth] = ToGray(wbSource.Pixels[x + y * pixelWidth]);
    
         }
        }
       }
       else if (angle == 180)
       {
        for (int x = 0; x < pixelWidth; x++)
        {
         for (int y = 0; y < pixelHeight; y++)
         {
          wbTarget.Pixels[(pixelWidth - x - 1) + (pixelHeight - y - 1) * pixelWidth] = ToGray(wbSource.Pixels[x + y * pixelWidth]);
    
         }
        }
       }
       else if (angle == 270)
       {
        for (int x = 0; x < pixelWidth; x++)
        {
         for (int y = 0; y < pixelHeight; y++)
         {
          wbTarget.Pixels[y + (pixelWidth - x - 1) * pixelHeight] = ToGray(wbSource.Pixels[x + y * pixelWidth]);
    
         }
        }
       }
    
       return wbTarget;
      }


    Oublies pas d'indiquer les messages comme réponse s'ils te conviennent !


    WP addict
    • Proposé comme réponse rudyhuynMVP lundi 25 juillet 2011 09:12
    • Marqué comme réponse Sebastien.F lundi 25 juillet 2011 11:17
    lundi 25 juillet 2011 09:11

Toutes les réponses

  • Bonjour, sous la version actuelle (Nodo) :

     

    >J'aurai aimé savoir si il est >possible (d'après mes recherches non, mais une petite confirmation ne fait pas de mal) de pouvoir configurer la résolution et/ou l'effet de l'appareil photo ?

    Pas possible actuellement

     

    >Si ce n'est pas le cas, était-il possible d'ajouter un cadre et/ou un cible à l'écran de l'appareil photo afin de "forcer" l'utilisateur à centrer la forme dans la photo et ainsi pouvoir découper la photo avant de la traiter ??

    CameraCaptureTask est comme son nom l'indique, une tache, ton application laisse la main complètement à l'application APN, il est impossible d'ajouter quoique ce soit (sous mango, tu pourras gérer la caméra directement depuis ton app)

     

    Pour l"histoire de la durée, il faudrait voir ton code pour te répondre

     

     


    WP addict
    • Proposé comme réponse rudyhuynMVP samedi 23 juillet 2011 21:19
    • Marqué comme réponse Sebastien.F lundi 25 juillet 2011 11:15
    samedi 23 juillet 2011 21:10
  • Merci pour ces réponses !

     

    > Pour l"histoire de la durée, il faudrait voir ton code pour te répondre

     

    Le code qui me pose vraiment problème c'est celui mis en lien pour gérer l'orientation de la photo. En effet, ce simple code avec le passage de couleur à N&B me prend en moyenne 3,5 secondes !!...

     

    Voila le code en question :

     

          e.ChosenPhoto.Position = 0;
          JpegInfo info = ExifReader.ReadJpeg(e.ChosenPhoto, e.OriginalFileName);
    
          _width = info.Width;
          _height = info.Height;
          _orientation = info.Orientation;
    
          PostedUri.Text = info.Orientation.ToString();
    
          switch (info.Orientation)
          {
            case ExifOrientation.TopLeft:
            case ExifOrientation.Undefined:
              _angle = 0;
              break;
            case ExifOrientation.TopRight:
              _angle = 90;
              break;
            case ExifOrientation.BottomRight:
              _angle = 180;
              break;
            case ExifOrientation.BottomLeft:
              _angle = 270;
              break;
          }
    
          if (_angle > 0d)
          {
            capturedImage = RotateStream(e.ChosenPhoto, _angle);
          }
          else
          {
            capturedImage = e.ChosenPhoto;
          }
    
          WriteableBitmap writeableBmp = new WriteableBitmap(0, 0), writeableBmp2 = new WriteableBitmap(0, 0);
    
          writeableBmp.SetSource(capturedImage);
    
          writeableBmp = ToAverageGrayscale(new WriteableBitmap(writeableBmp));
    
    

     

    La fonction ToAverageGrayscale :

    WriteableBitmap ToAverageGrayscale(WriteableBitmap bmp)
        {
          WriteableBitmap grayscale = new WriteableBitmap(bmp.PixelWidth, bmp.PixelHeight);
          
          for (int pixelIndex = 0;
            pixelIndex < bmp.Pixels.Length;
            pixelIndex++)
          {
            int pixelColor = bmp.Pixels[pixelIndex];
            byte red = (byte)((pixelColor & 0xFF0000) >> 16);
            byte green = (byte)((pixelColor & 0xFF00) >> 8);
            byte blue = (byte)(pixelColor & 0xFF);
    
            byte intensity = (byte)((red + green + blue) / 3);
    
            grayscale.Pixels[pixelIndex] = 255 << 24
              | intensity << 16
              | intensity << 8
              | intensity;
          }
          return grayscale;
        }
    


    Et la Fonction RotateSteam :

    private Stream RotateStream(Stream stream, int angle)
        {
          stream.Position = 0;
          if (angle % 90 != 0 || angle < 0) throw new ArgumentException();
          if (angle % 360 == 0) return stream;
    
          BitmapImage bitmap = new BitmapImage();
          bitmap.SetSource(stream);
          WriteableBitmap wbSource = new WriteableBitmap(bitmap);
    
          WriteableBitmap wbTarget = null;
          if (angle % 180 == 0)
          {
            wbTarget = new WriteableBitmap(wbSource.PixelWidth, wbSource.PixelHeight);
          }
          else
          {
            wbTarget = new WriteableBitmap(wbSource.PixelHeight, wbSource.PixelWidth);
          }
    
          for (int x = 0; x < wbSource.PixelWidth; x++)
          {
            for (int y = 0; y < wbSource.PixelHeight; y++)
            {
              switch (angle % 360)
              {
                case 90:
                  wbTarget.Pixels[(wbSource.PixelHeight - y - 1) + x * wbTarget.PixelWidth] = wbSource.Pixels[x + y * wbSource.PixelWidth];
                  break;
                case 180:
                  wbTarget.Pixels[(wbSource.PixelWidth - x - 1) + (wbSource.PixelHeight - y - 1) * wbSource.PixelWidth] = wbSource.Pixels[x + y * wbSource.PixelWidth];
                  break;
                case 270:
                  wbTarget.Pixels[y + (wbSource.PixelWidth - x - 1) * wbTarget.PixelWidth] = wbSource.Pixels[x + y * wbSource.PixelWidth];
                  break;
              }
            }
          }
          MemoryStream targetStream = new MemoryStream();
          wbTarget.SaveJpeg(targetStream, wbTarget.PixelWidth, wbTarget.PixelHeight, 0, 100);
          return targetStream;
        }
    

    Comme vous pouvez le constater, pour la rotation de la photo j'ai conservé en état la fonction trouvé sur le lien que j'ai fournis dans mon précédent message. (en autre car je ne maîtrise pas spécialement le sujet ^^) Après ces temps son peut-être normaux en vue du support mais n'ayant pas l'habitude de ce support (je parle de WP7 ;) ) et ayant vue des applications similaires avoir des lancements plus "fulgurent" sur d'autre smartphone, cela peut fausser mon jugement.

    lundi 25 juillet 2011 08:42
  • il suffit que tu fusionnes tes deux traitements pour avoir de meilleur performance, tu crées deux writeablebitmap que tu parcours entièrement, tu peux ne faire qu'une seule passe et gagner quasiment 50% de temps !

    de plus en sortant le switch case de ta boucle, tu auras de meilleurs perfs

     

     private WriteableBitmap RotateAndGray(Stream stream, int angle)
      {
       stream.Position = 0;
       if (angle % 90 != 0 || angle < 0) throw new ArgumentException();
       
       BitmapImage bitmap = new BitmapImage();
       bitmap.SetSource(stream);
       WriteableBitmap wbSource = new WriteableBitmap(bitmap);
       var pixelWidth = wbSource.PixelWidth;
       var pixelHeight = wbSource.PixelHeight;
       WriteableBitmap wbTarget = null;
       if (angle % 180 == 0)
       {
        wbTarget = new WriteableBitmap(pixelWidth, pixelHeight);
       }
       else
       {
        wbTarget = new WriteableBitmap(pixelHeight, pixelWidth);
       }
    
       angle = angle % 360;
       if (angle == 0)
       {
        for (int x = 0; x < pixelWidth; x++)
        {
         for (int y = 0; y < pixelHeight; y++)
         {
          wbTarget.Pixels[y + x * pixelWidth] = ToGray(wbSource.Pixels[x + y * pixelWidth]);
    
         }
        }
       }
       else if (angle == 90)
       {
        for (int x = 0; x < pixelWidth; x++)
        {
         for (int y = 0; y < pixelHeight; y++)
         {
          wbTarget.Pixels[(pixelHeight - y - 1) + x * wbTarget.PixelWidth] = ToGray(wbSource.Pixels[x + y * pixelWidth]);
    
         }
        }
       }
       else if (angle == 180)
       {
        for (int x = 0; x < pixelWidth; x++)
        {
         for (int y = 0; y < pixelHeight; y++)
         {
          wbTarget.Pixels[(pixelWidth - x - 1) + (pixelHeight - y - 1) * pixelWidth] = ToGray(wbSource.Pixels[x + y * pixelWidth]);
    
         }
        }
       }
       else if (angle == 270)
       {
        for (int x = 0; x < pixelWidth; x++)
        {
         for (int y = 0; y < pixelHeight; y++)
         {
          wbTarget.Pixels[y + (pixelWidth - x - 1) * pixelHeight] = ToGray(wbSource.Pixels[x + y * pixelWidth]);
    
         }
        }
       }
    
       return wbTarget;
      }


    Oublies pas d'indiquer les messages comme réponse s'ils te conviennent !


    WP addict
    • Proposé comme réponse rudyhuynMVP lundi 25 juillet 2011 09:12
    • Marqué comme réponse Sebastien.F lundi 25 juillet 2011 11:17
    lundi 25 juillet 2011 09:11
  • Merci pour cette réponse qui va m'être des plus utiles !
    lundi 25 juillet 2011 11:16