Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

OUVERTURE D'UN FICHIER BITMAP EN NATIF


Information sur la source

Catégorie :Graphique Source .NET ( DotNet ) Classé sous : bitmap, bmp, natif, image, octets Niveau : Expert Date de création : 17/02/2007 Date de mise à jour : 17/02/2007 18:27:16 Vu / téléchargé: 10 230 / 44 419

Note :
Aucune note

Commentaire sur cette source (5)
Ajouter un commentaire et/ou une note


Description

Ce code permet d'ouvir un fichier Bmp.

Oui, c'est sur il y a le composant Microsoft qui fait mieux mais ce n'est pas le but de cette source.
Cette source a pour but de montrer comment sont stockées les données dans un fichier Bmp, donc comment visualiser l'image contenue dans le fichier juste en lisant les octets où nativement.

Tout d'abors voici un petit tuto sur la structure d'un fichier Bmp :
http://209.85.135.104/search?q=cache:sZ6XC3UAKHUJ:ancrobot.free.fr/TechFiles/techfile.php%3FTableNum%3D12+fichier+bmp+structure&hl=fr&ct=clnk&cd=11&gl=fr

Il faut savoir qu'un fichier Bmp contient d'abords des entêtes (ou headers) qui nous informe sur la méthode à utiliser pour lire l'image.
Ensuite est stockée la palette de couleurs si la profondeur de l'image est inférieur ou égale à 8 bit.
Cette palette contient toutes les couleurs contenues dans l'image. Il faut les récupérer grâce à leur Index.
Enfin, l'image est stockée (pas toujours de la même façon, c'est là qu'est la difficultée)

Le format BitMap peut utiliser la compression RLE mais elle est tellement peu utilsée que mon programme n'en tient pas compte, il affiche seulement laquelle est utilsée.

