begin process at 2012 02 09 02:06:16
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Graphique

 > OUVERTURE D'UN FICHIER BITMAP EN NATIF

OUVERTURE D'UN FICHIER BITMAP EN NATIF


 Information sur la source

Note :
Aucune note
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é :13 178 / 44 481

Auteur : yvesyves

Ecrire un message privé
Site perso
Ce membre participe au partage de revenus publicitaires
Commentaire sur cette source (6)
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%3FTableNu m%3D12+fichier+bmp+structure&hl=fr&ct=clnk&cd=11&g l=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

Les Membres Club peuvent 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 ;)

 Sources du même auteur

Source avec Zip Source avec une capture Source .NET (Dotnet) SERVEUR HTTP (FICHIERS/WEB) PARTAGEZ VOS FICHIERS
Source avec Zip Source avec une capture Source .NET (Dotnet) TRANSFERT DE FICHIERS ENTRE 2 PC DISTANTS
Source avec Zip Source avec une capture Source .NET (Dotnet) INCLURE POCHETTE D'ALBUM / JAQUETTE DANS VOS TAG MP3 - EDITI...
Source avec Zip Source avec une capture Source .NET (Dotnet) REDIMENSIONNEMENT DE PHOTOS PAR LOT
Source avec Zip Source .NET (Dotnet) CLASSE READ/WRITE BIT À BIT DANS UN FICHIER À N'IMPORTE QUEL...

 Sources de la même categorie

Source avec une capture GRAPH PHP COURBE DE CHARGE par s.defaye
Source avec Zip Source avec une capture BOULE DE CRISTAL par BLUEBIBUBBLE
VB6 - DÉPLACEMENT D'UN CONTRÔLE SUR UN SEGMENT DE DROITE DÉL... par ucfoutu
Source avec Zip Source .NET (Dotnet) APPLICATION DE DESSIN par fsafsafsaf
Source avec Zip Source avec une capture Source .NET (Dotnet) MERGEIMAGES par Le Pivert

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture Source .NET (Dotnet) MERGEIMAGES par Le Pivert
Source avec Zip Source avec une capture Source .NET (Dotnet) DÉCOUPEUR DE SPRITES (POUR JEUX RPG) par guyom38
Source avec Zip Source avec une capture MENU POPUP AVEC IMAGE par zork74
Source .NET (Dotnet) CRÉE UNE IMAGE À PARTIR D'UN GRAPHICS par Charles Racaud
Source avec Zip Source avec une capture BMP2JPG CONVERTIR UNE IMAGE BITMAP EN JPEG AVEC UNE DLL ( CO... par soldier8514

Commentaires et avis

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).

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.

Commentaire de yvesyves le 17/02/2007 15:11:03

Maj faite

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.

@+

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 ;))

Commentaire de tresorsdevie le 25/11/2009 16:23:35

+1
merci pour cette source qui fait comprendre beaucoup de chose, elle va mettre utile pour modifier les bit de poids faible d'une image bmp!

 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 Agir sur une form depuis une fonction [ par mafieulemouton ] Bonjour, je cherche à créer une sub qui changera le curseur en sablier pendant qu'un traitement est effectué. Ici j'ai pris l'exemple d'une conversion Poids d'une image au format BMP 24 bits [ par dheroux ] Bonjour, Une curiosité sous Windows 7 (sauf erreur de ma part) Le poids indiqué d'une image BMP 24 bits semble erroné (pour certaines tout du moins) E [Catégorie modifiée .Net -> VB6] Sauvegarder une image BMP monochrome [ par HGouenard ] Bonjour à tous, Je suis à la recherche d'une méthode "simple" pour sauvegarder une image (créée dans une picturebox) vers un fichier BMP...mais de ty Image -Form [ par DIJONCTER ] bonjours à tous !!!!!J'aimerais changer le backgroundimage d'une Form mais à l'aide de lignes de programme sans passer par les propriétés de la Form.j GDI+ et problèmes divers de débutant [ par mioumiounorris ] Bonjour bonjour ! Je suis actuellement en train d'essayer de comprendre comment dessiner avec GDI+, et j'avoue que j'ai un peu de mal à tout comprendr Probleme de caractere non valide lors de l'enregistrement d'une image [ par niblon ] Bonjour a tous Voila j'ai un textbox (horodate) qui me renvoie la date et l'heure jusque la c'est bon cela fonctionne.Je sauvegarde une image avec l comparaison de 2 images, image actuel Xor Image prcédente [ par kalionehot ] La SaladeBonjour à tous!Actuellement je travail sur un projet et j'ai besoin d'un peu d'aide.Ce projet contient :     - un programme capture ecran réa


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
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

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 6,724 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales