Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1449

[VB6] GDI+ Workaround: JPG > Zero-Length APP Markers

$
0
0
Note: Tests of successful loading of the image without applying the workaround have been done on various O/S. This patch may not be required on Win7 and above

You probably know that GDI+ is useful for loading various image formats, but GDI+ also has issues with every format it loads. For JPGs specifically, if certain APP markers within the file have zero length data then one of two things can happen: 1) image won't load or 2) image loads, but the size reported by GDI+ is 0x0

The attached txt file is a VB class. After you save it to disk, rename it to .cls
I've also included a JPG with a zero-length APP marker.

So, to play.
1) Download the txt file & rename it .cls
2) Create a new project and add that class to your project
3) On the form, add a commandbutton
4) Paste this code to your form & run project
5) Drag/drop a JPG onto the form
Code:

Option Explicit

Private Declare Function GdipDeleteGraphics Lib "GdiPlus.dll" (ByVal mGraphics As Long) As Long
Private Declare Function GdipDrawImageRectRectI Lib "GdiPlus.dll" (ByVal hGraphics As Long, ByVal hImage As Long, ByVal dstX As Long, ByVal dstY As Long, ByVal dstWidth As Long, ByVal dstHeight As Long, ByVal srcX As Long, ByVal srcY As Long, ByVal srcWidth As Long, ByVal srcHeight As Long, ByVal srcUnit As Long, ByVal imageAttributes As Long, ByVal Callback As Long, ByVal callbackData As Long) As Long
Private Declare Function GdipCreateFromHDC Lib "GdiPlus.dll" (ByVal hDC As Long, hGraphics As Long) As Long
Private Declare Sub GdiplusShutdown Lib "gdiplus" (ByVal Token As Long)
Private Declare Function GdiplusStartup Lib "gdiplus" (Token As Long, inputbuf As Any, Optional ByVal outputbuf As Long = 0) As Long
Private Type GdiplusStartupInput
    GdiplusVersion          As Long
    DebugEventCallback      As Long
    SuppressBackgroundThread As Long
    SuppressExternalCodecs  As Long
End Type

Private m_Token As Long
Private m_JPG As cJPGreader

Private Sub Form_Load()
   
    Call pvCreateToken
    If m_Token = 0 Or m_Token = -1 Then
        Me.Show
        DoEvents
        MsgBox "Failed to start up GDI+", vbExclamation + vbOKOnly
        Unload Me
        Exit Sub
    End If
    Set m_JPG = New cJPGreader
   
    Me.Move (Screen.Width - 10245) \ 2, (Screen.Height - 6585) \ 2, 10245, 6585
    Me.ScaleMode = vbPixels
    Me.Command1.Move 0, 0
    Me.Command1.Caption = "Refresh"
    Me.OLEDropMode = vbOLEDropManual
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Set m_JPG = Nothing
    If Not (m_Token = 0& Or m_Token = -1&) Then pvDestroyToken
End Sub

Private Function pvCreateToken() As Boolean
    Dim GSI As GdiplusStartupInput
    On Error Resume Next
    If Not m_Token = -1 Then
        GSI.GdiplusVersion = 1&
        Call GdiplusStartup(m_Token, GSI)
        If m_Token = 0 Then
            m_Token = -1&
        Else
            pvCreateToken = True
        End If
    End If
End Function

Private Sub pvDestroyToken()
    If Not (m_Token = 0 Or m_Token = -1) Then GdiplusShutdown m_Token
    m_Token = 0&
End Sub

Private Sub Command1_Click()
    Call pvRenderImage
End Sub

Private Sub pvRenderImage()
    If Not m_JPG.Handle = 0& Then
       
        Dim hGraphics As Long, w As Long, h As Long, sngRatio As Single
        Dim x As Long, Y As Long, cx As Long, cy As Long
        Const UnitPixel As Long = 2&
       
        w = m_JPG.Width
        h = m_JPG.Height
        cy = Me.ScaleHeight - Command1.Height
        If Me.ScaleWidth / w > cy / h Then
            sngRatio = cy / h
        Else
            sngRatio = Me.ScaleWidth / w
        End If
        If sngRatio > 1! Then sngRatio = 1&
        cx = w * sngRatio
        cy = h * sngRatio
        x = (Me.ScaleWidth - cx) \ 2
        Y = ((Me.ScaleHeight - Command1.Height) - cy) \ 2 + Command1.Height
       
        Me.Cls
        GdipCreateFromHDC Me.hDC, hGraphics
        GdipDrawImageRectRectI hGraphics, m_JPG.Handle, x, Y, cx, cy, 0, 0, w, h, UnitPixel, 0, 0, 0
        GdipDeleteGraphics hGraphics
    End If

End Sub

Private Sub Form_OLEDragDrop(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, Y As Single)
    If Data.Files.Count Then
        m_JPG.FileName = Data.Files.Item(1)
        Call pvRenderImage
    End If
End Sub

See also:
GDI+ Workaround: TIFF > JPEG-compressed images
GDI+ Workaround: BMP > Alpha Channels + JPG/PNG Encoded
Attached Files

Viewing all articles
Browse latest Browse all 1449

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>