Ce programme permet de lire les BitMap signé ("BM"), c'est à dire le format Windows car il existe aussi des variantes pour le système d'exploitation OS/2.
Sont reconnus les profondeurs d'images (ou BitPerPixel) : 24,8,4,1
(Pour 32, il faut juste rajouter Alpha mais peu utilsé dans ce format et pour 16 c'est plus compliqué mais là aussi cette profondeur est peu utilsée)

Pour tester ce programme, télécharger le zip ou servez vous du module ci-dessous. Ouvrez une image pas trop grande. La plupart du temps elle sera en 24Bits. Maintenant ouvrez la avec Paint et amusez vous à la sauvegardez avec differentes profondeurs (256 couleurs, 16, N&B) puis réouvrez là avec le programme.

Le code est assez commenté mais peut s'avérer difficile à comprendre si on n'a pas bien compris comment fonctionne ce format d'image.

Niveau 3 :
-Opération sur les Bits
-Décalage des Bits
-Utilisation de la classe Marshal
-Difficultées de compréhension de la source

Niveau 2 :
-Ouverture d'un flux de fichier
-Lecture d'octets
-Tableaux utilisés pour le stockage des octets
-Rajout d'octets
-Ajout de pixels 1 à 1 en partant du bas avec les coordonnées X,Y

Niveau 1 :
-Boucles
-Utilisation des objets
-Utilisation des structures
-Conditions
-Opérateurs logiques



 

Source

  • 'Module créé par Yves Demirdjian le 17/02/2007
  • 'Ce module permet d'ouvrir une image Bitmap Windows (signé "BM"). OS/2 non pris en charge
  • 'Bitmaps pris en charge : Profondeur 24,8,4,1 bits, aucune compression
  • 'Pas d'optimisation performance
  • 'Ce module a juste pour but de montrer la structure d'un tel fichier
  • Option Strict On
  • Imports System.Text.Encoding
  • Imports System.Runtime.InteropServices
  • Module ModBmp
  • Public OutImage As Image
  • Public BmpFileInfo As BmpInfo
  • Public Structure BmpInfo
  • Public TailleDeLImage As Integer
  • Public OffSetImg As Integer
  • Public LargeurImg As Integer
  • Public HauteurImg As Integer
  • Public NbDeBitParPixel As Integer
  • Public Compression As String
  • Public TailleDeLImageAcRemplissage As Integer
  • Public ResolutionHorizontale As Integer
  • Public ResolutionVerticale As Integer
  • Public NbCouleurPalette As Integer
  • Public NbCouleurImportantes As Integer
  • End Structure
  • Public Sub OpenBmpFile(ByVal File As String)
  • Dim TblBytes() As Byte 'Buffer (tableaud de bytes)
  • Dim StreamBmpRead As New IO.FileStream(File, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read) 'Ouvre un flux de lecture
  • 'On lit l'entête et on vérifie que le fichier est bien signé BMP
  • ReDim TblBytes(1)
  • StreamBmpRead.Read(TblBytes, 0, 2)
  • If ASCII.GetString(TblBytes) <> "BM" Then MsgBox("Ce fichier n'est pas un fichier BMP Windows valide, celui peut être compatible OS/2 non pris en charge dans ce programme!", MsgBoxStyle.Critical Or MsgBoxStyle.OkOnly, "Erreur") : Exit Sub
  • 'On lit la taille de l'image contenue dans 4 octets (non fiable)
  • ReDim TblBytes(3)
  • StreamBmpRead.Read(TblBytes, 0, 4)
  • BmpFileInfo.TailleDeLImage = BytesToInt(TblBytes, 4)
  • 'On lit la valeur qui nous dit où commencer la lecture des données de l'image (offset)
  • StreamBmpRead.Read(TblBytes, 0, 4)
  • StreamBmpRead.Read(TblBytes, 0, 4)
  • BmpFileInfo.OffSetImg = BytesToInt(TblBytes, 4)
  • 'On vérifie que l'entête à bien une valeure de 40 octets
  • StreamBmpRead.Read(TblBytes, 0, 4)
  • If BytesToInt(TblBytes, 4) <> 40 Then MsgBox("L'entête du fichier Bmp n'est pas valide, lecture annulée", MsgBoxStyle.Critical Or MsgBoxStyle.OkOnly, "Erreur") : Exit Sub
  • 'On lit la valeur de la largeur de l'image
  • StreamBmpRead.Read(TblBytes, 0, 4)
  • BmpFileInfo.LargeurImg = BytesToInt(TblBytes, 4)
  • 'On lit la valeur de la hauteur de l'image
  • StreamBmpRead.Read(TblBytes, 0, 4)
  • BmpFileInfo.HauteurImg = BytesToInt(TblBytes, 4)
  • 'On lit la valeur du plan
  • ReDim TblBytes(1)
  • StreamBmpRead.Read(TblBytes, 0, 2)
  • If BytesToInt(TblBytes, 2) <> 1 Then MsgBox("La valeur du plan n'est pas valide, la lecture du fichier continue mais pourra poser problème.", MsgBoxStyle.Critical Or MsgBoxStyle.OkOnly, "Erreur")
  • 'On lit la valeur du nombre de bit par pixel
  • StreamBmpRead.Read(TblBytes, 0, 2)
  • BmpFileInfo.NbDeBitParPixel = BytesToInt(TblBytes, 2)
  • 'On lit la valeur de la compréssion utilsée
  • ReDim TblBytes(3)
  • StreamBmpRead.Read(TblBytes, 0, 4)
  • Select Case BytesToInt(TblBytes, 4)
  • Case 0
  • BmpFileInfo.Compression = "Aucune"
  • Case 1
  • BmpFileInfo.Compression = "RLE-8"
  • Case 2
  • BmpFileInfo.Compression = "RLE-4"
  • Case 3
  • BmpFileInfo.Compression = "BitField"
  • Case Else
  • BmpFileInfo.Compression = "Inconnue"
  • End Select
  • 'On lit la valeur de la taille de l'image avec le remplissage
  • StreamBmpRead.Read(TblBytes, 0, 4)
  • BmpFileInfo.TailleDeLImageAcRemplissage = BytesToInt(TblBytes, 4)
  • 'On lit la valeur de la resolution horizontale en pixel par metre (non fiable)
  • StreamBmpRead.Read(TblBytes, 0, 4)
  • BmpFileInfo.ResolutionHorizontale = BytesToInt(TblBytes, 4)
  • 'On lit la valeur de la resolution verticale en pixel par metre (non fiable)
  • StreamBmpRead.Read(TblBytes, 0, 4)
  • BmpFileInfo.ResolutionVerticale = BytesToInt(TblBytes, 4)
  • 'On lit la valeur du nombre de couleur contenu dans la palette
  • StreamBmpRead.Read(TblBytes, 0, 4)
  • BmpFileInfo.NbCouleurPalette = BytesToInt(TblBytes, 4)
  • 'On lit la valeur du nombre de couleur contenu dans l'image
  • StreamBmpRead.Read(TblBytes, 0, 4)
  • BmpFileInfo.NbCouleurImportantes = BytesToInt(TblBytes, 4)
  • 'Lecture de la palette de couleur si la condition est vérifiée
  • Dim TblPalette() As Byte
  • If BmpFileInfo.NbDeBitParPixel <= 8 Then
  • ReDim TblPalette(CInt(4 * 2 ^ BmpFileInfo.NbDeBitParPixel - 1))
  • StreamBmpRead.Read(TblPalette, 0, TblPalette.Length)
  • End If
  • 'Préparation de l'image
  • Dim Image As New System.Drawing.Bitmap(BmpFileInfo.LargeurImg, BmpFileInfo.HauteurImg)
  • 'Lecture de l'image
  • StreamBmpRead.Position = BmpFileInfo.OffSetImg 'On commence où commence l'image
  • 'Indique si on doit ajouter des octets pour avoir un multiple de 4
  • Dim NbAddOctet As Integer = 0
  • Dim BitEnTrop As Integer = 0
  • 'On prépare en fonction de la profondeur de l'image
  • Dim Mode24 As Byte = CByte(IIf(BmpFileInfo.NbDeBitParPixel = 24, 3, 1))
  • Dim NbOctetBuffer As Integer
  • Select Case BmpFileInfo.NbDeBitParPixel
  • Case 24
  • NbOctetBuffer = 3 * BmpFileInfo.LargeurImg
  • Case 8
  • NbOctetBuffer = BmpFileInfo.LargeurImg
  • Case 4
  • If Int(BmpFileInfo.LargeurImg / 2) < (BmpFileInfo.LargeurImg / 2) Then NbOctetBuffer = CInt(Int(BmpFileInfo.LargeurImg / 2) + 1) Else NbOctetBuffer = CInt(Int(BmpFileInfo.LargeurImg / 2))
  • If (BmpFileInfo.LargeurImg / 4) > (Int(BmpFileInfo.LargeurImg / 4)) Then BitEnTrop = 4
  • Case 1
  • If Int(BmpFileInfo.LargeurImg / 8) < (BmpFileInfo.LargeurImg / 8) Then NbOctetBuffer = CInt(Int(BmpFileInfo.LargeurImg / 8) + 1) Else NbOctetBuffer = CInt(BmpFileInfo.LargeurImg / 8)
  • BitEnTrop = (NbOctetBuffer * 8 - BmpFileInfo.LargeurImg)
  • Case Else
  • NbOctetBuffer = 1
  • End Select
  • If (NbOctetBuffer / 4) > (Int(NbOctetBuffer / 4)) Then NbAddOctet = CInt(Int(NbOctetBuffer / 4) + 1) * 4 - NbOctetBuffer
  • Dim X, Y As Integer 'Position du Pixel a afficher
  • X = 0 'On commence à gauche
  • Y = (BmpFileInfo.HauteurImg - 1) 'On commence en bas de l'image pour l'image (le bas de l'image est stocké en haut)
  • ReDim TblBytes(NbOctetBuffer - 1) 'Buffer en fonction de la largeur
  • Dim ValMaxRead As Integer 'Variable indiquant le nombre d'octets lu
  • Do While StreamBmpRead.Position < StreamBmpRead.Length 'Boucle tant qu'on est pas à la fin du fichier
  • FrmMain.Text = CStr(CInt(StreamBmpRead.Position / StreamBmpRead.Length * 100)) & "% chargé" 'Indiquation utilisateur
  • ValMaxRead = StreamBmpRead.Read(TblBytes, 0, NbOctetBuffer)
  • For I As Integer = 0 To CInt((ValMaxRead / Mode24 - 1)) 'Selon la profondeur et le Buffer
  • Select Case BmpFileInfo.NbDeBitParPixel
  • Case 24 'RGB codé sous 3 octets, pour un mode 32bit il faut rajouter Alpha (je n'ai pas codé ce mode car il est peu présent il faut juste prendre en compte un octet de plus)
  • Image.SetPixel(X, Y, Color.FromArgb(TblBytes(2 + (3 * I)), TblBytes(1 + (3 * I)), TblBytes(0 + (3 * I)))) 'On affiche le pixel (ARGB où A = 255)
  • PixelSuivant(X, Y)
  • Case 8 'Image en 256 couleurs, 1 octet = Index de couleur dans la palette
  • Image.SetPixel(X, Y, Color.FromArgb(TblPalette(TblBytes(I) * 4 + 2), TblPalette(TblBytes(I) * 4 + 1), TblPalette(TblBytes(I) * 4)))
  • PixelSuivant(X, Y)
  • Case 4 ' Ouvre une image en 16 couleurs : chaque octet contient 2 pixels donc codé sous 4 bit, puis trouvé l'index dans la palette pour savoir la couleur
  • Dim Octet1, Octet2 As Byte
  • Octet2 = TblBytes(I) And CByte(15)
  • Octet1 = TblBytes(I) And CByte(240) : Octet1 >>= 4
  • Image.SetPixel(X, Y, Color.FromArgb(TblPalette(Octet1 * 4 + 2), TblPalette(Octet1 * 4 + 1), TblPalette(Octet1 * 4)))
  • PixelSuivant(X, Y)
  • If Not (BitEnTrop = 4 And X = 0 And Octet2 = 0) Then
  • Image.SetPixel(X, Y, Color.FromArgb(TblPalette(Octet2 * 4 + 2), TblPalette(Octet2 * 4 + 1), TblPalette(Octet2 * 4)))
  • PixelSuivant(X, Y)
  • End If
  • Case 1 'Ouvre une image en N&B : il faut traduire chaque octet en huit octets de valeurs 1 ou 0
  • Dim Octet As Byte
  • Dim ByteOperation As Byte = 128
  • If I <> (TblBytes.Length - 1) Then
  • For K As Integer = 0 To 7
  • Octet = TblBytes(I) And ByteOperation
  • Octet >>= (7 - K)
  • ByteOperation >>= 1
  • Image.SetPixel(X, Y, Color.FromArgb(TblPalette(Octet * 4 + 2), TblPalette(Octet * 4 + 1), TblPalette(Octet * 4)))
  • PixelSuivant(X, Y)
  • Next
  • Else
  • For K As Integer = 0 To (7 - BitEnTrop)
  • Octet = TblBytes(I) And ByteOperation
  • Octet >>= (7 - K)
  • ByteOperation >>= 1
  • Image.SetPixel(X, Y, Color.FromArgb(TblPalette(Octet * 4 + 2), TblPalette(Octet * 4 + 1), TblPalette(Octet * 4)))
  • PixelSuivant(X, Y)
  • Next
  • End If
  • End Select
  • Next I
  • If NbAddOctet > 0 Then StreamBmpRead.Read(TblBytes, 0, NbAddOctet)
  • Application.DoEvents() 'Pour laisser l'application afficher le texte
  • Loop
  • 'Fermer le stream
  • StreamBmpRead.Close()
  • 'Remet le titre d'origine
  • FrmMain.Text = "Ouverture d'images en natif"
  • 'Affiche l'image
  • FrmMain.PbPicture.Image = Image
  • 'Libérer les ressources
  • Image = Nothing
  • TblBytes = Nothing
  • TblPalette = Nothing
  • 'Affichage du texte de la structure de l'image
  • FrmMain.TxtInfo.Text = "Headers >> " & vbCrLf & "Compression utilisée : " & BmpFileInfo.Compression & vbCrLf & _
  • "Hauteur de l'image en pixel : " & BmpFileInfo.HauteurImg & vbCrLf & _
  • "Largeur de l'image en pixel : " & BmpFileInfo.LargeurImg & vbCrLf & _
  • "Nombre de couleurs importantes : " & BmpFileInfo.NbCouleurImportantes & vbCrLf & _
  • "Nombre de couleurs de la palette : " & BmpFileInfo.NbCouleurPalette & vbCrLf & _
  • "Profondeur de l'image (en bits) : " & BmpFileInfo.NbDeBitParPixel & vbCrLf & _
  • "Offset du début des données de l'image : " & BmpFileInfo.OffSetImg & vbCrLf & _
  • "Résolution horizontale : " & BmpFileInfo.ResolutionHorizontale & vbCrLf & _
  • "Résolution verticale : " & BmpFileInfo.ResolutionVerticale & vbCrLf & _
  • "Taille de l'image (approx en octets) : " & BmpFileInfo.TailleDeLImage & vbCrLf & _
  • "Taille de l'image avec remplissage (approx en octets) : " & BmpFileInfo.TailleDeLImageAcRemplissage
  • End Sub
  • Private Sub PixelSuivant(ByRef X As Integer, ByRef Y As Integer)
  • X += 1
  • If X > (BmpFileInfo.LargeurImg - 1) Then 'Si on atteint la fin de la ligne
  • X = 0
  • Y -= 1
  • End If
  • End Sub
  • Private Function BytesToInt(ByVal TblBytes() As Byte, ByVal Len As Integer) As Integer
  • 'Comme son nom l'indique cette fonction transforme un tableau de bytes en Integer, il sagit d'une copie mémoire.
  • Dim Number As Integer
  • Dim MyGC As GCHandle = GCHandle.Alloc(Number, GCHandleType.Pinned)
  • Dim AddofLongValue As IntPtr = MyGC.AddrOfPinnedObject()
  • Marshal.Copy(TblBytes, 0, AddofLongValue, Len)
  • Number = Marshal.ReadInt32(AddofLongValue)
  • MyGC.Free()
  • Return Number
  • End Function
  • End Module
