Accueil > > > OUVERTURE D'UN FICHIER BITMAP EN NATIF
OUVERTURE D'UN FICHIER BITMAP EN NATIF
Information sur la source
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
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
Sources de la même categorie
Commentaires et avis
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é : command.picture = "B
Image dans RichTextBox [ par scottmat ]
Bonjours à tous, dans un richtextbox j’insère une image à l’aide du code suivant : <?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
|
Derniers Blogs
[FRAMEWORK 4] LES TASKS ET LE THREAD UI[FRAMEWORK 4] LES TASKS ET LE THREAD UI par fathi
Je viens de passer quelques temps au TechDay's et j'ai pu voir pas mal de session intéressante. Par contre une chose m'a un peu étonné lors de certaines de ces sessions qui abordaient les améliorations du framework .NET (donc le 4.5) : en gros, bea...
Cliquez pour lire la suite de l'article par fathi WORKFLOW FOUNDATION 3 A UN PIED DANS LA TOMBEWORKFLOW FOUNDATION 3 A UN PIED DANS LA TOMBE par JeremyJeanson
Depuis déjà un an, je conseille vivement les utilisateurs de Workflow Foundation 3 à migrer vers la version 4. L'information qui va suivre ne devrait donc pas trop prendre au dépourvu les personnes qui m'ont suivi. Je profite de ce poste, pour faire le re...
Cliquez pour lire la suite de l'article par JeremyJeanson TECHDAYS PARIS 2012 : NOUVELLES TENDANCES DU POSTE DE TRAVAIL - BRING YOUR OWN PCTECHDAYS PARIS 2012 : NOUVELLES TENDANCES DU POSTE DE TRAVAIL - BRING YOUR OWN PC par ROMELARD Fabrice
Speakers: Thierry Rapatout, Antoine Petit et Xavier Trebbia Cette session entre dans le cadre des RDV Décideurs des TechDays 2012, elle est liée à la consumérisation de l'IT et la mise en place du "DeskTop as a Service" dans de plus en ...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice TECHDAYS PARIS 2012 : SYSTEM CENTER SERVICE MANAGER 2012 VUE D'ENSEMBLETECHDAYS PARIS 2012 : SYSTEM CENTER SERVICE MANAGER 2012 VUE D'ENSEMBLE par ROMELARD Fabrice
Speakers: Julien Marechal, Gautier Confiant, Sébastien MEYER La session débute par le positionnement de la solution System Center par rapport aux concepts d'organisation ITIL. Le portail du catalogue de se...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice TECHDAYS PARIS 2012 : PLEINIèRE SECOND JOURTECHDAYS PARIS 2012 : PLEINIèRE SECOND JOUR par ROMELARD Fabrice
Après une première journée dédiée aux développeurs, cette seconde journée est dédiée au monde des entreprises et de ses applications. Ainsi, cette pleinière est dédiée à faire un 360 de l'évolution des applications Business aux demandes ac...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice
Forum
VB6 + GRAPHVIZVB6 + GRAPHVIZ par nouirayosra
Cliquez pour lire la suite par nouirayosra
Logiciels
Academy System (17.2.1.0)ACADEMY SYSTEM (17.2.1.0)Logiciel de gestion des établissements.
- élèves/étudiants (inscription, dossier, absence...)
-... Cliquez pour télécharger Academy System Easy-Planning (1.0.0.1)EASY-PLANNING (1.0.0.1)Basé sur les mêmes principes que MyPlanning, Easy-Planning permet de créer des plannings sous la ... Cliquez pour télécharger Easy-Planning COLLECTOR PLUS (3.00B)COLLECTOR PLUS (3.00B)COLLECTOR PLUS version 3.00B est un logiciel utilisant une base de données alimentée par :
- L... Cliquez pour télécharger COLLECTOR PLUS PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA TV DEVIENS HELLLOOO FLASH
LA TV SUR VOTRE ORDINATEUR.
Toute une plateforme Multi... Cliquez pour télécharger PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO LettresFaciles 2011 (8.0.0.1)LETTRESFACILES 2011 (8.0.0.1)LettresFaciles est un logiciel facilitant la création et la rédaction de lettres types.
Son inte... Cliquez pour télécharger LettresFaciles 2011
|