Announcement

Collapse
No announcement yet.

How to make a BMP image in memory? Any pointers?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to make a BMP image in memory? Any pointers?

    I need to make a 72x72 24bit BMP image in memory. Anyone have a small example?
    I need to set the color via RGB and put text on the image etc....

    At the moment I have a bad workaround - I make the image in photoshop then open the file and read it into my program. Then I can stream it out to the device over USB.

    Once I have it in memory I might like to be able to save it to disk too...

    How do I get the actual data the from the handle?
    GRAPHIC BITMAP NEW 72, 72 TO h_BMP???????
    Last edited by David Clarke; 10 May 2019, 05:12 PM.

  • #2
    Originally posted by David Clarke View Post
    I need to make a 72x72 24bit BMP image in memory. Anyone have a small example?
    I need to set the color via RGB and put text on the image etc....

    At the moment I have a bad workaround - I make the image in photoshop then open the file and read it into my program. Then I can stream it out to the device over USB.

    Once I have it in memory I might like to be able to save it to disk too...

    How do I get the actual data the from the handle?
    GRAPHIC BITMAP NEW 72, 72 TO h_BMP???????
    You should consider using a GRAPHIC Control for drawing.
    Setting colors and placing text is quite simple, then.
    Copying the image to a bitmap is also quite simple.
    So is saving to disk.
    Code:
    #COMPILE EXE
    #DIM ALL
    #DEBUG DISPLAY
    #INCLUDE "win32api.inc"
    %Grfx = 500
    %SaveBMP = 501
    FUNCTION PBMAIN () AS LONG
        GLOBAL hfont AS LONG
        LOCAL hWin AS DWORD,  xitval AS LONG
        FONT NEW "Comic Sans MS", 8 TO hfont
        DIALOG NEW PIXELS, 0, "()", , , 80, 125, %WS_POPUP OR %WS_CAPTION OR %WS_SYSMENU TO hWin
        DIALOG SET COLOR hWin, %WHITE, %RGB_NAVY
        CONTROL ADD BUTTON, hWin, %SaveBMP, "Save BMP", 5, 5, 70, 30
        CONTROL ADD GRAPHIC, hWin, %Grfx, "8", 4, 40, 72, 72
        DIALOG SHOW MODAL hWin, CALL dlgproc() TO xitval
        FONT END hfont
        FUNCTION = xitval
    END FUNCTION
    CALLBACK FUNCTION dlgproc() AS LONG
        SELECT CASE CB.MSG
            CASE %WM_INITDIALOG
                DrawGraphic(CB.HNDL, %Grfx)
            CASE %WM_COMMAND
                SELECT CASE CB.CTL
                    CASE %SaveBMP
                        IF CB.CTLMSG = %BN_CLICKED THEN
                            LOCAL hBmp AS DWORD
                            GRAPHIC BITMAP NEW 72, 72 TO hBmp
                            GRAPHIC ATTACH hBmp, 0
                            GRAPHIC COPY CB.HNDL, %Grfx
                            GRAPHIC SAVE "TestBitmap.bmp"
                        END IF
                END SELECT
        END SELECT
    END FUNCTION
    SUB DrawGraphic(dlg AS DWORD, ctl AS LONG)
        GRAPHIC ATTACH dlg, ctl
        GRAPHIC CLEAR %RED
        GRAPHIC LINE (0, 0)-(71, 71), %WHITE
        GRAPHIC LINE (0, 71)-(71, 0), %WHITE
        GRAPHIC ELLIPSE (10, 10)-(61, 61), %BLACK
        GRAPHIC SET FONT hfont
        GRAPHIC COLOR %GREEN, -2
        GRAPHIC SET POS (5, 28)
        GRAPHIC PRINT "TEST TEXT"
    END SUB
    The world is strange and wonderful.*
    I reserve the right to be horrifically wrong.
    Please maintain a safe following distance.
    *wonderful sold separately.

    Comment


    • #3
      Code:
      FUNCTION PBMAIN()
      GRAPHIC BITMAP NEW X&, Y& TO BMPHNDL&
      GRAPHIC ATTACH BMPHNDL&, 0
      GRAPHIC CLEAR %RGB_PEACHPUFF
      FONT NEW "Times Roman", 12, 0, 0, 0, 0 TO FontHndl&
      GRAPHIC FONT FontHndl&
      GRAPHIC CELL SIZE TO CLX&, CLY&
      TxtStr$ = "Button"
      XC& = X& \ 2
      YC& = Y& \ 2
      LTX& = LEN(TxtStr$) \ 2
      '''''''GRAPHIC CELL = YC&, LTX&
      GRAPHIC CELL = YC&, XC& - LTX&
      GRAPHIC PRINT TxtStr$
      GRAPHIC SAVE "SomeBmpName.Bmp"
      END FUNCTION
      Placing the bitmap on a window using a graphic control:

      Code:
      CONTROL ADD GRAPHIC, WinHndl&, %GFX, "", 0, 0, X&, Y&, %SS_NOTIFY
      GRAPHIC ATTACH WinHndl&, %GFX
      GRAPHIC BITMAP RENDER "SomeBmpName.Bmp", (0, 0) - (X, Y)
      Placing it on a window without using a graphic control:

      Code:
      GRAPHIC BITMAP LOAD "SomeBmpName.Bmp", 0, 0, TO BmpHndl&
      GRAPHIC ATTACH BmpHndl&, 0
      GRAPHIC GET DC TO BmpDC&
      WinDc = getdc(WinHndl&)
      bitblt(WinDc, X&, Y&, X1&, Y&, BmpDC&, 0, 0, %COPYSRC)
      Last edited by Walt Decker; 11 May 2019, 10:50 AM. Reason: Mistake in code
      Walt Decker

      Comment


      • #4
        Thanks guys! I will give those ideas a try.

        Comment


        • #5
          This is very helpful! Next question:

          How can I put the created bitmap into a STRING variable?

          Comment


          • #6
            GRAPHIC GET BITS TO BitVar - does something but it is not a bmp.file....

            Comment


            • #7
              Use GRAPHIC GET BITS if using a graphic window or control.

              -OR-

              From a 24 bit bitmap file make a string of (X * Y * 4) + 8 bytes ((like nul$(length)) (((saves a lot of slow concatenating)))

              Get X and Y from file header. Poke X long into first 4 bytes, poke Y long into second 4 bytes.

              In a loop, get 3 bytes from file into long, Poke 4 bytes of long into next 4 bytes of string to end of file

              For 8 bit bitmap you "lookup" the 3 byte color of each pixel in the pallet (is between header and image bytes in file) Like before poke the 4 byte long containing the 3 byte color into the string.

              --------------------------------

              You may use @longpointer instead of POKE if you prefer.

              The string is called a DIB.

              Cheers,
              Dale

              Comment


              • #8
                You said -
                How can I put the created bitmap into a STRING variable?
                To create a bitmap file, get a DIB. get X and Y from DIB as part of header. Header starts with "BM" (I think you that part). Take the 3 RBG bytes from every 4 bytes in DIB and PUT after header in the file. A LONG in a UNION with a 3 byte UDT can make this easier.

                OR - build a string with the header, add the pixel info as above, save whole string to file.

                Cheers,

                added - I don't remember the endian of the numbers in the header.
                Dale

                Comment


                • #9
                  GRAPHIC GET BITS creates a string which contains the size of the bitmap in the first two bytes followed by all the pixel data as one four byte bitvar$ per pixel.

                  GRAPHIC SAVE creates a bitmap file comprising 1) A 14 byte BITMAPFILEHEADER plus 2) A 40 byte BITMAPINFOHEADER plus 3) The pixel info with 3 Bytes per pixel.

                  Only Three bytes per pixel are used in the Bitmap File - ie 24 bits w/ No Alpha info.

                  See post #19 in your other thread.

                  You can get the whole string, Header data plus Pixel bytes with file OPEN .. GET$ statements - just like the USB analyser gave you in that other thread
                  Rgds, Dave

                  Comment


                  • #10
                    Thanks, lots to try here!

                    And thanks Dave for post #19 very helpful.

                    Comment


                    • #11
                      Dale, you said "To create a bitmap file, get a DIB." How do I get a DIB?

                      Comment


                      • #12
                        GRAPHIC GET BITS if using a graphic window or control.
                        Dale

                        Comment


                        • #13
                          This is the device I am working on - https://www.elgato.com/en/gaming/stream-deck-mini
                          I think I can pull this off in a tiny PB program - The factory software has hundreds of files!
                          Basically all it does is tell you when a button is pressed and lets you put a bmp on the buttons.

                          Perhaps I should start over. I have a bitmap, I attached it to this post. It is a 80 by 80 where each pixel is 75-125-255 RGB.
                          I am going to call it a night and start fresh tomorrow.

                          I was trying to avoid doing
                          GRAPHIC SAVE "C:\ALL_BASIC_SOURCE\BASIC_USB_HID\DC_TRY\API\Bitmap.bmp"

                          Then reading the file from the disk. I am going to go back to that in the morning and give it a try...
                          Here is the bmp from a file.

                          When I look in the file I see more going on than just a BMP header followed by 6400 RGB (BGR) pixels.

                          Click image for larger version  Name:	Bitmap.bmp Views:	0 Size:	18.9 KB ID:	781209



                          I am sending it to a USB device and each WriteFile to the device needs an HID header.

                          Code:
                          HID_PACKET_HEADER_16 = CHR$(02, 01) + CHR$(I) + CHR$(00, 00) +  CHR$(KEY_NUMBER) + CHR$(00, 00, 00, 00, 00, 00, 00, 00, 00, 00)
                          That goes first on every write - where I = from 0 to 18.

                          Then I have a BMP Header.
                          Code:
                              BMP_HEADER = CHR$(&h42, &h4D, &h38, &h4B, &h00, &h00, &h00, &h00, &h00, &h00, &h36, &h00, &h00, &h00, &h28, &h00,_  '16
                                                &h00, &h00, &h50, &h00, &h00, &h00, &h50, &h00, &h00, &h00, &h01, &h00, &h18, &h00, &h00, &h00,_  '32
                                                &h00, &h00, &h00, &h00, &h4b, &h00, &h00, &h4c, &h0e, &h00, &h00, &h4c, &h0e, &h00, &h00, &h00,_  '48
                                                &h00, &h00, &h00, &h00, &h00, &h00)
                          Total packt size must be &h400 = 1024

                          Code:
                            IF i = 0 THEN
                               WRITE_BUFFER = LEFT$(HID_PACKET_HEADER_16 + BMP_HEADER + REPEAT$(336, "FF8833"),1024)
                              ELSE
                               WRITE_BUFFER = HID_PACKET_HEADER_16 + REPEAT$(336, "FF8833")
                             END IF
                             SEND_PACKET_TO_DEVICE WRITE_BUFFER
                          Then this is the final send. You have to change the HID_PACKET_HEADER to show it is the end of transmission

                          Code:
                             HID_PACKET_HEADER_16 = CHR$(02, 01) + CHR$(19) + CHR$(00, 00) +  CHR$(KEY_NUMBER) + CHR$(00, 00, 00, 00, 00, 00, 00, 00, 00, 00)
                             WRITE_BUFFER = HID_PACKET_HEADER_16 + REPEAT$(336, "FF8833")
                             SEND_PACKET_TO_DEVICE WRITE_BUFFER

                          Comment


                          • #14
                            Just be aware: The bitmap.bmp file attached to post #13 has a 124 byte BITMAPV5INFOHEADER structure which may not suit the Stream-Deck Mini device?

                            The captured data that you posted in another thread had a simpler 40 byte BITMAPINFOHEADER structure (the same as is generated by a PB GRAPHIC SAVE statement).
                            Rgds, Dave

                            Comment


                            • #15
                              Thanks Dave!!!

                              Comment


                              • #16
                                Mr. Clark;

                                take a look at https://forum.powerbasic.com/forum/u...228-clone-draw

                                There is code in there that will both load and unload a bitmap in the correct format. It also has code to get the bits from a DIB and a variety of other functions you may be interested in.
                                Walt Decker

                                Comment


                                • #17
                                  Thanks Walt!

                                  Cant find file -> NewTest.PLT

                                  Comment


                                  • #18
                                    NewTest.plt is a pallette file that you create when you draw something with the app. If the .cfg file has that in it you can edit the .cfg file and remove it. However, I've attached a .zip file containing it.

                                    newtest.zip
                                    Attached Files
                                    Walt Decker

                                    Comment


                                    • #19
                                      Thanks Walt!

                                      Comment


                                      • #20
                                        You are more than welcome, Mr. Clarke. I hope my little app will be of assistance to you.
                                        Walt Decker

                                        Comment

                                        Working...
                                        X