Convert image to 8bit 256 colors (windows only)

Share your advanced PureBasic knowledge/code with the community.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Didn't work here Netmaestro, just made a copy of the original color image.

Vista x86, PB 4.4 beta 2.

**EDIT : my mistake! Doh! Works fine - thanks.
Last edited by srod on Sun Aug 30, 2009 9:16 pm, edited 1 time in total.
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

I'm pulling the saved image from the disk into Photoshop and verifying 8bit indexed color, how are you testing to see if the image is truly 8 bits depth? If you do an ImageDepth() on the catched image, that won't work because PB pulls it in at the default 24bit depth.
BERESHEIT
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Sorry, works fine! :)
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Damn you you scared me!! :shock:
BERESHEIT
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

netmaestro wrote:Damn you you scared me!! :shock:
Now you know how I feel everytime I wake up in the afternoon and see my face staring back at me in the mirror! :wink:
I may look like a mule, but I'm not a complete ass.
LuCiFeR[SD]
666
666
Posts: 1033
Joined: Mon Sep 01, 2003 2:33 pm

Post by LuCiFeR[SD] »

haha, you guys crack me up... Just like Srod's Mirror :P
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Convert image to 8bit 256 colors (windows only)

Post by luis »

Wow... nice code Netmaestro, I was looking in the forum for something to quantize color images and found this.

Your adaptive palette works a lot better than the ones generated using octrees, and with most images do a better job than a good optimized median cut too. And it's simple and fast to implement.