'Module créé par Yves Demirdjian le 17/02/2007
'Ce module permet d'ouvrir une image Bitmap Windows (signé "BM"). OS/2 non pris en charge
'Bitmaps pris en charge : Profondeur 24,8,4,1 bits, aucune compression
'Pas d'optimisation performance
'Ce module a juste pour but de montrer la structure d'un tel fichier


Option Strict On
Imports System.Text.Encoding
Imports System.Runtime.InteropServices
Module ModBmp
    Public OutImage As Image
    Public BmpFileInfo As BmpInfo
    Public Structure BmpInfo
        Public TailleDeLImage As Integer
        Public OffSetImg As Integer
        Public LargeurImg As Integer
        Public HauteurImg As Integer
        Public NbDeBitParPixel As Integer
        Public Compression As String
        Public TailleDeLImageAcRemplissage As Integer
        Public ResolutionHorizontale As Integer
        Public ResolutionVerticale As Integer
        Public NbCouleurPalette As Integer
        Public NbCouleurImportantes As Integer
    End Structure

    Public Sub OpenBmpFile(ByVal File As String)
        Dim TblBytes() As Byte 'Buffer (tableaud de bytes)

        Dim StreamBmpRead As New IO.FileStream(File, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read) 'Ouvre un flux de lecture

        'On lit l'entête et on vérifie que le fichier est bien signé BMP
        ReDim TblBytes(1)
        StreamBmpRead.Read(TblBytes, 0, 2)
        If ASCII.GetString(TblBytes) <> "BM" Then MsgBox("Ce fichier n'est pas un fichier BMP Windows valide, celui peut être compatible OS/2 non pris en charge dans ce programme!", MsgBoxStyle.Critical Or MsgBoxStyle.OkOnly, "Erreur") : Exit Sub

        'On lit la taille de l'image contenue dans 4 octets (non fiable)
        ReDim TblBytes(3)
        StreamBmpRead.Read(TblBytes, 0, 4)
        BmpFileInfo.TailleDeLImage = BytesToInt(TblBytes, 4)

        'On lit la valeur qui nous dit où commencer la lecture des données de l'image (offset)
        StreamBmpRead.Read(TblBytes, 0, 4)
        StreamBmpRead.Read(TblBytes, 0, 4)
        BmpFileInfo.OffSetImg = BytesToInt(TblBytes, 4)

        'On vérifie que l'entête à bien une valeure de 40 octets
        StreamBmpRead.Read(TblBytes, 0, 4)
        If BytesToInt(TblBytes, 4) <> 40 Then MsgBox("L'entête du fichier Bmp n'est pas valide, lecture annulée", MsgBoxStyle.Critical Or MsgBoxStyle.OkOnly, "Erreur") : Exit Sub

        'On lit la valeur de la largeur de l'image
        StreamBmpRead.Read(TblBytes, 0, 4)
        BmpFileInfo.LargeurImg = BytesToInt(TblBytes, 4)

        'On lit la valeur de la hauteur de l'image
        StreamBmpRead.Read(TblBytes, 0, 4)
        BmpFileInfo.HauteurImg = BytesToInt(TblBytes, 4)

        'On lit la valeur du plan
        ReDim TblBytes(1)
        StreamBmpRead.Read(TblBytes, 0, 2)
        If BytesToInt(TblBytes, 2) <> 1 Then MsgBox("La valeur du plan n'est pas valide, la lecture du fichier continue mais pourra poser problème.", MsgBoxStyle.Critical Or MsgBoxStyle.OkOnly, "Erreur")

        'On lit la valeur du nombre de bit par pixel
        StreamBmpRead.Read(TblBytes, 0, 2)
        BmpFileInfo.NbDeBitParPixel = BytesToInt(TblBytes, 2)

        'On lit la valeur de la compréssion utilsée
        ReDim TblBytes(3)
        StreamBmpRead.Read(TblBytes, 0, 4)
        Select Case BytesToInt(TblBytes, 4)
            Case 0
                BmpFileInfo.Compression = "Aucune"
            Case 1
                BmpFileInfo.Compression = "RLE-8"
            Case 2
                BmpFileInfo.Compression = "RLE-4"
            Case 3
                BmpFileInfo.Compression = "BitField"
            Case Else
                BmpFileInfo.Compression = "Inconnue"
        End Select

        'On lit la valeur de la taille de l'image avec le remplissage
        StreamBmpRead.Read(TblBytes, 0, 4)
        BmpFileInfo.TailleDeLImageAcRemplissage = BytesToInt(TblBytes, 4)

        'On lit la valeur de la resolution horizontale en pixel par metre (non fiable)
        StreamBmpRead.Read(TblBytes, 0, 4)
        BmpFileInfo.ResolutionHorizontale = BytesToInt(TblBytes, 4)

        'On lit la valeur de la resolution verticale en pixel par metre (non fiable)
        StreamBmpRead.Read(TblBytes, 0, 4)
        BmpFileInfo.ResolutionVerticale = BytesToInt(TblBytes, 4)

        'On lit la valeur du nombre de couleur contenu dans la palette
        StreamBmpRead.Read(TblBytes, 0, 4)
        BmpFileInfo.NbCouleurPalette = BytesToInt(TblBytes, 4)

        'On lit la valeur du nombre de couleur contenu dans l'image
        StreamBmpRead.Read(TblBytes, 0, 4)
        BmpFileInfo.NbCouleurImportantes = BytesToInt(TblBytes, 4)

        'Lecture de la palette de couleur si la condition est vérifiée
        Dim TblPalette() As Byte
        If BmpFileInfo.NbDeBitParPixel <= 8 Then
            ReDim TblPalette(CInt(4 * 2 ^ BmpFileInfo.NbDeBitParPixel - 1))
            StreamBmpRead.Read(TblPalette, 0, TblPalette.Length)
        End If

        'Préparation de l'image
        Dim Image As New System.Drawing.Bitmap(BmpFileInfo.LargeurImg, BmpFileInfo.HauteurImg)

        'Lecture de l'image
        StreamBmpRead.Position = BmpFileInfo.OffSetImg  'On commence où commence l'image

        'Indique si on doit ajouter des octets pour avoir un multiple de 4
        Dim NbAddOctet As Integer = 0
        Dim BitEnTrop As Integer = 0

        'On prépare en fonction de la profondeur de l'image
        Dim Mode24 As Byte = CByte(IIf(BmpFileInfo.NbDeBitParPixel = 24, 3, 1))
        Dim NbOctetBuffer As Integer
        Select Case BmpFileInfo.NbDeBitParPixel
            Case 24
                NbOctetBuffer = 3 * BmpFileInfo.LargeurImg
            Case 8
                NbOctetBuffer = BmpFileInfo.LargeurImg
            Case 4
                If Int(BmpFileInfo.LargeurImg / 2) < (BmpFileInfo.LargeurImg / 2) Then NbOctetBuffer = CInt(Int(BmpFileInfo.LargeurImg / 2) + 1) Else NbOctetBuffer = CInt(Int(BmpFileInfo.LargeurImg / 2))
                If (BmpFileInfo.LargeurImg / 4) > (Int(BmpFileInfo.LargeurImg / 4)) Then BitEnTrop = 4
            Case 1
                If Int(BmpFileInfo.LargeurImg / 8) < (BmpFileInfo.LargeurImg / 8) Then NbOctetBuffer = CInt(Int(BmpFileInfo.LargeurImg / 8) + 1) Else NbOctetBuffer = CInt(BmpFileInfo.LargeurImg / 8)
                BitEnTrop = (NbOctetBuffer * 8 - BmpFileInfo.LargeurImg)
            Case Else
                NbOctetBuffer = 1
        End Select
        If (NbOctetBuffer / 4) > (Int(NbOctetBuffer / 4)) Then NbAddOctet = CInt(Int(NbOctetBuffer / 4) + 1) * 4 - NbOctetBuffer


        Dim X, Y As Integer 'Position du Pixel a afficher
        X = 0 'On commence à gauche
        Y = (BmpFileInfo.HauteurImg - 1) 'On commence en bas de l'image pour l'image (le bas de l'image est stocké en haut)

        ReDim TblBytes(NbOctetBuffer - 1) 'Buffer en fonction de la largeur

        Dim ValMaxRead As Integer 'Variable indiquant le nombre d'octets lu

        Do While StreamBmpRead.Position < StreamBmpRead.Length 'Boucle tant qu'on est pas à la fin du fichier

            FrmMain.Text = CStr(CInt(StreamBmpRead.Position / StreamBmpRead.Length * 100)) & "% chargé" 'Indiquation utilisateur

            ValMaxRead = StreamBmpRead.Read(TblBytes, 0, NbOctetBuffer)

            For I As Integer = 0 To CInt((ValMaxRead / Mode24 - 1)) 'Selon la profondeur et le Buffer
                Select Case BmpFileInfo.NbDeBitParPixel
                    Case 24 'RGB codé sous 3 octets, pour un mode 32bit il faut rajouter Alpha (je n'ai pas codé ce mode car il est peu présent il faut juste prendre en compte un octet de plus)

                        Image.SetPixel(X, Y, Color.FromArgb(TblBytes(2 + (3 * I)), TblBytes(1 + (3 * I)), TblBytes(0 + (3 * I)))) 'On affiche le pixel (ARGB où A = 255) 
                        PixelSuivant(X, Y)
                    Case 8 'Image en 256 couleurs, 1 octet = Index de couleur dans la palette

                        Image.SetPixel(X, Y, Color.FromArgb(TblPalette(TblBytes(I) * 4 + 2), TblPalette(TblBytes(I) * 4 + 1), TblPalette(TblBytes(I) * 4)))
                        PixelSuivant(X, Y)
                    Case 4 ' Ouvre une image en 16 couleurs : chaque octet contient 2 pixels donc codé sous 4 bit, puis trouvé l'index dans la palette pour savoir la couleur

                        Dim Octet1, Octet2 As Byte
                        Octet2 = TblBytes(I) And CByte(15)
                        Octet1 = TblBytes(I) And CByte(240) : Octet1 >>= 4
                        Image.SetPixel(X, Y, Color.FromArgb(TblPalette(Octet1 * 4 + 2), TblPalette(Octet1 * 4 + 1), TblPalette(Octet1 * 4)))
                        PixelSuivant(X, Y)
                        If Not (BitEnTrop = 4 And X = 0 And Octet2 = 0) Then
                            Image.SetPixel(X, Y, Color.FromArgb(TblPalette(Octet2 * 4 + 2), TblPalette(Octet2 * 4 + 1), TblPalette(Octet2 * 4)))
                            PixelSuivant(X, Y)
                        End If
                    Case 1 'Ouvre une image en N&B : il faut traduire chaque octet en huit octets de valeurs 1 ou 0

                        Dim Octet As Byte
                        Dim ByteOperation As Byte = 128
                        If I <> (TblBytes.Length - 1) Then
                            For K As Integer = 0 To 7
                                Octet = TblBytes(I) And ByteOperation
                                Octet >>= (7 - K)
                                ByteOperation >>= 1
                                Image.SetPixel(X, Y, Color.FromArgb(TblPalette(Octet * 4 + 2), TblPalette(Octet * 4 + 1), TblPalette(Octet * 4)))
                                PixelSuivant(X, Y)
                            Next
                        Else
                            For K As Integer = 0 To (7 - BitEnTrop)
                                Octet = TblBytes(I) And ByteOperation
                                Octet >>= (7 - K)
                                ByteOperation >>= 1
                                Image.SetPixel(X, Y, Color.FromArgb(TblPalette(Octet * 4 + 2), TblPalette(Octet * 4 + 1), TblPalette(Octet * 4)))
                                PixelSuivant(X, Y)
                            Next
                        End If
                End Select
            Next I

            If NbAddOctet > 0 Then StreamBmpRead.Read(TblBytes, 0, NbAddOctet)
            Application.DoEvents() 'Pour laisser l'application afficher le texte

        Loop

        'Fermer le stream
        StreamBmpRead.Close()

        'Remet le titre d'origine
        FrmMain.Text = "Ouverture d'images en natif"

        'Affiche l'image
        FrmMain.PbPicture.Image = Image

        'Libérer les ressources
        Image = Nothing
        TblBytes = Nothing
        TblPalette = Nothing

        'Affichage du texte de la structure de l'image
        FrmMain.TxtInfo.Text = "Headers >> " & vbCrLf & "Compression utilisée : " & BmpFileInfo.Compression & vbCrLf & _
        "Hauteur de l'image en pixel : " & BmpFileInfo.HauteurImg & vbCrLf & _
    "Largeur de l'image en pixel : " & BmpFileInfo.LargeurImg & vbCrLf & _
    "Nombre de couleurs importantes : " & BmpFileInfo.NbCouleurImportantes & vbCrLf & _
        "Nombre de couleurs de la palette : " & BmpFileInfo.NbCouleurPalette & vbCrLf & _
 "Profondeur de l'image (en bits) : " & BmpFileInfo.NbDeBitParPixel & vbCrLf & _
  "Offset du début des données de l'image : " & BmpFileInfo.OffSetImg & vbCrLf & _
   "Résolution horizontale : " & BmpFileInfo.ResolutionHorizontale & vbCrLf & _
    "Résolution verticale : " & BmpFileInfo.ResolutionVerticale & vbCrLf & _
 "Taille de l'image (approx en octets) : " & BmpFileInfo.TailleDeLImage & vbCrLf & _
 "Taille de l'image avec remplissage (approx en octets) : " & BmpFileInfo.TailleDeLImageAcRemplissage

    End Sub
    Private Sub PixelSuivant(ByRef X As Integer, ByRef Y As Integer)
        X += 1
        If X > (BmpFileInfo.LargeurImg - 1) Then 'Si on atteint la fin de la ligne
            X = 0
            Y -= 1
        End If
    End Sub

    Private Function BytesToInt(ByVal TblBytes() As Byte, ByVal Len As Integer) As Integer
        'Comme son nom l'indique cette fonction transforme un tableau de bytes en Integer, il sagit d'une copie mémoire.
        Dim Number As Integer
        Dim MyGC As GCHandle = GCHandle.Alloc(Number, GCHandleType.Pinned)
        Dim AddofLongValue As IntPtr = MyGC.AddrOfPinnedObject()
        Marshal.Copy(TblBytes, 0, AddofLongValue, Len)
        Number = Marshal.ReadInt32(AddofLongValue)
        MyGC.Free()
        Return Number
    End Function
