No announcement yet.


  • Filter
  • Time
  • Show
Clear All
new posts

  • bitmaps

    Ok, this is going to sound like a really, really stupid question...

    But how do I display an image? I have the image info (height, width etc.) in a BITMAP structure, and the image itself is currently in one big (~2.5Mb) dynamic string.

    The .bmBits member of the BITMAP structure is set as STRPTR(bits$), and then I use the CreateBitmapIndirect function, from the win32 API.

    Not feeling brave enough to tackle device contexts and all that nonsense, I copied the code from Petzold to put a bitmap in the clipboard.
    This gave me a nice black rectangle. Which is not what my original image looks like. I know that the image data is being generated correctly because I did manage to output if to a windows bitmap file, which is then correctly understood by graphics software, and can be set to the desktop wallpaper etc.

    However, now I need to use (i.e. display) the image within my programme, which means persuading Windows that it is indeed an image, for which it can give me a handle. The API call I've been using should do the job, but all I get is a blank box, and having tried all the variations I can think of, and searched POFFS, I am now at a loss.
    I wondered if its because I'm using a dynamic string, and tried to overlay an array using DIM... AT, but I have no idea if I was doing that properly, and it didn't work anyway.

    Suggestions would be greatly appreciated.


  • #2
    Dan --
    I have no idea, what are you doing.
    That's why I suggest to look this training code.

       #Compile Exe
       #Register None
       #Dim All
       #Include "Win32Api.Inc"
       Sub CopyPicture(hWnd As Long)
          Static hBmpClip As Long
          Dim hDC As Long, hDC1 As Long, hBmp As Long, rc As Rect, hBmpOld As Long
          hDC = GetDC(hWnd)
          hDC1 = CreateCompatibleDC(hDC)
          GetClientRect hWnd, rc
          hBmp = CreateCompatibleBitMap (hDC, rc.nRight, rc.nBottom)
          hBmpOld = SelectObject (hDc1, hBmp)
          BitBlt hDC1, 0, 0, rc.nRight, rc.nBottom, hDC, 0, 0, %SRCCOPY
          SelectObject hDC1, hBmpOld
          OpenClipboard ByVal 0
          If hBmpClip > 0 Then DeleteObject hBmpClip
          SetClipboardData %CF_BITMAP, hBMP
          DeleteObject hDC1
          hBmpClip = hBmp
          ReleaseDC hWnd, hDC
       End Sub
       Sub InsertPicture(hWnd As Long)
          Dim rc As Rect
          Dim hDC As Long, hBmp As Long, hDCMem As Long
          hDC = GetDC(hWnd)
          hdcMem = CreateCompatibleDC(hdc)
          If hdcMem Then
             If OpenClipboard(hWnd) Then
                hBmp = GetClipboardData(%CF_BITMAP)
                SelectObject hdcMem, hBmp
                GetClientRect hwnd, rc
                BitBlt hdc, 0, 0, rc.nRight, rc.nBottom, hdcMem, 0, 0, %SRCCOPY
             End If
             DeleteDC hdcMem
          End If
          ReleaseDC hWnd, hDC
       End Sub
       Global hDlg As Long
       CallBack Function ButProc
          CopyPicture GetDesktopWindow
          InsertPicture GetDlgItem(hDlg, 102)
       End Function
       Function PbMain () As Long
          Dialog New 0, "Polus", ,, 200, 240, %WS_CAPTION Or %WS_SYSMENU  To hDlg
          Control Add Button, hDlg, 101, "Paste Desktop window", 10, 10, 180, 15  Call ButProc
          Control Add Label, hDlg, 102, "", 10, 30, 180, 200, , %WS_EX_CLIENTEDGE
          Dialog Show Modal hDlg
       End Function
    E-MAIL: [email protected]


    • #3
      Semen, thanks for your code.

      This is my programme:

      #INCLUDE ""
      #INCLUDE ""
         LOCAL dib AS bitmap     'image info
         LOCAL result AS LONG    'did LoadJPG succeed?
         LOCAL file AS STRING    'Jpeg filename
         LOCAL hBmp AS LONG      'handle to bmp
         LOCAL bits AS STRING    'decoded jpeg image
         file = "D:\PBDLL60\Mine\CD project\testpic1.jpg"
         result = LoadJPG(file, dib, bits)
         IF result THEN
            hBmp = CreateBitmapIndirect(dib)
            IF hBmp = 0 THEN
               MSGBOX "Failure to create bitmap!" + $CRLF + _
                      "Error code: " + STR$(GetLastError())
               bmfh.bfType= CVWRD("BM")
               bmfh.bfSize = SIZEOF(bmfh) + SIZEOF(bmih) + LEN(bits)
               bmfh.bfOffBits = SIZEOF(bmfh) + SIZEOF(bmih)
               bmih.biSize = SIZEOF(bmih)
               bmih.biWidth = dib.bmWidth
               bmih.biHeight = dib.bmHeight
               bmih.biPlanes = 1
               bmih.biBitCount = 24
               OPEN "C:\temp\image.bmp" FOR BINARY AS #1
               PUT #1,, bmfh
               PUT #1,, bmih
               PUT$ #1, bits
               CLOSE #1
               MSGBOX "Image in file: C:\temp\image.bmp" + $CRLF + _
                      $CRLF + "Image data:" + $CRLF + _
                      "X: " + STR$(dib.bmWidth) + $CRLF + _
                      "Y: " + STR$(dib.bmHeight)
               OpenClipboard %NULL
               SetClipboardData %CF_BITMAP, hBmp
               'DeleteObject hBmp
               MSGBOX "Success!" + $CRLF + _
                      "Image should now be in clipboard." + $CRLF + _
                      "But probably isn't."
            END IF
            MSGBOX "Failure to load jpeg!!"
         END IF
      The file contains the LoadJPG function, which is essentially a wrapper for the Intel JPEG Library DLL.
      That function is working perfectly well: it opens the jpg image in file, and returns true if it succeeded, false otherwise. If it's succeeded, the variables dib and bits contain the image, as I described in my previous post.

      This code does correctly outputs the bitmap image file, but leaves only an empty image in the clipboard. And I have no idea why.



      • #4
        Dan --
        I can't say nothing without DLL + INC.
        But if you can select dib-section into any (memory) hDC, in further you can use
        a code, which I posted above or a code, which I posted in "source code" (to work directly with pixels).

        PS. If this DLL is freeware, put it on ftp.

        E-MAIL: [email protected]


        • #5
          Semen, the DLL is free from Intel:

          I translated the inc.h file provided with the DLL from C to PB. I am perfectly happy that my LoadJPG wrapper function works as it should. Rather than posting that and the lengthy header file, it would probably be better to use a "dummy" function instead of LoadJPG.
          I'll put one together tomorrow.

          I looked at your code for using a DIB section... but couldn't compile it ("String Operand Expected" line 57, IF @pi2.pDevMode = 0 THEN). I did try using the CreateDIBsection function in my code though, but with the same result as before - a bitmap image of the right size is created, but it's an empty box, no image data.
          I also tried the SetDIBits function. Strangely, this returned zero, but GetLastError also returned zero. Which makes no sense at all.

          I have now tried:
          and possibly one or two others. Always the function either fails (without any reason being made available through GetLastError), or I get the big black rectangle instead of the image. I'm sure I'm just missing the wood for the trees, but it's very frustrating, and after about two weeks of this I'm fast running out of ideas. The only thing I haven't tried is to output the image as a bitmap file, then read it back in again using LoadImage. But that's horribly clumsy, and more importantly it would be very slow with such big images.



          • #6

            You may want to relook what you are passing to this function "result = LoadJPG(file, dib, bits)"...

            Function LoadJPG(ByRef cDib As cDIBSection, ByVal sFile As String, ByVal jpg_scale As Long) As LONG