Visualizzazione dei risultati da 1 a 2 su 2
  1. #1

    estrarre profili da una bitmap - VBA

    Salve a tutti. Ho questo problema: devo estrarre una matrice dei dati relativi ai livelli di colore di immagini di tipo bitmap al fine di effettuare su questi analisi successive. Ho preparato le macro per l'estrazione dati da matrice e per l'analisi degli stessi perchè ho esperienza di programmazione Fortran. Purtroppo, sulla gestione delle immagini e sul VBA sono neofita. Dopo aver studiato il problema (Loadimage con LR-CreateDIBSection+GetObject dal DIBSection) anche su questo sito ed altrove, senza riuscire, ho trovato il cosice allegato che funziona ma non riesce a gestire le mie immagini BMP che hanno più di 100 livelli di grigio: qualcuno può aiutarmi?
    Grazie
    Gaetano



    codice:
    Option Explicit
    '###################################################################
    ' Full Credit to Gary Simmons for this BMP loader code
    ' Demonstration/tutorial of reading and manually drawing an
    ' uncompressed (most) bitmap Free for any use:
    ' see included file (BMP.TXT) for Bitmap file info reference.
    '
    ' Please email me at gary.simmons@optushome.com.au if you find this
    ' useful
    '
    ' 21st December 2001 Gary Simmons
    '###################################################################
    Private Type BitMapFile  'bitmap file header structure
        bfType As String * 2
        bfSize As String * 4
        bfReserved1 As String * 2
        bfreserved2 As String * 2
        bfOffset As String * 4
    End Type
    Private Type BitMapInfo  'bitmap info header structure
        biSize As String * 4
        biWidth As String * 4
        biHeight As String * 4
        biPlanes As String * 2
        biBitCount As String * 2
        biCompression As String * 4
        biSizeImage As String * 4
        biXPelsPerMeter As String * 4
        biYPelsPerMeter As String * 4
        biClrUsed As String * 4
        biClrImportant As String * 4
    End Type
    Private Type RGBQuads  'RGBQuad structure (temporary)
        cBlue As String * 1
        cGreen As String * 1
        cRed As String * 1
        cReserved As String * 1
    End Type
    Private Type RGBQuad  'RGBQuad (used in index)
        Blue As Byte
        Green As Byte
        Red As Byte
    End Type
    
    Public Sub GetBmpValues(Filename As String, BMPData() As Long, Progress As MSForms.Label)
    ' show information about the bitmap and
    ' manually draw it in another Picturebox
        Dim bmf As BitMapFile
        Dim bmi As BitMapInfo
        Dim rgbqs As RGBQuads
        Dim rgbq(255) As RGBQuad
        Dim s1 As String * 1
        Dim Dword As String * 4
        Dim lngCol As Long
        Dim lngRow As Long
        Dim IWidth As Long
        Dim IBitCount As Integer
        Dim Pointer As Long
        Dim i As Integer
        Dim ClrInd As Integer
        Dim aMask As Long
        Dim z As Integer
        Dim ByteNum As Integer
        Dim ThisByte As Byte
        Dim ColoursFound As Integer
        Dim ThisRed As Byte
        Dim ThisGreen As Byte
        Dim ThisBlue As Byte
        Const MAX_WIDTH = 256
        Const MAX_HEIGHT = 65536
        
        Progress.Caption = "Reading BMP " & Filename
        DoEvents
        Open Filename For Binary As #1
        Get #1, , bmf           'load the file header
        Get #1, , bmi           'info header follows
        If lVal(bmi.biSize) <> 40 Or bmf.bfType <> "BM" Then
            MsgBox "Not a compatible bitmap."
            Close #1
            Exit Sub
        End If
        
        'load the relevant colour tables
        If lVal(bmi.biBitCount) = 1 Then
            For i = 0 To 1
                Get #1, , rgbqs
                rgbq(i).Red = lVal(rgbqs.cRed)
                rgbq(i).Green = lVal(rgbqs.cGreen)
                rgbq(i).Blue = lVal(rgbqs.cBlue)
            Next i
        ElseIf lVal(bmi.biBitCount) = 4 Then
            For i = 0 To 15
                Get #1, , rgbqs
                rgbq(i).Red = lVal(rgbqs.cRed)
                rgbq(i).Green = lVal(rgbqs.cGreen)
                rgbq(i).Blue = lVal(rgbqs.cBlue)
            Next i
        ElseIf lVal(bmi.biBitCount) = 8 Then
            For i = 0 To 255
            Get #1, , rgbqs
                rgbq(i).Red = lVal(rgbqs.cRed)
                rgbq(i).Green = lVal(rgbqs.cGreen)
                rgbq(i).Blue = lVal(rgbqs.cBlue)
            Next i
        End If
        
        ' show the properties of the bitmap
        ' some don't seem to be used
        
    '    MsgBox "Actual File Size:" & (Str(LOF(1))) & " bytes" & vbCrLf & _
    '        "Bitmap File Size: " & lVal(bmf.bfSize) & " bytes" & vbCrLf & _
    '        "Bitmap Width: " & lVal(bmi.biWidth) & " pixels" & vbCrLf & _
    '        "Bitmap Height: " & lVal(bmi.biHeight) & " pixels" & vbCrLf & _
    '        "Bitmap Offset: " & lVal(bmf.bfOffset) & vbCrLf & _
    '        "Bitmap BitPlanes: " & lVal(bmi.biPlanes) & vbCrLf & _
    '        "Bitmap BitCount: " & lVal(bmi.biBitCount) & " bit/pixel" & vbCrLf & _
    '        "Bitmap Size: " & lVal(bmi.biSizeImage) & " bytes" & vbCrLf & _
    '        "Bitmap ClrUsed: " & lVal(bmi.biClrUsed) & vbCrLf & _
    '        "Bitmap ClrsImportant: " & lVal(bmi.biClrImportant) & vbCrLf & _
    '        "Bitmap Compression: " & lVal(bmi.biCompression)
            
        If lVal(bmi.biCompression) <> 0 Then
            MsgBox "Its a compressed bitmap."
            Close #1
            Exit Sub
        End If
        
        Close #1
        
        If lVal(bmi.biBitCount) <= 8 Then
            ' the file is either:
            '         mono (1-bit/pixel)
            '         16-color (4-bit/pixel)
            '         256-color (8-bit/pixel)
            
            Open Filename For Binary As #1
            lngCol = 0                        'holds X position of pixel to draw
            lngRow = lVal(bmi.biHeight) '- 1   'holds Y position (Note: bitmap stored from lowest line to highest)
            IWidth = lVal(bmi.biWidth)      'width of bitmap
            ReDim BMPData(lngRow, IWidth) As Long
            
            IBitCount = lVal(bmi.biBitCount) ' bits/pixel (1,4,8)
            Get #1, lVal(bmf.bfOffset), s1  'move binary pointer to start of bitmap
            Do While Not EOF(1)
                Get #1, , Dword   ' read 4-bytes at a time
                ByteNum = 1       ' start with first byte in double word
                Do While lngCol < IWidth And ByteNum < 5  'stop drawing if edge of bitmap encountered or processed every byte in dword
                    ThisByte = lVal(Mid(Dword, ByteNum, 1)) 'get relevant byte
                    Pointer = 8   ' start bit pointer
                    Do
                        If lngCol < IWidth Then 'only bother if edge of bitmap not reached
                            aMask = 0         'reset bit-mask
                            For z = Pointer To Pointer - IBitCount + 1 Step -1 'the best algorithm
                                aMask = aMask + 2 ^ (z - 1)                    'I could come up with to build a bit-mask
                            Next z
                            ClrInd = (ThisByte And (aMask)) / (2 ^ (Pointer - IBitCount)) ' mask of relevant bits and reduce to an appropriate index
                            BMPData(lngRow, lngCol + 1) = RGB(rgbq(ClrInd).Red, rgbq(ClrInd).Green, rgbq(ClrInd).Blue) 'set the pixel the colour
                        End If
                        Pointer = Pointer - IBitCount  'move to the next appropriate bits
                        lngCol = lngCol + 1    'move the X-position
                    Loop Until Pointer = 0 'not more bits to process - exit
                    ByteNum = ByteNum + 1  'point to the next byte in the dword
                Loop
                If lngCol >= IWidth Then     'if, after processing this dword, we have
                    Progress.Caption = "Lines remaining " & lngRow
                    DoEvents
                    lngRow = lngRow - 1      'reached the end of a line then
                    If lngRow = 0 Then Exit Do
                    lngCol = 0               'get the next line and reset the X-position
                End If
            Loop
            Close #1
        ElseIf lVal(bmi.biBitCount) = 24 Then
        ' 16Million-color (24-bit/pixel)
            Open Filename For Binary As #1
            lngCol = 0
            lngRow = lVal(bmi.biHeight) ' - 1
            IWidth = lVal(bmi.biWidth)
            ReDim BMPData(lngRow, IWidth) As Long
            IBitCount = lVal(bmi.biBitCount)
            Get #1, lVal(bmf.bfOffset), s1
            ColoursFound = 0         'need 3-colours to form a pixel
            Do While Not EOF(1)
                Get #1, , Dword      'get 4-bytes
                ByteNum = 1
                Do While lngCol < IWidth And ByteNum < 5
                    ThisByte = lVal(Mid(Dword, ByteNum, 1))
                    If lngCol < IWidth Then
                        ColoursFound = ColoursFound + 1
                        Select Case ColoursFound
                        Case Is = 1  'first byte in three is blue (contradicts BMP.TXT)
                            ThisBlue = ThisByte
                        Case Is = 2  'second byte is green
                            ThisGreen = ThisByte
                        Case Is = 3  'third byte is red
                            ThisRed = ThisByte
                            'got the colours we need
                            'draw the pixel and move on to next pixel
                            BMPData(lngRow, lngCol + 1) = RGB(ThisRed, ThisGreen, ThisBlue)
                            ColoursFound = 0
                            lngCol = lngCol + 1
                        End Select
                    End If
                    ByteNum = ByteNum + 1
                Loop
                If lngCol >= IWidth Then
                    Progress.Caption = "Lines remaining " & lngRow
                    DoEvents
                    lngRow = lngRow - 1
                    If lngRow = 0 Then Exit Do
                    lngCol = 0
                End If
            Loop
            Close #1
        End If
    
    End Sub
    Function lVal(vStr As String) As Long
        'convert little-endian string to long integer
    
        Dim i As Integer
        Dim t As Long
        t = 0
        For i = 1 To Len(vStr)
            t = t + Asc(Mid(vStr, i, 1)) * (256 ^ (i - 1))
        Next i
        lVal = t
    End Function
    
    Sub BMPToChart()
        frmBMPLoader.Show
        Unload frmBMPLoader
    End Sub

  2. #2

    evoluzione...

    ho cambiato i limiti da 56 e 128 a 256 e 512 per i colori e funziona. Purtroppo, però, le mie immagini sono enormi (1024x1024) e non posso ridimensionarle per cui credo che excel non sia in grado di gestire il problema se non con le funzioni Loadimage con LR_CreateDIBSection e GetOBject...qualcuno può aiutarmi???

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.