I believe I wil start from your code and try to see if I can enhance it more... I just read a paper on neural networks (Kohonen's to be precise) used exactly for this same purpose...

I'll let you know.

I really like the PB's forum :)
"Have you tried turning it off and on again ?"
A little PureBasic review
Booger
Enthusiast
Enthusiast
Posts: 134
Joined: Tue Sep 04, 2007 2:18 pm

Re: Convert image to 8bit 256 colors (windows only)

Post by Booger »

Very impressive. Thanks alot. Thanks for sharing.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: Convert image to 8bit 256 colors (windows only)

Post by Mistrel »

Does not work on Windows XP 64-bit.

I tried both this and luis's method in PureBasic 4.31 and 4.40.

For your code "i" from ImageTo8bit() always returns 0.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: Convert image to 8bit 256 colors (windows only)

Post by Mistrel »

It works slightly better when compiling with 4.40 x64. Greyscale works fine. Screen8 works but looks wildly different, and adaptive crashes with an #Image not initialized at line 85 in the .pbi.
Inf0Byt3
PureBasic Fanatic
PureBasic Fanatic
Posts: 2236
Joined: Fri Dec 09, 2005 12:15 pm
Location: Elbonia

Re: Convert image to 8bit 256 colors (windows only)

Post by Inf0Byt3 »

Sorry to dig old topics out, but I'm wondering if it would be hard to add support for icon files?
None are more hopelessly enslaved than those who falsely believe they are free. (Goethe)
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Convert image to 8bit 256 colors (windows only)

Post by netmaestro »

I have written code for saving icons to disk and this code includes a procedure to minimize the filesize of the saved icon by counting the colors actually used in the original and creating the output icon using the minimum necessary. For example, if an icon is 5 kb in size because of the format it was saved in, but it only uses 16 or less actual colors, my routine will save it at 1 k.

Hopefully this is more or less what you are looking for, and here is the code:

Code: Select all

;=======================================================================
;  Library:               IconLib
;  Author:                Lloyd Gallant (netmaestro)
;  Date:                  October 15, 2009
;  Target OS:             Microsoft Windows All
;  Target Compiler:       Requires PureBasic 4.40
;  
;  Functions:             WriteIconFile
;                         Writes an Array of 4bit-32bit hIcons 
;                         to an .ico file on disk
;                          
;                         WriteCursorFile
;                         writes a 1bit-32bit hIcon or 1bit hCursor
;                         to a .cur file on disk
;=======================================================================

Structure ICONDIR
  idReserved.w                  ; // Reserved (must be 0)
  idType.w                      ; // Resource type (1 for icons)
  idCount.w                     ; // How many images?
  idEntries.ICONHEADER[0]       ; // The entries for each image
EndStructure

Structure ICONARRAY
  icons.l[0]
EndStructure

Procedure CountColorsUsed(pBitmap)
  GetObject_(pBitmap, SizeOf(BITMAP), @bmp.BITMAP) 
  *bmi.BITMAPINFO = AllocateMemory(SizeOf(BITMAPINFO)+SizeOf(RGBQUAD)*255)
  With *bmi\bmiHeader
    \biSize         = SizeOf(BITMAPINFOHEADER) 
    \biWidth        = bmp\bmWidth 
    \biHeight       = bmp\bmHeight 
    \biPlanes       = 1 
    \biBitCount     = 32 
  EndWith 
  hDC = CreateCompatibleDC_(#Null) 
  GetDIBits_(hDC, pBitmap, 0, bmp\bmHeight, #Null, *bmi, #DIB_RGB_COLORS)
  *pPixels = AllocateMemory(*bmi\bmiHeader\biSizeImage)
  iRes = GetDIBits_(hDC, pBitmap, 0, bmp\bmHeight, *pPixels, *bmi, #DIB_RGB_COLORS) 
  
  Global mapsize = MemorySize(*pPixels)/2
  Global NewMap Colors.RGBQUAD(mapsize)
  *p.RGBQUAD = *pPixels
  For i=1 To MemorySize(*pPixels)/SizeOf(RGBQUAD)
    With Colors(Hex(PeekL(*p)))
      \rgbBlue      = *p\rgbBlue
      \rgbGreen     = *p\rgbGreen
      \rgbRed       = *p\rgbRed
      \rgbReserved  = *p\rgbReserved
    EndWith
    *p+SizeOf(RGBQUAD)
  Next
  
  result = MapSize(colors())
  
  If result <= 16
    *colortable = AllocateMemory(16*SizeOf(RGBQUAD))
  ElseIf result <= 256
    *colortable= AllocateMemory(256*SizeOf(RGBQUAD))
  Else
    *colortable = 0
  EndIf
  
  If *colortable
    *writeptr.RGBQUAD = *colortable
    ForEach colors()
      With *writeptr
        \rgbBlue     = colors()\rgbBlue
        \rgbGreen    = colors()\rgbGreen
        \rgbRed      = colors()\rgbRed
        \rgbReserved = 0
      EndWith
      *writeptr+SizeOf(RGBQUAD)
    Next
  EndIf
  
  DeleteDC_(hdc)
  ClearMap(colors())
  FreeMemory(*pPixels)
  FreeMemory(*bmi)
  
  ProcedureReturn *colortable
EndProcedure

Procedure MinimizeColors(hBitmap)
  
  ; Count actual colors used: 
  ;  if     <= 16  -----> convert To 4bit
  ;  elseif <= 256 -----> convert to 8bit
  ;  else          -----> return original bitmap
  
  *colortable = CountColorsUsed(hBitmap)
  hImageOut = 0
  
  If *colortable
    Select MemorySize(*colortable)
      Case 64
        newdepth = 4
      Case 1024
        newdepth = 8
    EndSelect
    
    GetObject_(hBitmap,SizeOf(BITMAP),bmp.BITMAP) 
    w = bmp\bmWidth 
    h = bmp\bmHeight 
    
    hdcSrc = CreateCompatibleDC_(0)
    
    With bmi.BITMAPINFO 
      \bmiHeader\biSize     = SizeOf(BITMAPINFOHEADER) 
      \bmiHeader\biWidth    = w 
      \bmiHeader\biHeight   = h 
      \bmiHeader\biPlanes   = 1 
      \bmiHeader\biBitCount = 32
    EndWith  
    
    GetDIBits_(hdcSrc, hBitmap, 0, h, #Null, @bmi, #DIB_RGB_COLORS) 
    
    *colorbits = AllocateMemory(bmi\bmiHeader\biSizeImage) 
    
    GetDIBits_(hdcSrc, hBitmap, 0, h, *colorbits, @bmi, #DIB_RGB_COLORS) 
    
    With bmiReduced.BITMAPINFO 
      \bmiHeader\biSize     = SizeOf(BITMAPINFOHEADER) 
      \bmiHeader\biWidth    = w 
      \bmiHeader\biHeight   = h 
      \bmiHeader\biPlanes   = 1 
      \bmiHeader\biBitCount = newdepth
    EndWith
    
    hdcDest = CreateCompatibleDC_(0)
    
    hImageOut = CreateDIBSection_(hdcDest, @bmiReduced, #DIB_PAL_COLORS, @*bitsReduced, 0, 0) 
    
    SelectObject_(hdcDest, hImageOut) 
    SetDIBColorTable_(hdcDest, 0, MemorySize(*colortable)/SizeOf(RGBQUAD), *colortable)
    
    GdiFlush_()
    SetDIBits_(hdcSrc, hImageOut, 0, h, *colorbits, @bmi, #DIB_PAL_COLORS) 
    
    DeleteDC_(hdcSrc)
    DeleteDC_(hdcDest)
    
    FreeMemory(*colortable)
    FreeMemory(*colorbits)
    
  EndIf
  
  If GetObjectType_(hImageOut) = #OBJ_BITMAP
    ProcedureReturn hImageOut   
  Else
    ProcedureReturn hBitmap
  EndIf
  
EndProcedure


;=======================================================================
;  Library Function:      WriteIconFile
;  Author:                Lloyd Gallant (netmaestro)
;  Date:                  October 15, 2009
;  Target OS:             Microsoft Windows All
;  Target Compiler:       PureBasic 4.40
;  
;  Function:              Writes an array of 4bit-32bit hIcons 
;                         to an .ico file on disk
;=======================================================================

ProcedureDLL.l WriteIconFile( *hIcon_array.ICONARRAY, num_hIcons, filename$)
  
  ; netmaestro October 2009 based on http://msdn.microsoft.com/en-us/library/ms997538.aspx
  ; contributors: srod
  
  Protected hdc, iinf.ICONINFO, mask, color, bmpColor.BITMAP, bmpMask.BITMAP, *bi_color.BITMAPINFO, *bi_mask.BITMAPINFO
  Protected *maskbits, *colorbits, *file, *direntryptr,*imagedataptr, *id.ICONDIR, *ih.ICONHEADER, *ii.ICONIMAGE
  Protected i, testicon, thisfile, sz_color, sz_mask, result=0, writesuccess, icons_processed=0
  
  NewList Valid_hIcon.i() ; Valid_hIcon list gets filled with validated hIcons only
  
  For i=0 To num_hIcons-1
    testicon = *hIcon_array\icons[i]
    FillMemory(@iinf, SizeOf(ICONINFO), 0)
    GetIconInfo_(testicon, @iinf)
    If iinf\hbmMask And iinf\hbmColor And iinf\fIcon=1 ; 1-bit icons are not supported, valid depths are 4,8,16,32
      AddElement(Valid_hIcon())
      Valid_hIcon()=testicon
    EndIf
  Next
  
  hdc = CreateCompatibleDC_(#Null)
  
  *file = AllocateMemory(1024*1024*4) ; 4 megabytes should be more than enough
  *direntryptr = *file
  
  ; File header
  *id.ICONDIR = *direntryptr
  With *id
    \idType  = 1
    \idCount = ListSize(Valid_hIcon())
  EndWith
  *direntryptr+SizeOf(ICONDIR) ; ICONHEADER entries start here
  
  *imagedataptr = *direntryptr + ListSize(Valid_hIcon())*SizeOf(ICONHEADER) ; Leave room for <listsize> ICONHEADER entries
  ; Image data entries start here
  ForEach Valid_hIcon()
    GetIconInfo_(Valid_hIcon(), @iinf.ICONINFO)
    usecolortable = #False
    num_colors    = 0
    sz_colortable = 0
    
    mask  = iinf\hbmMask
    
    color = MinimizeColors(iinf\hbmColor)
    
    ;===================================================
    ;          Get this entry's color bits
    ;===================================================
    
    GetObject_(color, SizeOf(BITMAP), bmpColor.BITMAP)
    
    If bmpColor\bmBitsPixel <= 8
      usecolortable = #True
      num_colors = Int(Pow(2,bmpColor\bmBitsPixel))
      sz_colortable = num_colors*SizeOf(RGBQUAD)
      If *colortable : FreeMemory(*colortable) : EndIf
      *colortable = AllocateMemory(sz_colortable)
      old = SelectObject_(hdc, color)
      GetDIBColorTable_(hdc, 0, num_colors, *colortable)    
      SelectObject_(hdc, old)
    EndIf
    
    If *bi_color : FreeMemory(*bi_color) : EndIf
    *bi_color = AllocateMemory(SizeOf(BITMAPINFOHEADER)+256*SizeOf(RGBQUAD))
    *bi_color\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
    
    GetDIBits_(hdc, color, 0, bmpColor\bmHeight, 0, *bi_color, #DIB_RGB_COLORS ) 
    sz_color = *bi_color\bmiHeader\biSizeImage
    *bi_color\bmiHeader\biBitCount = bmpColor\bmBitsPixel
    If *colorbits : FreeMemory(*colorbits) : EndIf
    *colorbits = AllocateMemory(sz_color) 
    GetDIBits_(hdc, color, 0, bmpColor\bmHeight, *colorbits, *bi_color, #DIB_RGB_COLORS )     
    
    ;===================================================
    ;          Get this entry's mask bits
    ;===================================================
    
    GetObject_(mask, SizeOf(BITMAP), bmpMask.BITMAP)
    
    If *bi_mask : FreeMemory(*bi_mask) : EndIf 
    *bi_mask = AllocateMemory(SizeOf(BITMAPINFOHEADER)+256*SizeOf(RGBQUAD))
    *bi_mask\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
    
    GetDIBits_(hdc, mask, 0, bmpMask\bmHeight, 0, *bi_mask, #DIB_RGB_COLORS ) 
    sz_mask = *bi_mask\bmiHeader\biSizeImage
    *bi_mask\bmiHeader\biBitCount = bmpMask\bmBitsPixel
    If *maskbits : FreeMemory(*maskbits) : EndIf
    *maskbits = AllocateMemory( sz_mask ) 
    GetDIBits_(hdc, mask, 0, bmpMask\bmHeight, *maskbits, *bi_mask, #DIB_RGB_COLORS )     
    
    ;===================================================
    ;           Write this entry to the file
    ;===================================================
    
    ; Icon header first, in the headers section
    *ih.ICONHEADER = *direntryptr 
    With *ih
      \bWidth        = bmpcolor\bmWidth
      \bHeight       = bmpcolor\bmHeight 
      \wPlanes       = 1
      \wBitCount     = bmpcolor\bmBitsPixel 
      \dwBytesinRes  = sz_colortable + sz_color + sz_mask + SizeOf(ICONIMAGE) 
      \dwBytesOffset = *imagedataptr - *file
    EndWith
    *direntryptr+SizeOf(ICONHEADER) 
    
    ; ICONIMAGE structure next, in the imagedata section
    *ii.ICONIMAGE = *imagedataptr 
    With *ii\icHeader
      \biSize      = SizeOf(BITMAPINFOHEADER)
      \biWidth     = bmpColor\bmWidth
      \biHeight    = bmpColor\bmHeight * 2
      \biPlanes    = 1
      \biBitCount  = bmpcolor\bmBitsPixel 
      \biSizeImage = sz_colortable + sz_color + sz_mask + SizeOf(ICONIMAGE)
    EndWith
    *imagedataptr+SizeOf(BITMAPINFOHEADER) 
    
    ; Lastly, colortable (if present), color and mask bits
    If usecolortable : CopyMemory( *colortable, *imagedataptr, sz_colortable ) : *imagedataptr + sz_colortable : EndIf
    CopyMemory( *colorbits, *imagedataptr, sz_color ) : *imagedataptr + sz_color
    CopyMemory( *maskbits,  *imagedataptr, sz_mask  ) : *imagedataptr + sz_mask ; Pointer is ready for the next entry
    
    icons_processed + 1
    
    If color:DeleteObject_(color):EndIf
    DeleteObject_(mask)
    
  Next  
  
  DeleteDC_(hdc)
  
  ;===========================================================
  ;   All icons are processed, file can be written to disk
  ;===========================================================
  
  If icons_processed
    thisfile = CreateFile(#PB_Any, filename$)
    If thisfile
      writesuccess = *imagedataptr-*file 
      result       = WriteData( thisfile, *file, writesuccess )
      CloseFile( thisfile )
    Else
      MessageRequester("Info:", "Function WriteIconFile in library IconLib failed with error: unable to create file "+filename$+"  ", #MB_ICONERROR)
    EndIf
    FreeMemory(*bi_color)
    FreeMemory(*bi_mask)
    If *colortable : FreeMemory(*colortable) : EndIf    
    FreeMemory(*colorbits)
    FreeMemory(*maskbits)
  EndIf
  
  FreeMemory(*file)
  
  If result = writesuccess And result <> 0
    ProcedureReturn icons_processed
  Else
    ProcedureReturn 0
  EndIf
  
EndProcedure

;=======================================================================
;  Library Function:      WriteCursorFile
;  Author:                Lloyd Gallant (netmaestro)
;  Date:                  October 16, 2009
;  Target OS:             Microsoft Windows All
;  Target Compiler:       PureBasic 4.40
;  
;  Function:              Writes a 16bit-32bit or 1bit hCursor
;                         to a .cur file on disk
;=======================================================================

ProcedureDLL.l WriteCursorFile(hCursor, xHotspot, yHotspot, filename$)
  
  GetIconInfo_(hCursor, @ii.ICONINFO)
  
  If Not (ii\hbmMask)
    ProcedureReturn 0
  EndIf
  
  mask  = ii\hbmMask
  color = ii\hbmColor
  
  usecolortable = #False
  num_colors    = 0
  sz_colortable = 0
  
  hdc = CreateCompatibleDC_(#Null)
  
  ;===================================================
  ;                Get color bits
  ;===================================================
  
  If color
    GetObject_(color, SizeOf(BITMAP), bmpColor.BITMAP)
    
    If bmpColor\bmBitsPixel <= 8
      usecolortable = #True
      num_colors = Int(Pow(2,bmpColor\bmBitsPixel))
      sz_colortable = num_colors*SizeOf(RGBQUAD)
      If *colortable : FreeMemory(*colortable) : EndIf
      *colortable = AllocateMemory(sz_colortable)
      old = SelectObject_(hdc, color)
      GetDIBColorTable_(hdc, 0, num_colors, *colortable)    
      SelectObject_(hdc, old)
    EndIf
    
    *bi_color.BITMAPINFO = AllocateMemory(SizeOf(BITMAPINFOHEADER)+255*SizeOf(RGBQUAD))
    
    *bi_color\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
    
    GetDIBits_(hdc, color, 0, bmpColor\bmHeight, 0, *bi_color, #DIB_RGB_COLORS ) 
    sz_color = *bi_color\bmiHeader\biSizeImage
    *bi_color\bmiHeader\biBitCount = bmpColor\bmBitsPixel
    *colorbits = AllocateMemory(sz_color) 
    GetDIBits_(hdc, color, 0, bmpColor\bmHeight, *colorbits, *bi_color, #DIB_RGB_COLORS )    
  Else ; 1-bit 
    sz_color = 0 
    sz_colortable = 2*SizeOf(RGBQUAD)
  EndIf
  
  ;===================================================
  ;                  Get mask bits
  ;===================================================
  
  GetObject_(mask, SizeOf(BITMAP), bmpMask.BITMAP)
  
  *bi_mask.BITMAPINFO = AllocateMemory(SizeOf(BITMAPINFOHEADER)+255*SizeOf(RGBQUAD))
  
  With *bi_mask\bmiHeader
    \biSize        = SizeOf(BITMAPINFOHEADER)
    \biWidth       = bmpMask\bmWidth 
    \biHeight      = bmpMask\bmHeight
    \biPlanes      = bmpMask\bmPlanes
    \biBitCount    = 0
  EndWith
  
  GetDIBits_(hdc, mask, 0, bmpMask\bmHeight, 0, *bi_mask, #DIB_PAL_COLORS ) 
  sz_mask = *bi_mask\bmiHeader\biSizeImage
  *bi_mask\bmiHeader\biBitCount = bmpMask\bmBitsPixel
  *maskbits = AllocateMemory( sz_mask ) 
  GetDIBits_(hdc, mask, 0, bmpMask\bmHeight, *maskbits, *bi_mask, #DIB_PAL_COLORS )     
  
  ;===================================================
  ;              Start writing the file
  ;===================================================
  
  *file = AllocateMemory(1024*1024)
  *writeptr = *file
  
  *id.ICONDIR = *writeptr
  With *id
    \idType  = 2
    \idCount = 1
  EndWith
  *writeptr+SizeOf(ICONDIR) 
  
  *ih.ICONHEADER = *writeptr 
  With *ih
    If color : \bHeight = bmpColor\bmHeight : Else : \bHeight = bmpMask\bmHeight/2 : EndIf
    \bWidth        = bmpMask\bmWidth   
    \wPlanes       = xHotspot
    \wBitCount     = yHotspot
    \dwBytesinRes  = sz_colortable + sz_color + sz_mask + SizeOf(ICONIMAGE) 
    \dwBytesOffset = SizeOf(ICONDIR)+SizeOf(ICONHEADER)
  EndWith
  *writeptr+SizeOf(ICONHEADER) 
  
  *ii.ICONIMAGE = *writeptr 
  With *ii\icHeader
    \biSize   = SizeOf(BITMAPINFOHEADER)
    \biWidth  = bmpMask\bmWidth 
    If color : \biHeight = bmpColor\bmHeight * 2 : Else : \biHeight = bmpMask\bmHeight : EndIf
    \biPlanes = 1
    If color : \biBitCount  = bmpColor\bmBitsPixel : Else : \biBitCount = 1 : EndIf
    \biSizeImage = sz_colortable + sz_color + sz_mask + SizeOf(ICONIMAGE) 
  EndWith
  *writeptr+SizeOf(BITMAPINFOHEADER) 
  
  If Not color ; 1-bit
    PokeL( *writeptr, #Black ) : *writeptr + SizeOf(LONG)
    PokeL( *writeptr, #White ) : *writeptr + SizeOf(LONG)
  Else
    If usecolortable : CopyMemory( *colortable, *writeptr, sz_colortable ) : *writeptr + sz_colortable : EndIf
  EndIf
  
  If color: CopyMemory( *colorbits, *writeptr, sz_color ) : *writeptr + sz_color : EndIf 
  CopyMemory( *maskbits,  *writeptr, sz_mask  ) : *writeptr + sz_mask
  
  If color : DeleteObject_(color) : EndIf
  If mask  : DeleteObject_(mask)  : EndIf
  
  If *bi_color   : FreeMemory(*bi_color)   : EndIf
  If *bi_mask    : FreeMemory(*bi_mask)    : EndIf
  If *colorbits  : FreeMemory(*colorbits)  : EndIf
  If *colortable : FreeMemory(*colortable) : EndIf
  If *maskbits   : FreeMemory(*maskbits)   : EndIf
  
  thisfile = CreateFile(#PB_Any, filename$)
  If thisfile
    writesuccess = *writeptr-*file 
    result       = WriteData( thisfile, *file, writesuccess )
    CloseFile( thisfile )
  Else
    MessageRequester("Info:", "Function WriteCursorFile in library IconLib failed with error: unable to create file "+filename$+"  ", #MB_ICONERROR)
  EndIf
  
  FreeMemory(*file)
  DeleteDC_(hdc)
  
  If result = writesuccess And result <> 0
    ProcedureReturn 1
  Else
    ProcedureReturn 0
  EndIf
  
EndProcedure 


Dim icos(1)
icos(0) = LoadImage(0,#PB_Compiler_Home+"Examples\sources\data\cdplayer.ico")
WriteIconFile(icos(),1,"c:\cdplayer.test.ico")
BERESHEIT
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: Convert image to 8bit 256 colors (windows only)

Post by MachineCode »

Can the original code save as PNG instead of BMP? Because wouldn't that reduce the file size even more? PNG supports 256 color palettes, so it should work?
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Convert image to 8bit 256 colors (windows only)

Post by netmaestro »

Can the original code save as PNG instead of BMP?
You have the code, go ahead and add it if you like. I won't have time for it anytime soon unfortunately.
BERESHEIT
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: Convert image to 8bit 256 colors (windows only)

Post by MachineCode »

I tried it already but it didn't work. That's why I was asking the original source. ;)

All I did was use "SaveImage(i, filename$, #PB_ImagePlugin_PNG)" instead of the Save8bitImage() procedure, but I get an error of "The specified #Image is not initialized." Not sure how to get around it.
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
Post Reply