Results 1 to 10 of 10

Thread: 8-bit paletted graphics in memory [resolved]

  1. #1

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    8-bit paletted graphics in memory [resolved]

    I already have some idea how to do this, but it is all theory. I have no real knowledge how to assign a palette to a graphic in a memory - I haven't done a non 32-bit image before either. So if anyone has a simple example code / tutorial to go with, I'll be grateful My search results this far have given far too complicated codes atm, but I continue searching once I'm awake again.
    Last edited by Merri; May 21st, 2004 at 06:57 AM.

  2. #2
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    Here are two tools i've made for my quake modifications (which uses 8-bit palette).

    In palette.zip there is a program for editing the palette.

    In convert.zip there is a program that converts 8/16/24/32 bit images to 8 bit using the palette. I've made a dll file in C that searches for closest matching color from the palette, and because I'm not that good at C I didn't make the program load the palette file, I've added the palette to the code instead. You'll have to make it load it yourself.

    Have fun!
    Attached Files Attached Files
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  3. #3
    So Unbanned DiGiTaIErRoR's Avatar
    Join Date
    Apr 1999
    Location
    /dev/null
    Posts
    4,111
    Originally posted by cyborg
    Here are two tools i've made for my quake modifications (which uses 8-bit palette).

    In palette.zip there is a program for editing the palette.

    In convert.zip there is a program that converts 8/16/24/32 bit images to 8 bit using the palette. I've made a dll file in C that searches for closest matching color from the palette, and because I'm not that good at C I didn't make the program load the palette file, I've added the palette to the code instead. You'll have to make it load it yourself.

    Have fun!
    It's slow....

  4. #4
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    Yes it is, but why would you want to convert 32-bit images to 8-bit in realtime?
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  5. #5

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654
    I don't need to convert images at all, as I have to read 8-bit images to memory and then view them with the correct palette. I might have found a code that works for me, but I can't test it until I can get as far as reading the data properly - sure is complicated not to be able to debug well, but I've always found a way

  6. #6
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    It's really easy to read 8-bit images...

    The colors in a 8-bit image are from 0 to 255 so the palette should have the Red, Green and Blue values for each 256 colors.
    Just load the palette into an array like this:

    VB Code:
    1. Private Type ColorUDT
    2.     Red As Byte
    3.     Green As Byte
    4.     Blue As Byte
    5. End Type
    6.  
    7. Dim Palette(255) As ColorUDT

    Then to get the color from the palette you just do something like this:
    Palette(ColorFrom8BitImage).Red
    Palette(ColorFrom8BitImage).Green
    Palette(ColorFrom8BitImage).Blue
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  7. #7
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    Btw...Check the function that loads LMP files in the Bmp2Lmp program i attached. It loads 8-bit images and displays them on the screen using a palette.
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  8. #8

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654
    I know how to do it the slow way - I want to do it the fast Windows native way. Should be possible.

    - I have byte array of the image
    - I want to storage it in a form I can display instantly from the memory
    - I want to be able to view it in a PictureBox or any other object that supports Picture

    There is code there, but these aren't too clear on what they do. And there are tons of API calls. At the moment I have ended up creating a class module - the only thing missing is the _working_ code. I haven't seen anything that is exactly what I need so I'm trying to figure out how to do it from the codes that handle the memory storaged images. What really lacks with the examples I have found are the comments: they are like "'Create the picture" - not describing how it does the new picture and what the input values mean.

  9. #9

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654
    This is my current class module, at the moment untested. You are free to point out errors you might see. I'm pretty sure this won't work, but I keep up a small drop of hope.

    VB Code:
    1. Option Explicit
    2.  
    3. Private Const DIB_RGB_COLORS As Long = 0
    4.  
    5. 'bitmap information
    6. Private Type BITMAP
    7.     bmType As Long
    8.     bmWidth As Long
    9.     bmHeight As Long
    10.     bmWidthBytes As Long
    11.     bmPlanes As Integer
    12.     bmBitsPixel As Integer
    13.     bmBits As Long
    14. End Type
    15.  
    16. Private Type BMP_GUID
    17.     Data1 As Long
    18.     Data2 As Integer
    19.     Data3 As Integer
    20.     Data4(7) As Byte
    21. End Type
    22.  
    23. Private Type BMP_PICTURE
    24.     Size As Long
    25.     Type As Long
    26.     hBmp As Long
    27.     hPal As Long
    28.     Reserved As Long
    29. End Type
    30.  
    31. 'images in memory
    32. Private Declare Function CreateBitmap Lib "gdi32" (ByVal nWidth As Long, ByVal nHeight As Long, ByVal nPlanes As Long, ByVal nBitCount As Long, lpBits As Any) As Long
    33. Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hDC As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
    34. Private Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
    35.  
    36. Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    37. Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
    38. Private Declare Function SelectObject Lib "gdi32" (ByVal hDC As Long, ByVal hObject As Long) As Long
    39.  
    40. Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hDC As Long) As Long
    41. Private Declare Function DeleteDC Lib "gdi32" (ByVal hDC As Long) As Long
    42. Private Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
    43. Private Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hDC As Long) As Long
    44.  
    45. Private Declare Function SetDIBits_8 Lib "gdi32" Alias "SetDIBits" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpbi As BITMAPINFO_8, ByVal wUsage As Long) As Long
    46.  
    47. Private Declare Function CreatePalette Lib "gdi32" (lpLogPalette As LOGPALETTE) As Long
    48. Private Declare Function RealizePalette Lib "gdi32" (ByVal hDC As Long) As Long
    49. Private Declare Function SelectPalette Lib "gdi32" (ByVal hDC As Long, ByVal hPalette As Long, ByVal bForceBackground As Long) As Long
    50.  
    51. Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (PicDesc As BMP_PICTURE, RefIID As BMP_GUID, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long
    52.  
    53. Private InUseScreen As Boolean, InUseImage As Boolean
    54. Private ScreenDC As Long, PicDC As Long, DestDC As Long
    55. Private PicBmp As Long, PicPrevBmp As Long, PicPal As Long, PicPrevPal As Long
    56. Private Width As Long, Height As Long
    57. 'initial step: get screen DC as default DC
    58. Private Sub Class_Initialize()
    59.     Init GetDC(0)
    60. End Sub
    61. 'last step: free memory
    62. Private Sub Class_Terminate()
    63.     If InUseImage Then ClearImage
    64.     'free Dc
    65.     Call ReleaseDC(0, ScreenDC)
    66.     InUseScreen = False
    67. End Sub
    68. Public Sub ClearImage()
    69.     Dim PrevBmp As Long
    70.     'free image
    71.     If InUseImage Then
    72.         PrevBmp = SelectObject(PicDC, PicPrevBmp)
    73.         Call DeleteObject(PicBmp)
    74.         Call DeleteDC(PicDC)
    75.         InUseImage = False
    76.     End If
    77. End Sub
    78. 'alternative step: change DC
    79. Public Sub Init(hDC As Long)
    80.     'do a proper clearing before filling up with new information (if required)
    81.     If InUseScreen Then Class_Terminate
    82.     'set default DC
    83.     ScreenDC = hDC
    84.     PicDC = CreateCompatibleDC(ScreenDC)
    85.     'mark we have filled DC
    86.     InUseScreen = True
    87. End Sub
    88. 'step 3: view the image
    89. Property Get Picture() As IPictureDisp
    90.     Dim Pic As BMP_PICTURE, IPic As IPicture, IID_IDispatch As BMP_GUID
    91.  
    92.     'fill GUID info (whatever it is...)
    93.     With IID_IDispatch
    94.         .Data1 = &H20400
    95.         .Data4(0) = &HC0
    96.         .Data4(7) = &H46
    97.     End With
    98.  
    99.     'fill picture info
    100.     With Pic
    101.         .Size = Len(Pic) ' Length of structure
    102.         .Type = vbPicTypeBitmap ' Type of Picture (bitmap)
    103.         .hBmp = PicBmp ' Handle to bitmap
    104.         .hPal = PicPal ' Handle to palette (may be null)
    105.     End With
    106.    
    107.     Call OleCreatePictureIndirect(Pic, IID_IDispatch, 1, IPic)
    108.    
    109.     'view picture in destination
    110.     Set Picture = IPic
    111. End Property
    112. 'step 1: image must be set
    113. Public Sub SetImage(ByRef Info As BITMAPINFO_8, ByRef DataArray() As Byte)
    114.     'do a proper clearing before new image
    115.     If InUseImage Then ClearImage
    116.     'create image
    117.     PicBmp = CreateCompatibleBitmap(ScreenDC, Width, Height)
    118.     PicPrevBmp = SelectObject(PicDC, PicBmp)
    119.     'set image bits
    120.     Call SetDIBits_8(PicDC, PicBmp, 0, Width, DataArray(0), Info, DIB_RGB_COLORS)
    121.     'mark image to be in use
    122.     InUseImage = True
    123. End Sub
    124. 'step 2: palette must be set
    125. Public Sub SetPalette(ByRef DataArray() As Byte)
    126.     Dim BmpPal As BITMAPPALETTE
    127.     'init palette
    128.     BmpPal.palVersion = &H300
    129.     BmpPal.palNumEntries = 256
    130.     RtlMoveMemory VarPtr(BmpPal.palPalEntry(0)), VarPtr(DataArray(0)), 1024
    131.     'create palette and set it in use
    132.     PicPal = CreatePalette(BmpPal)
    133.     PicPrevPal = SelectPalette(PicDC, PicPal, 0)
    134.     Call RealizePalette(PicDC)
    135. End Sub

  10. #10

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654
    I finally found this great code that resolves my problem:

    VB Code:
    1. Option Explicit
    2.  
    3. Private Const BI_RGB = 0&
    4. Private Const CBM_INIT = &H4
    5. Private Const DIB_RGB_COLORS = 0
    6. Private Const SRCCOPY = &HCC0020
    7.  
    8. Private Type BITMAPINFOHEADER
    9.     biSize As Long
    10.     biWidth As Long
    11.     biHeight As Long
    12.     biPlanes As Integer
    13.     biBitCount As Integer
    14.     biCompression As Long
    15.     biSizeImage As Long
    16.     biXPelsPerMeter As Long
    17.     biYPelsPerMeter As Long
    18.     biClrUsed As Long
    19.     biClrImportant As Long
    20. End Type
    21. Private Type RGBQUAD
    22.     rgbBlue As Byte
    23.     rgbGreen As Byte
    24.     rgbRed As Byte
    25.     rgbReserved As Byte
    26. End Type
    27. Private Type BITMAPINFO_256
    28.     bmiHeader As BITMAPINFOHEADER
    29.     bmiColors(0 To 255) As RGBQUAD
    30. End Type
    31.  
    32. Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
    33. Private Declare Function CreateDIBitmap Lib "gdi32" (ByVal hdc As Long, lpInfoHeader As BITMAPINFOHEADER, ByVal dwUsage As Long, lpInitBits As Any, lpInitInfo As BITMAPINFO_256, ByVal wUsage As Long) As Long
    34. Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
    35. Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
    36. Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
    37. Private Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
    38.  
    39. Dim Pixels() As Byte          ' Pixel data.
    40. Dim bm_info As BITMAPINFO_256 ' DIB bitmap info.
    41. Dim hDIB As Long              ' Bitmap handle.
    42. Dim wid As Integer            ' Size of the bitmap.
    43. Dim hgt As Integer
    44.  
    45. ' Create the DIB.
    46. Private Sub CreateDIB()
    47. Dim screen_hdc As Long
    48.  
    49.     With bm_info.bmiHeader
    50.         .biSize = Len(bm_info.bmiHeader)
    51.         .biWidth = wid          ' Width in pixels.
    52.         .biHeight = hgt         ' Height in pixels.
    53.         .biPlanes = 1           ' 1 color plane.
    54.         .biBitCount = 8         ' 8 bits per pixel.
    55.         .biCompression = BI_RGB ' No compression.
    56.         .biSizeImage = 0        ' Unneeded with no compression.
    57.         .biXPelsPerMeter = 0    ' Unneeded.
    58.         .biYPelsPerMeter = 0    ' Unneeded.
    59.         .biClrUsed = 256        ' # colors in color table that are used by the image. 0 means all.
    60.         .biClrImportant = 256   ' # important colors. 0 means all.
    61.     End With
    62.    
    63.     ' Get the screen's device context.
    64.     screen_hdc = GetDC(0)
    65.    
    66.     ' Create the DIB.
    67.     hDIB = CreateDIBitmap(screen_hdc, _
    68.         bm_info.bmiHeader, CBM_INIT, Pixels(0, 0), _
    69.         bm_info, DIB_RGB_COLORS)
    70. End Sub
    71.  
    72. ' Draw the DIB onto the form.
    73. Private Sub DrawDIB()
    74. Dim compat_dc As Long
    75.  
    76.     ' Create a compatible device context.
    77.     compat_dc = CreateCompatibleDC(hdc)
    78.    
    79.     ' Select the DIB into the compatible DC.
    80.     SelectObject compat_dc, hDIB
    81.        
    82.     ' Copy the compatible DC's image onto the form.
    83.     StretchBlt Picture1.hdc, 0, 0, _
    84.         Picture1.ScaleWidth, Picture1.ScaleHeight, _
    85.         compat_dc, 0, 0, wid, hgt, _
    86.         SRCCOPY
    87.  
    88.     ' Destroy the compatible DC.
    89.     DeleteDC compat_dc
    90. End Sub
    91.  
    92. ' Initialize 256 shades of blue.
    93. Private Sub SetColorTable()
    94. Dim i As Integer
    95.  
    96.     For i = 0 To 255
    97.         bm_info.bmiColors(i).rgbRed = 0
    98.         bm_info.bmiColors(i).rgbGreen = 0
    99.         bm_info.bmiColors(i).rgbBlue = i
    100.         bm_info.bmiColors(i).rgbReserved = 0
    101.     Next i
    102. End Sub
    103. ' Create a drawing.
    104. Private Sub SetPixels()
    105. Dim X As Integer
    106. Dim Y As Integer
    107.  
    108.     wid = 100
    109.     hgt = 256
    110.     ReDim Pixels(0 To wid - 1, 0 To hgt - 1)
    111.     For Y = 0 To hgt - 1
    112.         For X = 0 To wid - 1
    113.             If Y Mod 20 = 19 Or X Mod 20 = 19 Then
    114.                 Pixels(X, Y) = Y
    115.             Else
    116.                 Pixels(X, Y) = 255 - Y
    117.             End If
    118.         Next X
    119.     Next Y
    120. End Sub
    121. Private Sub Form_Load()
    122.     SetColorTable
    123.     SetPixels
    124.     CreateDIB
    125. End Sub
    126.  
    127. Private Sub Form_Resize()
    128.     Picture1.Move 0, 0, ScaleWidth, ScaleHeight
    129.     Picture1.Refresh
    130. End Sub
    131.  
    132.  
    133. Private Sub Picture1_Paint()
    134.     DrawDIB
    135. End Sub

    Simple and clear code and does exatly what I want. Well, not exactly (it doesn't provide Picture handling), but close enough to be usable

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