Finding the Dimensions of a Graphic (.bmp, .gif, .png, .jpg)

by - JanetTerra JanetTerra

The four common graphic types are Bitmap (.bmp), Graphics Interchange Format (.gif), Portable Network Graphics (.png), and Joint Photography Experts Group (.jpg). File formats are very specific for each. After identifying the file, it is possible to open that graphics file as a sequential file and extract the width and height (in pixels) of that file.

The Bitmap (.bmp) File

The structure of the bitmap file has been well documented in Liberty BASIC Newsletter Issue #100 and a basic wikispaces Tip. All bitmap files, whether 16, 24, 32, or 256 bitmap format, store the width and height information at bytes 19, 20 and 23, 24.
    Filedialog "Open Bitmap","*.bmp", picFile$
 
    Open picFile$ for Input as #pic
        pic$=Input$(#pic, LOF(#pic))
    Close #pic
 
    picWidth = Asc(Mid$(pic$, 19, 1)) + (Asc(Mid$(pic$, 20, 1)) * 256)
    picHeight = Asc(Mid$(pic$, 23, 1)) + (Asc(Mid$(pic$, 24, 1)) * 256)
 
    Print "Bitmap width is ";picWidth
    Print "Bitmap height is ";picHeight
End

The Graphics Interface Format (.gif) File

The dimensions of a .gif file are found the same way bitmap dimensions are found. Dimensions of the .gif file are found in bytes 7, 8 and 9, 10. The structure of the .gif file is explained more fully in Viewing Animated GIF Files.
   Filedialog "Open GIF","*.gif", picFile$
 
    Open picFile$ for Input as #pic
        pic$=Input$(#pic, LOF(#pic))
    Close #pic
 
    picWidth = Asc(Mid$(pic$, 7, 1)) + (Asc(Mid$(pic$, 8, 1)) * 256)
    picHeight = Asc(Mid$(pic$, 9, 1)) + (Asc(Mid$(pic$, 10, 1)) * 256)
 
    Print "GIF width is ";picWidth
    Print "GIF height is ";picHeight
End

The Portable Network Graphics (.png) File

PNG information is stored in chunks. Each chunk is identified by a specific (IHDR) header. To find the dimensions of a .png file, the first IHDR marker must be found. The width and height values are stored in the 7, 8 and 11, 12 bytes following the first chunk beginning with IHDR.
    Filedialog "Open PNG","*.png", picFile$
 
    Open picFile$ for Input as #pic
        pngInfo$=Input$(#pic, LOF(#pic))
    Close #pic
 
    IHDRpos = Instr(pngInfo$, "IHDR")
 
    picWidth = Asc(Mid$(pngInfo$, IHDRpos + 7, 1)) + (Asc(Mid$(pngInfo$, IHDRpos + 6, 1)) * 256)
    picHeight = Asc(Mid$(pngInfo$, IHDRpos + 11, 1)) + (Asc(Mid$(pngInfo$, IHDRpos + 10, 1)) * 256)
 
    Print "PNG width is ";picWidth,
    Print "PNG height is ";picHeight
End

The Joint Photography Experts Group (.jpg, .jpeg) File

As with the .png file, finding the dimensions of a .jpeg file also requires finding a marker. The .jpeg marker is FFC0. Unlike the .png file, though, where only the first marker must be found, the entire .jpeg file must be searched until the last FFC0 marker is found. The width and height information is found in the 5, 6 and 7, 8 bytes following that last FFC0 marker.
    Filedialog "Open JPEG","*.jpg;*.jpeg", picFile$
    Open picFile$ for Input as #pic
        jpgInfo$=Input$(#pic, LOF(#pic))
    Close #pic
 
    FFC0$ = Chr$(255);Chr$(192)
    FFC0pos = 1
    While FFC0pos > 0
        FFC0pos = Instr(jpgInfo$, FFC0$)
            If Asc(Mid$(jpgInfo$, FFC0pos, 1)) = 255 Then
                If Asc(Mid$(jpgInfo$, FFC0pos + 1, 1)) = 192 Then
                        jpgInfo$ = Mid$(jpgInfo$, FFC0pos + 2)
                End If
            End If
    Wend
 
    picWidth = Asc(Mid$(jpgInfo$, FFC0pos + 7, 1)) + (Asc(Mid$(jpgInfo$, FFC0pos + 6, 1)) * 256)
    picHeight = Asc(Mid$(jpgInfo$, FFC0pos + 5, 1)) + (Asc(Mid$(jpgInfo$, FFC0pos + 4, 1)) * 256)
 
    Print "JPG width is ";picWidth,
    Print "JPG height is ";picHeight
End

Finding the File Format

The file extension (e.g., .bmp, .gif, .png, .jpg, .jpeg) usually identifies the file. The file format can also be found within the file information. Bitmaps contain BM in the first 2 bytes, GIF files contain GIF in the first 3 bytes, PNG files contain PNG in the 2nd, 3rd, and 4th bytes, and JPEG files contain JFIF in the 7th, 8th, 9th, and 10th files. Open the file as a sequential file to identify the file format.
    Filedialog "Open Graphic File","*.*", picFile$
    Open picFile$ for Input as #pic
        pic$=Input$(#pic, LOF(#pic))
    Close #pic
    ID$ = Left$(pic$, 10)
    Select Case
        Case Left$(pic$, 2) = "BM"
            graphicFormat$ = "BMP"
        Case Left$(pic$, 3) = "GIF"
            graphicFormat$ = "GIF"
        Case Mid$(pic$, 2, 3) = "PNG"
            graphicFormat$ = "PNG"
        Case Mid$(pic$, 7, 4) = "JFIF"
            graphicFormat$ = "JPEG"
        Case Else
            graphicFormat$ = "Unknown"
    End Select
 
 
    Print "Graphic Format = ";graphicFormat$
End

A Function to Obtain the Dimensions of a Graphic

Combining the separate format string parsings into one function makes an easy snippet to obtain the dimensions of any of the four common graphic formats.
 
 
    Filedialog, "Open Graphic File", "*.bmp;*.gif;*.png;*.jpg;*.jpeg", picFile$
    graphicFormat$ = GraphicFormat$(picFile$)
 
    Print "GraphicFormat = ";graphicFormat$;"."
    If graphicFormat$ = "Unknown" Then
        Print "Unable to continue."
        End
    End If
 
    graphicDimen$ =GraphicDimensions$(picFile$, graphicFormat$)
    graphicWidth = Val(Word$(graphicDimen$, 1, "|"))
    graphicHeight = Val(Word$(graphicDimen$, 2, "|"))
 
    Print "Graphic Width = ";graphicWidth
    Print "Graphic Height = ";graphicHeight
End
 
Function GraphicDimensions$(picFile$, graphicFormat$)
    Open picFile$ for Input as #pic
        pic$ = Input$(#pic, LOF(#pic))
    Close #pic
    Select Case graphicFormat$
        Case "BMP"
            picWidth = Asc(Mid$(pic$, 19, 1)) + (Asc(Mid$(pic$, 20, 1)) * 256)
            picHeight = Asc(Mid$(pic$, 23, 1)) + (Asc(Mid$(pic$, 24, 1)) * 256)
        Case "GIF"
            picWidth = Asc(Mid$(pic$, 7, 1)) + (Asc(Mid$(pic$, 8, 1)) * 256)
            picHeight = Asc(Mid$(pic$, 9, 1)) + (Asc(Mid$(pic$, 10, 1)) * 256)
        Case "PNG"
            IHDRpos = Instr(pic$, "IHDR")
            picWidth = Asc(Mid$(pic$, IHDRpos + 7, 1)) + (Asc(Mid$(pic$, IHDRpos + 6, 1)) * 256)
            picHeight = Asc(Mid$(pic$, IHDRpos + 11, 1)) + (Asc(Mid$(pic$, IHDRpos + 10, 1)) * 256)
        Case "JPEG"
            FFC0$ = Chr$(255);Chr$(192)
            FFC0pos = 1
            While FFC0pos > 0
                FFC0pos = Instr(pic$, FFC0$)
                If Asc(Mid$(pic$, FFC0pos, 1)) = 255 Then
                    If Asc(Mid$(pic$, FFC0pos + 1, 1)) = 192 Then
                        pic$ = Mid$(pic$, FFC0pos + 2)
                    End If
                End If
            Wend
            picWidth = Asc(Mid$(pic$, FFC0pos + 7, 1)) + (Asc(Mid$(pic$, FFC0pos + 6, 1)) * 256)
            picHeight = Asc(Mid$(pic$, FFC0pos + 5, 1)) + (Asc(Mid$(pic$, FFC0pos + 4, 1)) * 256)
        Case Else
            picWidth = 0
            picHeight = 0
    End Select
    GraphicDimensions$ = Str$(picWidth);"|";Str$(picHeight)
End Function
 
Function GraphicFormat$(picFile$)
    Open picFile$ for Input as #pic
        pic$=Input$(#pic, LOF(#pic))
    Close #pic
    ID$ = Left$(pic$, 10)
    Select Case
        Case Left$(pic$, 2) = "BM"
            GraphicFormat$ = "BMP"
        Case Left$(pic$, 3) = "GIF"
            GraphicFormat$ = "GIF"
        Case Mid$(pic$, 2, 3) = "PNG"
            GraphicFormat$ = "PNG"
        Case Mid$(pic$, 7, 4) = "JFIF"
            GraphicFormat$ = "JPEG"
        Case Else
            GraphicFormat$ = "Unknown"
    End Select
End Function