End Module

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Historique

17 février 2007 15:10:42 :
Permet de se déplacer dans l'image si celle-ci est plus grande que le contrôle.
17 février 2007 18:27:16 :
Correction de la correction ;)

Commentaires et avis

signaler à un administrateur
Commentaire de yvesyves le 17/02/2007 14:45:32

Si l'ouverture d'un fichier pose problème c'est qu'il n'est pas pris en charge (compression, méthodes spéciales, BitPerPixel non reconnu, etc).

signaler à un administrateur
Commentaire de yvesyves le 17/02/2007 15:00:15

Je vois qu'en compilant ma source j'atteint uen vitesse 200 fois plus élevée. (J'ai ouvert une photo de 6 millions de pixels en 3 Sec). Puisque c'est comme ca, je vais faire une Maj qui n'a rien avoir au but de la source pour qu'on puisse se déplacer dans l'image afin de la voir entierement.

signaler à un administrateur
Commentaire de yvesyves le 17/02/2007 15:11:03

Maj faite

signaler à un administrateur
Commentaire de EBArtSoft le 17/02/2007 19:12:53 administrateur CS

Quelle galere le vb.net pour lire une structure. Remarque celle ci tu aurais pu la lire en une seul ligne de code.

@+

signaler à un administrateur
Commentaire de yvesyves le 17/02/2007 19:21:20

Oui, j'aurais pu lire la structure d'un coup. Mais je préfere piocher les données une par une, c'est plus long mais plus clair (pour moi en tout cas ;))

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Comment attribué une image à un bouton ? [ par loic38760 ] je veux que quand je clique sur le boutton "Command" par exemple l'image "Bitmap.bmp" s'affiche dans le bouton.j'ai essay&#233; : command.picture = "B Image dans RichTextBox [ par scottmat ] Bonjours &#224; tous, dans un richtextbox j&#146;ins&#232;re une image &#224; l&#146;aide du code suivant&nbsp;: &nbsp;<?xml:nam Enregistrer une image contenu dans le presse-papier en BMP [ par tonymitchelli ] Bonjour &#224; tous et merci d'avance &#224; ceux qui auront la gentillesse de me r&#233;pondre,Quelqu'un pourrait-il m'aider SVP, voil&#224; ce que j effacer tout les pixels qui ne sont pas de la couleur "x" dans une image bmp????????? [ par zwarul ] bon voila je cherche une fonction, ou un code, qui me permette de ne conserver dans une image que les pixels qui sont d'une couleur pr&#233;cise (dans Y a t-il un equivalent de picturebox.pset (x,y),vbblack sur un compatible bitmap ? [ par hcadieu ] Salut a tousJe dessine&nbsp;des points &nbsp;noirs sur une picturebox&nbsp; avec un fond blanc puis pour un traitement s&#233;par&#233; j'aurais besoi Inserer une image dans un bitmap [ par malhivertman1 ] Bonjour, J'aimerai pouvoir récupérer une image de mon disque et la mettre dans une variable de type bitmap pour ensuite pouvoir dessiner dessus en uti Afficher des bitmaps [ par luna4 ] Salut,j'ai eu beau chercher sur le site, j'ai pas trouvé de réponses à mon problème.Alors voila, (en vb net) je voudrais afficher sucessivement des im conversion DataGridViewIMAGE en BMP (vb2005) [ par vercomax ] bonjour,j'ai beau chercher je ne retrouve plus le code qui permet de transformer une image stokée dans une DataGridViewColumImage en fichier BMP.cette décodage image bitmap [ par arnovb ] bonjour je cherche un programme en visual basic qui me permettrait de dire si une zone d'une image bitmap est blanche ou pas quelqu'un peut il m'aider PictureBox et *.bmp [ par dheroux ] Bonjour,Dans un PictureBox j'ai affiché un code-barre qui a été calculé et dessiné ( et non chargé à partir d'une image)Je voudrais que ce PictureBox


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,655 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.