Author Topic: ImageToData (and back) by SMcNeill  (Read 651 times)

Offline The Librarian

  • Moderator
  • Newbie
  • Posts: 43
ImageToData (and back) by SMcNeill
« on: August 18, 2019, 12:38:36 AM »
ImageToData (and back)

Contributor(s): @SMcNeill
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=1553.0
Tags: [data] [graphics] [mem]

Description:
The MemImageToData is a specialized version of MemToHex which takes a _MEMIMAGE and converts it to Hex, while placing the DATA statement in front of it for us, for quick use pasting it into another program.  It basically lets us store image files inside a BAS file, without needing to _LOADIMAGE them externally.

Source Code:
Code: QB64: [Select]
  1. ' Set graphics mode.
  2. SCREEN _NEWIMAGE(640, 480, 32)
  3.  
  4. ' Prepare mem block(s) and image(s).
  5. t = _NEWIMAGE(16, 16, 32)
  6. m = _MEMIMAGE(t)
  7.  
  8. ' Send colored pixels to the destination "t".
  9. CIRCLE (8, 8), 7, -1
  10. PAINT (8, 8), -1
  11.  
  12. ' --> So far, nothing has appeared on the screen! <--
  13.  
  14. ' Copy the contents of "t" to the clipboard and display the result.
  15. _CLIPBOARD$ = MemImagetoDATA$(m, "t", 160)
  16.  
  17.  
  18. COLOR _RGB(255, 255, 255)
  19. PRINT "Hex representation of a small filled circle:": PRINT
  20. COLOR _RGB(155, 155, 155)
  21. PRINT "... etc. etc. ..."
  22. COLOR _RGB(255, 255, 255)
  23. PRINT "This information is already contained in the DATA statements in this program."
  24. PRINT "Press any key to convert this data back to an image."
  25.  
  26.  
  27. ' Restore using the proper label associated with the data.
  28. RESTORE TheDataLabel
  29.  
  30. ' Create and display a new image using the data.
  31. t1 = DATAtoImage
  32. _PUTIMAGE (320, 400), t1
  33.  
  34.  
  35. TheDataLabel:
  36. DATA 16,16,4
  37. DATA 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  38. DATA FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000
  39. DATA 0000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  40. DATA FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  41. DATA 00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  42. DATA FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000
  43. DATA 000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000
  44.  
  45. FUNCTION DATAtoImage&
  46.     'Requires a RESTORE label for the proper data BEFORE calling this routine
  47.     READ w, h, ps
  48.     SELECT CASE ps
  49.         CASE 1: ps = 256 '256 color screen
  50.         CASE 2: ps = 0 'text screen
  51.         CASE 4: ps = 32 '32-bit color screen
  52.     END SELECT
  53.     DATAtoImage& = _NEWIMAGE(w, h, ps)
  54.     DIM m AS _MEM
  55.     m = _MEMIMAGE(DATAtoImage&)
  56.     DO
  57.         READ hx$
  58.         FOR i = 1 TO LEN(hx$) STEP 2
  59.             h = VAL("&H" + MID$(hx$, i, 2))
  60.             _MEMPUT m, m.OFFSET + o, h
  61.             o = o + 1
  62.         NEXT
  63.         LOCATE 1, 1: PRINT o, m.SIZE
  64.     LOOP UNTIL o >= m.SIZE
  65.     _MEMFREE m
  66.  
  67. FUNCTION MemImagetoDATA$ (m AS _MEM, label$, break)
  68.     s = ConvertOffset(m.SIZE) - 1
  69.     label$ = _TRIM$(label$)
  70.     IF label$ = "" THEN label$ = "generic_label_placeholder:"
  71.     IF RIGHT$(label$, 1) <> ":" THEN label$ = label$ + ":"
  72.     MemImagetoDATA$ = label$ + CHR$(10) + "DATA "
  73.     MemImagetoDATA$ = MemImagetoDATA$ + STR$(_WIDTH(m.IMAGE)) + ", "
  74.     MemImagetoDATA$ = MemImagetoDATA$ + STR$(_HEIGHT(m.IMAGE)) + ", "
  75.     MemImagetoDATA$ = MemImagetoDATA$ + STR$(_PIXELSIZE(m.IMAGE)) + CHR$(10) + "DATA "
  76.     FOR i = 0 TO s
  77.         _MEMGET m, m.OFFSET + i, b
  78.         h$ = HEX$(b)
  79.         IF LEN(h$) = 1 THEN h$ = "0" + h$
  80.         MemImagetoDATA$ = MemImagetoDATA$ + h$
  81.         IF i MOD break = break - 1 AND i < s THEN
  82.             MemImagetoDATA$ = MemImagetoDATA$ + CHR$(10) + "DATA "
  83.         END IF
  84.     NEXT
  85.  
  86. FUNCTION ConvertOffset&& (value AS _OFFSET)
  87.     DIM m AS _MEM 'Define a memblock
  88.     m = _MEM(value) 'Point it to use value
  89.     $IF 64BIT THEN
  90.         'On 64 bit OSes, an OFFSET is 8 bytes in size.  We can put it directly into an Integer64
  91.         _MEMGET m, m.OFFSET, ConvertOffset&& 'Get the contents of the memblock and put the values there directly into ConvertOffset&&
  92.     $ELSE
  93.         'However, on 32 bit OSes, an OFFSET is only 4 bytes.  We need to put it into a LONG variable first
  94.         _MEMGET m, m.OFFSET, temp& 'Like this
  95.         ConvertOffset&& = temp& 'And then assign that long value to ConvertOffset&&
  96.     $END IF
  97.     _MEMFREE m 'Free the memblock
  98.  

« Last Edit: March 07, 2020, 01:18:41 AM by The Librarian »