How to use freeimage.dll to load picture into either picture or image control using vb6?

Posted on 2004-11-12
Last Modified: 2012-06-27

How does one use freeimage.dll to load a picture into either a picture control or an image control.  I'm using Visual Basic, version 6.  I can load an image into memory and retrieve a handle for it OK, as such:

Dim TN  as Long
FName = "mybmp.bmp"

TN = FreeImage_Load(FIF_BMP, FName, 0) 'where FIF_BMP = 0 and where FName is for a .bmp file.

Once loaded, I can perform operations on the graphic OK.  For example, I can get the dimensions, as such:

'Get pic dimensions.
 Debug.Print "Width: " & FreeImage_GetWidth(TN) & ", Height: " & FreeImage_GetHeight(TN)

So, I can use freeimage.dll to load the image and convert it, rescale it and perform other operations on it just fine except for one thing...  how can I get that affected graphic loaded into a picturebox or an image control so that I can view it?  

Freeimage.dll allows me to save the image to a file and I know how to do that.  So, one method could be to save the image to disk as a .bmp and then use LoadPicture to load it into a picturebox (or image control or whatever).  But, I don't want to have to save it to disk and then load it back in again.

Can I do it somehow using FreeImage_LoadFromHandle?  Or maybe FreeImage_GetBits?

Looking forward to your replies.  


Question by:ksm
    LVL 32

    Accepted Solution

    Hi Kevin,

    The easiest way to display the DIB pointer returned from the freeimage library is to use the StretchDIBits API call to draw the image to a PictureBox (or any hDC).  Following is an example.  Please note the declare for StretchDIBits is a little different from the "standard" declare in that lpBitsInfo is passed "As Any."

    Private Const DIB_RGB_COLORS = 0
    Private Declare Function StretchDIBits Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal dx As Long, ByVal dy As Long, _
        ByVal SrcX As Long, ByVal SrcY As Long, ByVal wSrcWidth As Long, ByVal wSrcHeight As Long, lpBits As Any, _
        lpBitsInfo As Any, ByVal wUsage As Long, ByVal dwRop As Long) As Long

    Private Sub Command1_Click()

        Dim pDIB As Long
        Dim width As Long, height As Long
        'load an image and return a pointer to the DIB
        pDIB = FreeImg_Load(0, "c:\grayscale.bmp", 0)
        'get the DIB dimensions
        width = FreeImg_GetWidth(pDIB)
        height = FreeImg_GetHeight(pDIB)

        'Prepare to draw the DIB on Picture1
        Picture1.AutoRedraw = True
        'Draw the DIB
        Call StretchDIBits(Picture1.hdc, 0, 0, width, height, 0, 0, width, height, _
            ByVal FreeImg_GetBits(pDIB), ByVal FreeImg_GetInfo(pDIB), DIB_RGB_COLORS, vbSrcCopy)
        'Clean up
        Call FreeImg_Free(pDIB)

    End Sub

    Expert Comment

    I have done what you have wanted in C#

    My image is a 16bpp grayscale image, hence the *p1 is copied 3 times into *p for the RGB values. Since it is 16bpp, I am using short*. You could use byte* if it is a bpp image.
    // First load the image
    uint handle = FreeImageAPI.FreeImage.Load(FreeImageAPI.FREE_IMAGE_FORMAT.FIF_BMP, @"C:\tifImg.bmp", 0);
    // My image is 640x480, but you choose an empty canvas size of your choice
    Bitmap bmp = new Bitmap(640, 480);
    // Load the BMP map into memory
    BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, 640, 480), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    // Memory access via pointers is very fast!
       byte* p = (byte*)bmpData.Scan0;  // Get the address to the first   
       for (int i = 0; i < 480; i++)
          // Get the address to the scanline specified by 480-i
          short* p1 = (short*)FreeImageAPI.FreeImage.GetScanLine(handle, 480-i);
          for (int j = 0; j < 640; j++)
             *p = (byte)Math.Floor((double)*p1 / (2 ^ 5));
             *p = (byte)Math.Floor((double)*p1 / (2 ^ 5));
             *p = (byte)Math.Floor((double)*p1 / (2 ^ 5));
       p += bmpData.Stride - (640 * 3);
    // Display bmp in the picture box
    pic1.Image = bmp;

    Open in new window


    Featured Post

    Looking for New Ways to Advertise?

    Engage with tech pros in our community with native advertising, as a Vendor Expert, and more.

    Join & Write a Comment

    Introduction I needed to skip over some file processing within a For...Next loop in some old production code and wished that VB (classic) had a statement that would drop down to the end of the current iteration, bypassing the statements that were c…
    Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
    Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
    This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

    745 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    13 Experts available now in Live!

    Get 1:1 Help Now