Results 1 to 17 of 17

Thread: [VB6] In memory convert to JPEG using WIC

  1. #1

    Thread Starter
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,192

    [VB6] In memory convert to JPEG using WIC

    This uses Windows Imaging Component to convert a bitmap (a 32-bit DIB) to a JPEG stream purely in memory.

    Paste the following code in a .bas module:

    Code:
    Option Explicit
    
    Private Declare Function SHCreateMemStream Lib "shlwapi" Alias "#12" (pInit As Any, ByVal cbInit As Long) As stdole.IUnknown
    Private Declare Function IStream_Size Lib "shlwapi" (ByVal pStream As stdole.IUnknown, uiSize As Any) As Long
    Private Declare Function IStream_Reset Lib "shlwapi" (ByVal pStream As stdole.IUnknown) As Long
    Private Declare Function IStream_Read Lib "shlwapi" (ByVal pStream As stdole.IUnknown, pvBuf As Any, ByVal cbSize As Long) As Long
    '--- WIC
    Private Declare Function WICCreateImagingFactory_Proxy Lib "windowscodecs" (ByVal SDKVersion As Long, ppIImagingFactory As stdole.IUnknown) As Long
    Private Declare Function IWICImagingFactory_CreateStream_Proxy Lib "windowscodecs" (ByVal pFactory As stdole.IUnknown, ppIWICStream As stdole.IUnknown) As Long
    Private Declare Function IWICImagingFactory_CreateEncoder_Proxy Lib "windowscodecs" (ByVal pFactory As stdole.IUnknown, guidContainerFormat As Any, pguidVendor As Any, ppIEncoder As stdole.IUnknown) As Long
    Private Declare Function IWICImagingFactory_CreateBitmapFromMemory_Proxy Lib "windowscodecs" (ByVal pFactory As stdole.IUnknown, ByVal uiWidth As Long, ByVal uiHeight As Long, pixelFormat As Any, ByVal cbStride As Long, ByVal cbBufferSize As Long, pbBuffer As Any, ppIBitmap As stdole.IUnknown) As Long
    Private Declare Function IWICStream_InitializeFromIStream_Proxy Lib "windowscodecs" (ByVal pIWICStream As stdole.IUnknown, ByVal pIStream As stdole.IUnknown) As Long
    Private Declare Function IWICBitmapEncoder_Initialize_Proxy Lib "windowscodecs" (ByVal pIEncoder As stdole.IUnknown, ByVal pIStream As stdole.IUnknown, ByVal cacheOption As Long) As Long
    Private Declare Function IWICBitmapEncoder_CreateNewFrame_Proxy Lib "windowscodecs" (ByVal pIEncoder As stdole.IUnknown, ppIFrameEncode As stdole.IUnknown, ppIEncoderOptions As stdole.IUnknown) As Long
    Private Declare Function IWICBitmapEncoder_Commit_Proxy Lib "windowscodecs" (ByVal pIEncoder As stdole.IUnknown) As Long
    Private Declare Function IWICBitmapFrameEncode_Initialize_Proxy Lib "windowscodecs" (ByVal pIFrameEncode As stdole.IUnknown, ByVal pIEncoderOptions As stdole.IUnknown) As Long
    Private Declare Function IWICBitmapFrameEncode_SetSize_Proxy Lib "windowscodecs" (ByVal pIFrameEncode As stdole.IUnknown, ByVal uiWidth As Long, ByVal uiHeight As Long) As Long
    Private Declare Function IWICBitmapFrameEncode_WriteSource_Proxy Lib "windowscodecs" (ByVal pIFrameEncode As stdole.IUnknown, ByVal pIBitmapSource As stdole.IUnknown, pWicRect As Any) As Long
    Private Declare Function IWICBitmapFrameEncode_Commit_Proxy Lib "windowscodecs" (ByVal pIFrameEncode As stdole.IUnknown) As Long
    Private Declare Function IPropertyBag2_Write_Proxy Lib "windowscodecs" (ByVal pPropBag As stdole.IUnknown, ByVal cProperties As Long, pBag As Any, pvarValue As Variant) As Long
    
    Private m_pWicFactory           As stdole.IUnknown
    
    Public Function WicConvertToJpeg(baOutput() As Byte, ByVal lWidth As Long, ByVal lHeight As Long, baInput() As Byte, ByVal lQuality As Long) As Boolean
        Const WINCODEC_SDK_VERSION1   As Long = &H236&
        Const WINCODEC_SDK_VERSION2   As Long = &H237&
        Const WICBitmapEncoderNoCache As Long = 2
        Dim aGUID(0 To 3)   As Long
        Dim pBitmap         As stdole.IUnknown
        Dim pWicStream      As stdole.IUnknown
        Dim pStream         As stdole.IUnknown
        Dim pEncoder        As stdole.IUnknown
        Dim pFrame          As stdole.IUnknown
        Dim pPropBag        As stdole.IUnknown
        Dim cSize           As Currency
        Dim aBag(0 To 7)    As Long
        
        On Error GoTo EH
        If m_pWicFactory Is Nothing Then
            If WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION2, m_pWicFactory) < 0 Then
                If pvCheckHResult(WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION1, m_pWicFactory)) < 0 Then
                    GoTo QH
                End If
            End If
        End If
        '--- GUID_WICPixelFormat32bppPBGRA
        aGUID(0) = &H6FDDC324
        aGUID(1) = &H4BFE4E03
        aGUID(2) = &H773D85B1
        aGUID(3) = &H10C98D76
        If pvCheckHResult(IWICImagingFactory_CreateBitmapFromMemory_Proxy(m_pWicFactory, lWidth, lHeight, aGUID(0), lWidth * 4, UBound(baInput) + 1, baInput(0), pBitmap)) < 0 Then
            GoTo QH
        End If
        If pvCheckHResult(IWICImagingFactory_CreateStream_Proxy(m_pWicFactory, pWicStream)) < 0 Then
            GoTo QH
        End If
        Set pStream = SHCreateMemStream(ByVal 0, 0)
        If pvCheckHResult(IWICStream_InitializeFromIStream_Proxy(pWicStream, pStream)) < 0 Then
            GoTo QH
        End If
        '--- GUID_ContainerFormatJpeg
        aGUID(0) = &H19E4A5AA
        aGUID(1) = &H4FC55662
        aGUID(2) = &H5817C0A0
        aGUID(3) = &H57108E02
        If pvCheckHResult(IWICImagingFactory_CreateEncoder_Proxy(m_pWicFactory, aGUID(0), ByVal 0, pEncoder)) < 0 Then
            GoTo QH
        End If
        If pvCheckHResult(IWICBitmapEncoder_Initialize_Proxy(pEncoder, pWicStream, WICBitmapEncoderNoCache)) < 0 Then
            GoTo QH
        End If
        If pvCheckHResult(IWICBitmapEncoder_CreateNewFrame_Proxy(pEncoder, pFrame, pPropBag)) < 0 Then
            GoTo QH
        End If
        aBag(3) = StrPtr("ImageQuality")
        If pvCheckHResult(IPropertyBag2_Write_Proxy(pPropBag, 1, aBag(0), CSng(lQuality) / 100!)) < 0 Then
            GoTo QH
        End If
        If pvCheckHResult(IWICBitmapFrameEncode_Initialize_Proxy(pFrame, pPropBag)) < 0 Then
            GoTo QH
        End If
        If pvCheckHResult(IWICBitmapFrameEncode_SetSize_Proxy(pFrame, lWidth, lHeight)) < 0 Then
            GoTo QH
        End If
        If pvCheckHResult(IWICBitmapFrameEncode_WriteSource_Proxy(pFrame, pBitmap, ByVal 0)) < 0 Then
            GoTo QH
        End If
        If pvCheckHResult(IWICBitmapFrameEncode_Commit_Proxy(pFrame)) < 0 Then
            GoTo QH
        End If
        If pvCheckHResult(IWICBitmapEncoder_Commit_Proxy(pEncoder)) < 0 Then
            GoTo QH
        End If
        If pvCheckHResult(IStream_Size(pStream, cSize)) < 0 Then
            GoTo QH
        End If
        cSize = cSize * 10000
        If pvCheckHResult(IStream_Reset(pStream)) < 0 Then
            GoTo QH
        End If
        If cSize > 0 Then
            ReDim baOutput(0 To cSize - 1) As Byte
            If pvCheckHResult(IStream_Read(pStream, baOutput(0), cSize)) < 0 Then
                GoTo QH
            End If
        Else
            baOutput = vbNullString
        End If
        '--- success
        WicConvertToJpeg = True
    QH:
        Exit Function
    EH:
        Debug.Print Err.Description
    End Function
    
    Private Function pvCheckHResult(ByVal hResult As Long) As Long
        If hResult < 0 Then
            Err.Raise hResult
        End If
        pvCheckHResult = pvCheckHResult
    End Function
    Here is the sample Form1 that exercises the WicConvertToJpeg function above

    Code:
    Option Explicit
    
    Private Declare Function DeleteFile Lib "kernel32" Alias "DeleteFileA" (ByVal lpFileName As String) As Long
    
    Private Sub Form_Load()
        Dim lWidth          As Long
        Dim lHeight         As Long
        Dim baBitmap()      As Byte
        Dim baJpeg()        As Byte
        
        If Not WicLoadPicture("d:\temp\aaa.bmp", lWidth, lHeight, baBitmap) Then
            GoTo QH
        End If
        If Not WicConvertToJpeg(baJpeg, lWidth, lHeight, baBitmap, 80) Then
            GoTo QH
        End If
        WriteBinaryFile "d:\temp\aaa.jpg", baJpeg
    QH:
    End Sub
    
    Public Sub WriteBinaryFile(sFile As String, baBuffer() As Byte)
        Dim nFile           As Integer
        
        Call DeleteFile(sFile)
        nFile = FreeFile
        Open sFile For Binary Access Write Shared As nFile
        If UBound(baBuffer) >= 0 Then
            Put nFile, , baBuffer
        End If
        Close nFile
    End Sub
    The test code above needs another .bas module with the WicLoadPicture function

    Code:
    Option Explicit
    
    '--- WIC
    Private Declare Function WICCreateImagingFactory_Proxy Lib "windowscodecs" (ByVal SDKVersion As Long, ppIImagingFactory As stdole.IUnknown) As Long
    Private Declare Function IWICImagingFactory_CreateDecoderFromFilename_Proxy Lib "windowscodecs" (ByVal pFactory As stdole.IUnknown, ByVal wzFilename As Long, pguidVendor As Any, ByVal dwDesiredAccess As Long, ByVal lMetadataOptions As Long, ppIDecoder As stdole.IUnknown) As Long
    Private Declare Function IWICImagingFactory_CreateFormatConverter_Proxy Lib "windowscodecs" (ByVal pFactory As stdole.IUnknown, ppIFormatConverter As stdole.IUnknown) As Long
    Private Declare Function IWICBitmapDecoder_GetFrame_Proxy Lib "windowscodecs" (ByVal pThis As stdole.IUnknown, ByVal lIndex As Long, ppIBitmapFrame As stdole.IUnknown) As Long
    Private Declare Function IWICBitmapSource_CopyPixels_Proxy Lib "windowscodecs" (ByVal pThis As stdole.IUnknown, prc As Any, ByVal cbStride As Long, ByVal cbBufferSize As Long, pbBuffer As Any) As Long
    Private Declare Function IWICBitmapSource_GetSize_Proxy Lib "windowscodecs" (ByVal pThis As stdole.IUnknown, puiWidth As Long, puiHeight As Long) As Long
    Private Declare Function IWICFormatConverter_Initialize_Proxy Lib "windowscodecs" (ByVal pThis As stdole.IUnknown, ByVal pISource As stdole.IUnknown, dstFormat As Any, ByVal lDither As Long, ByVal pIPalette As stdole.IUnknown, ByVal dblAlphaThresholdPercent As Double, ByVal lPaletteTranslate As Long) As Long
    
    Private m_pWicFactory           As stdole.IUnknown
    
    Public Function WicLoadPicture( _
                sFileName As String, _
                lWidth As Long, _
                lHeight As Long, _
                baOutput() As Byte) As Boolean
        Const WINCODEC_SDK_VERSION1 As Long = &H236&
        Const WINCODEC_SDK_VERSION2 As Long = &H237&
        Const GENERIC_READ          As Long = &H80000000
        Dim pDecoder        As stdole.IUnknown
        Dim pFrame          As stdole.IUnknown
        Dim pConverter      As stdole.IUnknown
        Dim aGUID(0 To 3)   As Long
        
        If m_pWicFactory Is Nothing Then
            If WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION2, m_pWicFactory) < 0 Then
                If pvCheckHResult(WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION1, m_pWicFactory)) < 0 Then
                    GoTo QH
                End If
            End If
        End If
        If pvCheckHResult(IWICImagingFactory_CreateDecoderFromFilename_Proxy(m_pWicFactory, StrPtr(sFileName), ByVal 0, GENERIC_READ, 0, pDecoder)) < 0 Or pDecoder Is Nothing Then
            GoTo QH
        End If
        If pvCheckHResult(IWICBitmapDecoder_GetFrame_Proxy(pDecoder, 0, pFrame)) < 0 Or pFrame Is Nothing Then
            GoTo QH
        End If
        If pvCheckHResult(IWICBitmapSource_GetSize_Proxy(pFrame, lWidth, lHeight)) < 0 Then
            GoTo QH
        End If
        If pvCheckHResult(IWICImagingFactory_CreateFormatConverter_Proxy(m_pWicFactory, pConverter)) < 0 Or pConverter Is Nothing Then
            GoTo QH
        End If
        '--- GUID_WICPixelFormat32bppPBGRA
        aGUID(0) = &H6FDDC324
        aGUID(1) = &H4BFE4E03
        aGUID(2) = &H773D85B1
        aGUID(3) = &H10C98D76
        If pvCheckHResult(IWICFormatConverter_Initialize_Proxy(pConverter, pFrame, aGUID(0), 0, Nothing, 0#, 0)) < 0 Then
            GoTo QH
        End If
        ReDim baOutput(0 To lWidth * lHeight * 4 - 1) As Byte
        If pvCheckHResult(IWICBitmapSource_CopyPixels_Proxy(pConverter, ByVal 0&, lWidth * 4, lWidth * lHeight * 4, baOutput(0))) < 0 Then
            GoTo QH
        End If
        '--- success
        WicLoadPicture = True
    QH:
    End Function
    
    Private Function pvCheckHResult(ByVal hResult As Long) As Long
        If hResult < 0 Then
            Err.Raise hResult
        End If
        pvCheckHResult = pvCheckHResult
    End Function
    Posted all this code with all API declares to be searchable in the forums as WIC is quite apocryphal technology here.

    cheers,
    </wqw>

  2. #2
    Hyperactive Member
    Join Date
    Dec 2008
    Location
    Argentina
    Posts
    441

    Re: [VB6] In memory convert to JPEG using WIC

    Thanks for sharing, interesting! Do you have any opinion on comparing GDI + vs WIC?
    leandroascierto.com Visual Basic 6 projects

  3. #3
    PowerPoster yereverluvinuncleber's Avatar
    Join Date
    Feb 2014
    Location
    Norfolk UK (inbred)
    Posts
    3,560

    Re: [VB6] In memory convert to JPEG using WIC

    Well, one factor is that it requires Vista and above and so will not be compatible with NT5 devices, ie. Windows 2003, XP or ReactOS.

  4. #4

    Thread Starter
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,192

    Re: [VB6] In memory convert to JPEG using WIC

    Quote Originally Posted by yereverluvinuncleber View Post
    Well, one factor is that it requires Vista and above and so will not be compatible with NT5 devices, ie. Windows 2003, XP or ReactOS.
    A quote from Wikipedia: Windows Imaging Component (WIC) is a COM-based imaging codec framework introduced in Windows Vista (and later available in Windows XP Service Pack 3)[1] for working with and processing digital images and image metadata.

    I'm currently aiming this code at a more recent OS version as I'm using DXGI Desktop Duplication (at Win8+ feature) along with the converter so yes, while GDI+ is available on XP and above and has a redist for Win2000 it seems WIC is available on Vista and above and has a redist for XP.

    cheers,
    </wqw>

  5. #5
    PowerPoster yereverluvinuncleber's Avatar
    Join Date
    Feb 2014
    Location
    Norfolk UK (inbred)
    Posts
    3,560

    Re: [VB6] In memory convert to JPEG using WIC

    Interesting, do you have the link for the redist? It might be worth trying. Packaging a redistibutable with your program for the older oses might be problematic but for most developers, those oses won't be a primary target.

  6. #6
    PowerPoster
    Join Date
    Jan 2020
    Posts
    5,541

    Re: [VB6] In memory convert to JPEG using WIC

    CreateObject("WIA.ImageFile") ,Multiple image format conversion

    Code:
    Const wiaFormatBMP = "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}"
    Const wiaFormatPNG = "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}"
    Const wiaFormatGIF = "{B96B3CB0-0728-11D3-9D7B-0000F81EF32E}"
    Const wiaFormatTIFF = "{B96B3CB1-0728-11D3-9D7B-0000F81EF32E}"
    Const wiaFormatJPEG = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}"
    
    Sub WIA_Tojpg(srcFileName As String, JpgFile As String, Optional Quality As Long = 80)
    ' setup the image processor
    Dim prc, img
    Set prc = CreateObject("WIA.ImageProcess")
    With prc.Filters
        .Add prc.FilterInfos("Convert").FilterID
        .Item(1).Properties("FormatID").Value = wiaFormatJPEG
        If Quality > 0 Then .Item(1).Properties("Quality").Value = Quality ' 100%
    End With
    
    ' image object
    Set img = CreateObject("WIA.ImageFile")
    ' load, process and save the file
    img.LoadFile srcFileName
    Set img = prc.Apply(img)
    img.SaveFile JpgFile
    End Sub
    Sub TestWIA_PicTo()
        WIA_PicTo App.Path & "\002.bmp", App.Path & "\002_togif.gif", wiaFormatGIF, -1
    End Sub
    Sub WIA_PicTo(srcFileName As String, ToFile As String, Optional FormatID As String = wiaFormatJPEG, Optional Quality As Long = 80)
    ' setup the image processor
    Dim prc, img
    Set prc = CreateObject("WIA.ImageProcess")
    With prc.Filters
        .Add prc.FilterInfos("Convert").FilterID
        .Item(1).Properties("FormatID").Value = FormatID
        If Quality > 0 Then .Item(1).Properties("Quality").Value = Quality ' 100%
    End With
    
    ' image object
    Set img = CreateObject("WIA.ImageFile")
    ' load, process and save the file
    img.LoadFile srcFileName
    Set img = prc.Apply(img)
    img.SaveFile ToFile
    End Sub

  7. #7
    PowerPoster
    Join Date
    Jan 2020
    Posts
    5,541

    Re: [VB6] In memory convert to JPEG using WIC

    Get Jpg Byte Array() by wia:
    Code:
    Function WIA_TojpgByte(srcFileName As String, JpgFile As String, Optional Quality As Long = 80) As Byte()
    ' setup the image processor
    Dim prc As Object, img   As Object
    Set prc = CreateObject("WIA.ImageProcess")
    With prc.Filters
        .Add prc.FilterInfos("Convert").FilterID
        .Item(1).Properties("FormatID").Value = wiaFormatJPEG
        If Quality > 0 Then .Item(1).Properties("Quality").Value = Quality ' 100%
    End With
    
    ' image object
    Set img = CreateObject("WIA.ImageFile")
    ' load, process and save to byte Array
    img.LoadFile srcFileName
    Set img = prc.Apply(img)
    'dim Bt() As Byte
    'Bt = img.FileData.BinaryData()
    WIA_TojpgByte = img.FileData.BinaryData()
    End Function

    test bmp 3840*2160(31.6MB)

    used 84.4486 ms
    WicLoadPicture("d:\temp\aaa.bmp", lWidth, lHeight, baBitmap) Then
    WicConvertToJpeg
    =============
    WIA_Tojpg ,used 91.58 ms

    gdiplus,used 96.18ms
    get jpg byte from LoadPicture(BmpFile)

    use loadfile (not LoadPicture),used 58.4ms
    If GdipLoadImageFromFile(StrPtr(File1), lBitmap) = OK Then
    Last edited by xiaoyao; Mar 22nd, 2021 at 09:29 AM.

  8. #8

    Thread Starter
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,192

    Re: [VB6] In memory convert to JPEG using WIC

    What are you measuring? Loading 31.6MB from HDD or from drive cache?

    Please, stop micro-benchmarking *anything* because you don't know how to do it properly! I already told you several times these are bullsh*t elapsed times in milliseconds you are throwing left and right. . .

    cheers,
    </wqw>

  9. #9
    PowerPoster
    Join Date
    Jan 2020
    Posts
    5,541

    Re: [VB6] In memory convert to JPEG using WIC

    Quote Originally Posted by wqweto View Post
    What are you measuring? Loading 31.6MB from HDD or from drive cache?

    Please, stop micro-benchmarking *anything* because you don't know how to do it properly! I already told you several times these are bullsh*t elapsed times in milliseconds you are throwing left and right. . .

    cheers,
    </wqw>
    A picture taken from my computer desktop.This is just a simple test running speed, you can ignore it

  10. #10
    The Idiot
    Join Date
    Dec 2014
    Posts
    3,014

    Re: [VB6] In memory convert to JPEG using WIC

    also, we can use the typelib from the trick instead of the WIC API (I think)
    maybe I will look into it later, right now I dont need JPG, but could be that I want it in the future.
    if so, I will convert it to be used together with the typelib.

    its good that we start using WIC more, sure, as you say not fully compatible with XP and not working on older OS, but more and more people are leaving those systems and why not use something more recent?
    the same we could say about direct2d/directx, so we will be stuck forever with GDI. so thank for sharing wqweto.

  11. #11
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: [VB6] In memory convert to JPEG using WIC

    Quote Originally Posted by wqweto View Post
    Please, stop micro-benchmarking *anything* because you don't know how to do it properly!
    I agree of course (with the part of "not knowing how to do it properly").

    Though have to say, that I had high hopes, that WIC somehow incorporates the GPU now for JPG-encoding (on modern OSes) -
    but at least on my machine (Win10 with both, an Intel- and an NVidia-GPU) the results are not as good as the ones from libJPGTurbo.

    To encode a "Full HD" (1920x1080) 32bpp Bitmap (a ScreenShot) with 85% quality:
    - libJpgTurbo is needing 7-8msec
    - WIC needs nearly about 3 times as long -> 22-23msec

    So there seems to be no GPU-accelerated JpgEncoding involved when using WIC -
    and if we consider, that in a "RemoteServer-VNC-scenario", the Host (where the JPG-encoding takes place),
    runs often "headless" (in a VM), then WIC using GPU-accellerated JPG-encoding becomes even more unlikely.

    Here is my TestCode (using the somewhat newer libJPGTurbo-version, RC6 binds to):
    Code:
    Option Explicit
    
    Private Src32bpp As cCairoSurface, JpgBuf() As Byte
    
    Private Sub Form_Load()
      ReDim JpgBuf(0 To 10000000) 'ensure ~10MB "global JPG-BufSpace" for libJpgTurbo
      Set Src32bpp = Cairo.CreateSurface(0, 0, , "c:\temp\ScreenShot.png")
      Debug.Print New_c.FSO.FileLen("c:\temp\ScreenShot.png")
    End Sub
    
    Private Sub Form_Click()
      Cls
      Dim JPG As cJPG, JpgByteLen As Long, BOut() As Byte
      
      '**** libJPGTurbo-based encoding
      Set JPG = New_c.JPG
      
      New_c.Timing True
        With Src32bpp
             JpgByteLen = JPG.EncodeJPG(.DataPtr, .Width, .Height, VarPtr(JpgBuf(0)), 32, False, False, 85, TJ_420)
             'not really needed (when the result would be send via sockets directly from VarPtr(JpgBuf(0)),
             'but I'm including this here in the timing to isolate the Result-JpgBytes in their own ByteArray
             If JpgByteLen Then
                ReDim BOut(0 To JpgByteLen - 1)
                New_c.MemCopy VarPtr(BOut(0)), VarPtr(JpgBuf(0)), JpgByteLen
             End If
        End With
      Print JpgByteLen & New_c.Timing
      
      
      '**** WIC-based JPG-encoding
      Dim BInp() As Byte 'Let's leave the Input-ByteArray-prep out of the WIC-timing here
      ReDim BInp(0 To Src32bpp.Stride * Src32bpp.Height - 1)
      New_c.MemCopy VarPtr(BInp(0)), Src32bpp.DataPtr, Src32bpp.Stride * Src32bpp.Height
      Erase BOut
      
      New_c.Timing True
        With Src32bpp
             JpgByteLen = 0
             If WicConvertToJpeg(BOut, .Width, .Height, BInp, 85) Then JpgByteLen = UBound(BOut) + 1
        End With
      Print JpgByteLen & New_c.Timing
    End Sub
    Olaf

  12. #12

    Thread Starter
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,192

    Re: [VB6] In memory convert to JPEG using WIC

    Yes, libjpeg-turbo is a beast of an encoder! Everyone should donate $100 to not let the main contributor despair :-)) The funniest part is that it's a spin-off from the TurboVNC project -- its the SIMD optimized implementation of the JPEG compresor/decompressor they use and which was recently accepted as *the* reference JPEG implementation by the standard's committee thanks to its popularity.

    But your generous "~10MB global JPG-BufSpace for libJpgTurbo" comment reminded me there is a SHCreateMemStream call on every iteration on every tile of every frame being encoded so I had to bite the bullet and implement IStream::Seek with DispCallByVtbl to be able to determine stream's currently used space instead of depending on its allocated space which IStream_Size API call returns. This I hope saves a couple of million stream object instantiations and even more underlying buffer reallocations overall for the linked VNC server effort.

    cheers,
    </wqw>

  13. #13
    Hyperactive Member
    Join Date
    Jul 2020
    Posts
    437

    Re: [VB6] In memory convert to JPEG using WIC

    Unfortunately, due to lack of knowledge of the English language, I could not find out if it is possible to get the playing time of animated .gifs using the WIC functions?

  14. #14
    Frenzied Member
    Join Date
    May 2014
    Location
    Kallithea Attikis, Greece
    Posts
    1,312

    Re: [VB6] In memory convert to JPEG using WIC


  15. #15
    PowerPoster
    Join Date
    Jan 2020
    Posts
    5,541

    Re: [VB6] In memory convert to JPEG using WIC

    how to resize image size by wia?

    this only cut part of image,need your help,thanks
    i want change file to jpg/png ,and resize it
    if can cut any part of image,that's more better
    img size:700*500
    cut left=0,top=0, width=200,height=300
    cut left=100,top=100,width=300,height=400

    or cut first ,and resize 300*400 to 150*200 or resize to 150*350?

    Code:
        If NewWidth <> lWidth Or NewHeight <> lHeight Then
            If pvCheckHResult(IWICBitmapFrameEncode_SetSize_Proxy(pFrame, NewWidth, NewHeight)) < 0 Then
                GoTo QH
            End If
        End If
    Do wia and wic use the same API at the bottom? Perhaps they are all packaged in GDIPLUS?
    Last edited by xiaoyao; Feb 18th, 2025 at 10:30 AM.

  16. #16
    PowerPoster
    Join Date
    Jan 2020
    Posts
    5,541

    Re: [VB6] In memory convert to JPEG using WIC

    Is there any way to create a motion tween like flash?For example, 12 pictures are generated every second.
    Suppose there is a background picture. Then draw a light bulb on it. The light bulb is slowly getting bigger. Before each painting. The corresponding part of the background picture should be drawn again.
    For example, give him a reversal of the last transparent light bulb picture, which is to cover him with the original background picture. Or a mask map. ?

  17. #17
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    6,747

    Re: [VB6] In memory convert to JPEG using WIC

    Maybe this discussion can enlighten you
    https://graphicdesign.stackexchange....way-flash-does

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width