IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

PixelFormat.Format16bppGrayScale toujours mal supporté ?


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    999
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 999
    Par défaut PixelFormat.Format16bppGrayScale toujours mal supporté ?
    Bonjour,

    Je manipule un bitmap, que j'utilise pour faire des "heights maps" afin de créer en 3D des lithophanies ou des gravures

    La luminosité d'un pixel (ou son "niveau de gris") correspond à une hauteur selon l'axe Z, l'image étant un plan XY

    J'arrive à faire tout ce que je veux, j'ai un peut triché en utilisant des fausses couleurs pour que le niveau de gris ne soit pas sur 8 bits (256 niveaux ) mais sur 24 bits en utilisant les octets R, G et B comme des octets de poids faible, poids intermédiaire et poids forts du niveau de gris.

    Grâce à un handle j'accède directement aux données du bitmap (32 bits par pixels) sous forme de tableau sans passer par les coûteuses fonctions SetPixel et GetPixel.

    Cette façon de faire permet à la fois :
    - d'avoir un tableau de coordonnées XYZ rapide à utiliser et économe en mémoire (certes le 4e octet "alpha" n'est pas utilisé mais sur un CPU 32 ou 64 bits il est compliqué et sous-performant de manipuler des données 24 bits)
    - de pouvoir utiliser toutes les fonctions graphiques 2D de GDI+ pour créer des formes et des textes variés

    MAIS mon usage de "fausses couleurs" m'interdit d'utiliser les fonctions graphiques avec un antialiasing.
    Je dois lisser l'image après les dessins avec quelques passes de filtre moyenne (voir ici : http://ressources.unit.eu/cours/vide..._filtering.pdf)

    C'est un peut dommage, car un antialiasing "natif" serait meilleur, notamment sur les textes, j'aurais toujours besoin d'adoucir l'image ensuite mais beaucoup moins, ce qui éviterais d'avoir des formes trop "fondues"

    Vous allez me dire, pourquoi faire simple quand on peut faire compliqué ?

    Pourquoi ne pas travailler en couleurs et tout convertir en niveau de gris à la fin ?

    - 8 bits n'offre que 256 niveaux de gris, c'est une résolution un peu trop faible pour mon application

    - l'antialiasing en RGB correspond à l'algorithme "cleartype", qui tiens compte du fait de la positions relative des pixels rouges, verts et bleus dans un écran, alors que dans mon application il n'y a que des pixels gris ; si cleartype génère sur l'écran des images ayant un aspect très propres, après conversion en niveau de gris c'est décalé et flou

    Pourquoi ne pas travailler avec un bitmap directement en niveau de gris ?

    Le bitmap 8 bits ne convient pas :

    - 8 bits n'offre que 256 niveaux de gris, c'est une résolution un peu trop faible pour mon application

    - et surtout car le format "8 bits niveaux de gris" n'existe pas : il faut créer un bitmap 8 bits "indexé" c'est à dire avec une palette, et remplir les 256 couleurs de la palette avec les 256 niveaux de gris... or l'antialiasing ne peut pas fonctionner avec des bitmaps indexés

    Et les bitmaps grayscale 16 bits ?

    Cela semblait évident, il y a dans .NET un PixelFormat.Format16bppGrayScale

    Et 16 bits offre 65536 niveaux de gris, cette résolution est assez bonne pour ce que j'ai besoin de faire.

    Mais la joie fut de courte durée...

    PixelFormat.Format16bppGrayScale est très mal pris en charge par .NET/GDI+ (http://www.windows-tech.info/1/2b462b01460fe2a1.php)

    En gros, ce mode existe, mais :
    - les calculs et l'affichage se font sur 8 bits (donc aucun intérêt) - car en effet, les fonctions graphiques prennent en paramètre une couleur ARGB avec 8 bits par composante (il aurait fallu une surcharge de ces fonctions avec un niveau de gris sur 16 bits à la place d'une couleur ARGB)
    - pire certaines fonctions plantent (comme l'enregistrement d'une image avec .Save())

    C'est à se demander pourquoi Format16bppGrayScale existe.

    Les informations que j'ai trouvé sur le sujet sont assez anciennes ; est-ce que ça a évolué depuis, ou bien est-ce que les graphismes en niveaux de gris sont toujours "oubliés" par .NET ?

    C'est dommage, car on a pas besoin de tout faire en couleurs vraies sur 32 bits, il existe de réels besoins de traitement sur des images avec un seul canal sur 8 bits, 16 bits voire plus :
    - applications scientifiques
    - traitement numérique du signal
    - traitement d'images venant de photoastronomie, de caméras IR, UV ou rayons X
    - scan et impression 3D
    - ...

    A bientôt

  2. #2
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    999
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 999
    Par défaut
    Direct2D, présenté parfois comme successeur de GDI, ne semble pas faire mieux sur le support des images en niveau de gris :

    https://stackoverflow.com/questions/...channel-bitmap

    La question est débattue ici :

    https://stackoverflow.com/questions/...structor-error

    http://forums.cgsociety.org/t/dotnet...ages/2050972/8

    https://www.examplefiles.net/cs/1437103

    https://social.msdn.microsoft.com/Fo...=csharpgeneral

    Mais la difficulté/l'impossibilité de l'affichage sur écran LCD de niveaux de gris sur 16 bits est un faux problème...
    L'affichage sur moniteur LCD classique est possible avec une fonction de "loupe" sur l'échelle de luminosité pour mettre en évidence les faibles contrastes sur telle ou telle zone de l'image.
    Et surtout ce qui compte c'est de pouvoir travailler sur l'image en mémoire, qu'importe que son affichage soit moins précis ou compliqué sur le plan ergonomique, puisque l'image sera utilisée pour du calcul, de l'usinage ou de l'impression 3D.

    Dommage de devoir réécrire de zéro les fonctions graphiques avec antialiasing

    L'API FreeImage prend en charge les bitmaps "spéciaux" mais ne propose aucune fonction de dessin :
    file:///D:/_DONNEES/_CNC/VBNET_LUCAS_BMP_CNC/FreeImage3180.pdf

    Leadtools propose des outils pour gérer des images médicales sur 16 bits
    ... avec des tarifs correspondant au matériel médical
    https://www.leadtools.com/support

  3. #3
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    999
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 999
    Par défaut WPF à la rescousse ?
    Il semblerait que WPF supporterai les bitmaps en niveau de gris sur 16 bits...
    ...Et il serait possible d'appeler les fonctions WPF dans un projet Windows Form classique

    https://coderedirect.com/questions/4...-bitmap-in-net

    Concrètement :
    - Je suis allé dans le Menu "Projet" > "Ajouter une référence..."
    - Dans la fenêtre qui s'ouvre, cliquer sur l'onglet "Assemblys"
    - Trouver et cocher :
    * PresentationCore
    * WindowsBase
    * System.Xaml

    On peut alors accéder à l'espace de noms System.Windows.Media qui contient pas mal de fonctions WPF

    Je me suis contenté de ce bout de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            Dim Bmp16 As Windows.Media.Imaging.WriteableBitmap
            Bmp16 = New Windows.Media.Imaging.WriteableBitmap(Width, Height, 120, 120, Windows.Media.PixelFormats.Gray16, Nothing)
    Le "nothing" c'est pour la palette, elle est inutile avec PixelFormats.Gray16 et il n'y a pas de constructeur permettant de préciser un pixelformat sans palette

    Lire la documentation ? pourquoi faire
    J'ai déjà passé mon dimanche à lire des posts sur des forums en anglais, il est tard et je n'ai pas mangé, en plus c'est mon dernier jour de vacances, place à l'action maintenant et vive la méthode bourrin

    Petite précision : j'utilise Visual Studio 2015 sous Windows 7 Intégrale (paye ta config obsolète ) mais sur un bon PC avec une bonne carte graphique, un SSD pour le système, 16 Go de RAM.

    Je lance le déboggage...

    Ca commence par une exception (paye ton RTFM ), certainement liée au côté crade d'avoir placé des références pour accéder à des fonctions WPF :

    L'Assistant Débogage managé 'LoadFromContext' a détecté un problème dans 'D:\_DONNEES\_CNC\VBNET_LUCAS_BMP_CNC\LUCAS_BMP_CNC\bin\Debug\LUCAS_BMP_CNC.vshost.exe'.

    Informations supplémentaires*: L'assembly nommé 'WpfXamlDiagnosticsTap' a été chargé à partir de 'file:///C:/PROGRAM FILES (X86)/MICROSOFT VISUAL STUDIO 14.0/COMMON7/IDE/COMMONEXTENSIONS/MICROSOFT/CLIENTDIAGNOSTICS/XAMLDIAGNOSTICS/x64/WpfXamlDiagnosticsTap.dll' à l'aide du contexte LoadFrom. L'utilisation de ce contexte peut provoquer un comportement inattendu lors des opérations de sérialisation, de conversion et de résolution de dépendance. Dans la grande majorité des cas, il est recommandé d'éviter le contexte LoadFrom. Pour ce faire, il suffit d'installer les assemblys dans le Global Assembly Cache ou dans le répertoire ApplicationBase et d'utiliser Assembly.Load lors du chargement explicite des assemblys.

    S'il existe un gestionnaire pour cette exception, le programme peut continuer en toute sécurité.


    On verra ça plus tard, alors non je n'ai pas de gestionnaire mais pour "la sécurité" le PC ne va pas m'exploser à la figure non plus vu que je suis passé en mode bourrin je clique sur le bouton "continuer"

    Mon programme fonctionne normalement, je clique sur le bouton avec le code WPF ça ne plante pas

    Je vais voir si ces fonctions WPF permettent de faire ce que je n'arrive pas à faire avec GDI+
    Et en profiter pour comparer la consommation mémoire et la rapidité avec la méthode classique tant qu'à faire.

    C'est bien de pouvoir recourir à des fonctions WPF dans une application windows form, surtout si j'arrive à le faire proprement ensuite.
    L'application est assez grosse avec plein de fenêtres, je n'ai pas envie de tout migrer sous WPF juste pour une fonction.
    A noter que dans mon application, toutes les fonctions d'affichage graphique en 2D et en 3D sont faites de façon rapide et accélérées par la carte graphique avec OpenGL via OpenTK.
    Les fonctions graphiques GDI+ ne sont utilisés que pour cette histoire de bitmap en niveau de gris.

    Qu'en pensez vous ?

    A bientôt

Discussions similaires

  1. Le projet Kusu est il toujours supporté?
    Par wodel dans le forum RedHat / CentOS / Fedora
    Réponses: 0
    Dernier message: 27/05/2012, 18h02
  2. [Newsletter] j'ai toujours du mal a recevoir ma Newsletter par mail
    Par Invité dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 1
    Dernier message: 26/06/2011, 13h05
  3. Accents mal supporté dans les mails envoyés.
    Par laclac dans le forum Langage
    Réponses: 3
    Dernier message: 06/07/2010, 08h56
  4. Réponses: 7
    Dernier message: 19/09/2009, 18h01
  5. [Migration] inventaire des "éléments" supportant mal la migration
    Par Stebfr dans le forum Administration-Migration
    Réponses: 3
    Dernier message: 12/05/2009, 16h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo