Page 4 of 5

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

Posted: Mon Jun 06, 2011 5:19 am
by electrochrisso
Did you put UsePNGImageDecoder() at start of code, I forget it a lot.

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

Posted: Mon Jun 06, 2011 5:51 am
by MachineCode
Yes, I did. I took a closer look and it seems the BMP code is saved by being built in a custom procedure (and not saved with the SaveImage() command), which leads me to assume I'd need to save the PNG with a custom procedure too, and build the PNG file manually. That's way above me.

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

Posted: Mon Jun 06, 2011 8:20 pm
by Inf0Byt3
@netmaestro: I needed some code to create a 256-bit icon from an input icon that can have any depth. In the install maker I made, currently the user has to supply an icon made of 3 layers, each of them having 256 colors. The program can't use an icon with more layers or with different depth because the program basically patches the new icon over the old one and it has to have the same size bitwise. So in order to make it work with any icon the user supplies, i'd have to make a code to extract / make 3 layers of 16*16,32*32 and 48*48 pixels, make them all have 256 colors then save them inside an icon that the installer will use.

I'll try to adapt your code for this task, thank you for your time :D.

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

Posted: Thu May 02, 2013 10:58 pm
by Wend
Please correct the 'UnpackMemory(' in the OP

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

Posted: Sat May 04, 2013 11:45 am
by Little John
Uuuh, I've missed this fine piece of code until now.
Many thanks, netmaestro!
I can make good use of this in a future project.
Wend wrote:Please correct the 'UnpackMemory(' in the OP
Thanks for bringing this to our attention.
The last PB version with support for UnpackMemory() was PB 5.00. So I just re-installed PB 5.00, and wrote a small program for unpacking netmaestro's ColorTable and storing it in uncompressed form.

Then in the first code block of netmaestro's original post, I replaced

Code: Select all

Procedure ColorTable()

  *unpacked = AllocateMemory(824)
  UnpackMemory(?ColorTable, *unpacked)
  img0 = CatchImage(#PB_Any, *unpacked, 824)
  FreeMemory(*unpacked)
 
  DataSection
    ColorTable:
    Data.b $4A,$43,$38,$03,$00,$00,$4E,$C7,$B6,$7E,$B3,$A9,$D0,$20,$69,$14,$19,$88,$12,$CA
    Data.b $08,$B0,$4A,$08,$25,$90,$0C,$30,$46,$02,$89,$81,$20,$70,$60,$10,$D8,$42,$AA,$91
    Data.b $FF,$16,$02,$A9,$66,$80,$90,$84,$00,$68,$51,$20,$0A,$0C,$50,$52,$88,$02,$0A,$44
    Data.b $81,$28,$A2,$40,$6D,$21,$86,$28,$10,$05,$14,$88,$02,$49,$64,$1B,$A2,$40,$02,$51
    Data.b $20,$0A,$28,$D0,$76,$88,$20,$0A,$44,$81,$00,$48,$02,$49,$3A,$38,$10,$31,$14,$74
    Data.b $28,$52,$24,$0C,$30,$40,$A2,$40,$14,$88,$A0,$A4,$10,$05,$14,$88,$02,$51,$44,$81
    Data.b $DA,$42,$0C,$51,$20,$0A,$28,$10,$05,$92,$C8,$36,$44,$81,$05,$A2,$40,$14,$24,$81
    Data.b $24,$10,$02,$49,$20,$09,$35,$3A,$14,$C8,$40,$B6,$01,$C3,$6D,$A0,$0E,$03,$20,$92
    Data.b $30,$00,$14,$88,$02,$51,$44,$81,$92,$42,$0B,$51,$20,$0A,$28,$10,$05,$6A,$48,$32
    Data.b $44,$81,$05,$A2,$40,$14,$24,$81,$24,$10,$0E,$49,$20,$09,$28,$10,$05,$DA,$20,$0B
    Data.b $44,$81,$0C,$88,$02,$51,$88,$02,$49,$06,$05,$A2,$40,$14,$44,$81,$28,$10,$02,$51
    Data.b $20,$0A,$A2,$40,$14,$88,$81,$28,$10,$05,$51,$20,$0A,$44,$40,$13,$68,$02,$28,$D0
    Data.b $04,$9A,$20,$0A,$44,$81,$14,$88,$02,$51,$10,$05,$A2,$40,$68,$88,$82,$28,$0A,$D4
    Data.b $16,$30,$88,$02,$51,$20,$05,$A2,$40,$14,$44,$81,$28,$10,$02,$51,$20,$0A,$9A,$40
    Data.b $14,$88,$81,$26,$D0,$04,$51,$20,$0A,$34,$40,$14,$88,$02,$28,$10,$05,$A2,$20,$0A
    Data.b $44,$81,$14,$88,$02,$51,$57,$0A,$A2,$40,$50,$52,$C0,$A0,$0A,$44,$81,$28,$88,$02
    Data.b $51,$20,$05,$A2,$40,$14,$34,$81,$26,$10,$02,$4D,$A0,$09,$A2,$40,$14,$88,$81,$28
    Data.b $10,$05,$51,$20,$0A,$44,$40,$14,$88,$02,$28,$10,$05,$A2,$20,$0A,$44,$81,$2C,$88
    Data.b $02,$51,$24,$01,$83,$36,$10,$05,$A2,$40,$09,$44,$81,$28,$68,$02,$4D,$A0,$05,$A2
    Data.b $40,$13,$44,$81,$28,$10,$02,$51,$20,$0A,$A2,$40,$14,$88,$81,$28,$10,$05,$51,$20
    Data.b $0A,$44,$40,$14,$88,$02,$28,$10,$05,$A2,$20,$0A,$44,$81,$A8,$B4,$3C,$B4,$5A,$50
    Data.b $04,$30,$80,$51,$00,$A2,$8E,$3E,$80,$22,$22,$80,$11,$C9,$A0,$08,$14,$81,$11,$28
    Data.b $02,$45,$50,$04,$8A,$40,$08,$14,$81,$22,$28,$02,$45,$A0,$04,$8A,$40,$11,$14,$81
    Data.b $22,$50,$02,$45,$A0,$08,$89,$40,$11,$28,$00,$40,$24,$32
    ColorTableend:
  EndDataSection
with

Code: Select all

Procedure ColorTable()
   img0 = CatchImage(#PB_Any, ?ColorTable, 824)

   DataSection
      ColorTable:
      Data.b $42,$4D,$38,$03,$00,$00,$00,$00,$00,$00,$36,$00,$00,$00,$28,$00,$00,$00,$20,$00
      Data.b $00,$00,$08,$00,$00,$00,$01,$00,$18,$00,$00,$00,$00,$00,$02,$03,$00,$00,$12,$0B
      Data.b $00,$00,$12,$0B,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$00,$55,$FF,$00
      Data.b $AA,$FF,$00,$FF,$FF,$00,$00,$FF,$24,$55,$FF,$24,$AA,$FF,$24,$FF,$FF,$24,$00,$FF
      Data.b $49,$55,$FF,$49,$AA,$FF,$49,$FF,$FF,$49,$00,$FF,$6D,$55,$FF,$6D,$AA,$FF,$6D,$FF
      Data.b $FF,$6D,$00,$FF,$92,$55,$FF,$92,$AA,$FF,$92,$FF,$FF,$92,$00,$FF,$B6,$55,$FF,$B6
      Data.b $AA,$FF,$B6,$FF,$FF,$B6,$00,$FF,$DB,$55,$FF,$DB,$AA,$FF,$DB,$FF,$FF,$DB,$00,$FF
      Data.b $FF,$55,$FF,$FF,$AA,$FF,$FF,$FF,$FF,$FF,$00,$DB,$00,$55,$DB,$14,$AA,$DB,$00,$FF
      Data.b $DB,$00,$00,$DB,$24,$55,$DB,$24,$AA,$DB,$24,$FF,$DB,$24,$00,$DB,$49,$55,$DB,$49
      Data.b $AA,$DB,$49,$FF,$DB,$49,$00,$DB,$6D,$55,$DB,$6D,$AA,$DB,$6D,$FF,$DB,$6D,$00,$DB
      Data.b $92,$55,$DB,$92,$AA,$DB,$92,$FF,$DB,$92,$00,$DB,$B6,$55,$DB,$B6,$AA,$DB,$B6,$FF
      Data.b $DB,$B6,$00,$DB,$DB,$55,$DB,$DB,$AA,$DB,$DB,$FF,$DB,$DB,$00,$DB,$FF,$55,$DB,$FF
      Data.b $AA,$DB,$FF,$FF,$DB,$FF,$00,$B6,$00,$55,$B6,$00,$AA,$B6,$00,$FF,$B6,$00,$00,$B6
      Data.b $24,$55,$B6,$24,$AA,$B6,$24,$FF,$B6,$24,$00,$B6,$49,$55,$B6,$49,$AA,$B6,$49,$FF
      Data.b $B6,$49,$00,$B6,$6D,$55,$B6,$6D,$AA,$B6,$6D,$FF,$B6,$6D,$00,$B6,$92,$55,$B6,$92
      Data.b $AA,$B6,$92,$FF,$B6,$92,$00,$B6,$B6,$55,$B6,$B6,$AA,$B6,$B6,$FF,$B6,$B6,$00,$B6
      Data.b $DB,$55,$B6,$DB,$AA,$B6,$DB,$FF,$B6,$DB,$00,$B6,$FF,$55,$B6,$FF,$AA,$B6,$FF,$FF
      Data.b $B6,$FF,$00,$92,$00,$55,$92,$00,$AA,$92,$00,$FF,$92,$00,$00,$92,$24,$55,$92,$24
      Data.b $AA,$92,$24,$FF,$92,$24,$00,$92,$49,$55,$92,$49,$AA,$92,$49,$FF,$92,$49,$00,$92
      Data.b $6D,$55,$92,$6D,$AA,$92,$6D,$FF,$92,$6D,$00,$92,$92,$55,$92,$92,$AA,$92,$92,$FF
      Data.b $92,$92,$00,$92,$B6,$55,$92,$B6,$AA,$92,$B6,$FF,$92,$B6,$00,$92,$DB,$55,$92,$DB
      Data.b $AA,$92,$DB,$FF,$92,$DB,$00,$92,$FF,$55,$92,$FF,$AA,$92,$FF,$FF,$92,$FF,$00,$6D
      Data.b $00,$55,$6D,$00,$AA,$6D,$00,$FF,$6D,$00,$00,$6D,$24,$55,$6D,$24,$AA,$6D,$24,$FF
      Data.b $6D,$24,$00,$6D,$49,$55,$6D,$49,$AA,$6D,$49,$FF,$6D,$49,$00,$6D,$6D,$55,$6D,$6D
      Data.b $AA,$6D,$6D,$FF,$6D,$6D,$00,$6D,$92,$55,$6D,$92,$AA,$6D,$92,$FF,$6D,$92,$00,$6D
      Data.b $B6,$55,$6D,$B6,$AA,$6D,$B6,$FF,$6D,$B6,$00,$6D,$DB,$55,$6D,$DB,$AA,$6D,$DB,$FF
      Data.b $6D,$DB,$00,$6D,$FF,$55,$6D,$FF,$AA,$6D,$FF,$FF,$6D,$FF,$00,$49,$00,$55,$49,$00
      Data.b $AA,$49,$00,$FF,$49,$00,$00,$49,$24,$55,$49,$24,$AA,$49,$24,$FF,$49,$24,$00,$49
      Data.b $49,$55,$49,$49,$AA,$49,$49,$FF,$49,$49,$00,$49,$6D,$55,$49,$6D,$AA,$49,$6D,$FF
      Data.b $49,$6D,$00,$49,$92,$55,$49,$92,$AA,$49,$92,$FF,$49,$92,$00,$49,$B6,$55,$49,$B6
      Data.b $AA,$49,$B6,$FF,$49,$B6,$00,$49,$DB,$55,$49,$DB,$AA,$49,$DB,$FF,$49,$DB,$00,$49
      Data.b $FF,$55,$49,$FF,$AA,$49,$FF,$FF,$49,$FF,$00,$24,$00,$55,$24,$00,$AA,$24,$00,$FF
      Data.b $24,$00,$00,$24,$24,$55,$24,$24,$AA,$24,$24,$FF,$24,$24,$00,$24,$49,$55,$24,$49
      Data.b $AA,$24,$49,$FF,$24,$49,$00,$24,$6D,$55,$24,$6D,$AA,$24,$6D,$FF,$24,$6D,$00,$24
      Data.b $92,$55,$24,$92,$AA,$24,$92,$FF,$24,$92,$00,$24,$B6,$55,$24,$B6,$AA,$24,$B6,$FF
      Data.b $24,$B6,$00,$24,$DB,$55,$24,$DB,$AA,$24,$DB,$FF,$24,$DB,$00,$24,$FF,$55,$24,$FF
      Data.b $AA,$24,$FF,$FF,$24,$FF,$00,$00,$00,$55,$00,$00,$AA,$00,$00,$FF,$00,$00,$00,$00
      Data.b $24,$55,$00,$24,$AA,$00,$24,$FF,$00,$24,$00,$00,$49,$55,$00,$49,$AA,$00,$49,$FF
      Data.b $00,$49,$00,$00,$6D,$55,$00,$6D,$AA,$00,$6D,$FF,$00,$6D,$00,$00,$92,$55,$00,$92
      Data.b $AA,$00,$92,$FF,$00,$92,$00,$00,$B6,$55,$00,$B6,$AA,$00,$B6,$FF,$00,$B6,$00,$00
      Data.b $DB,$55,$00,$DB,$AA,$00,$DB,$FF,$00,$DB,$00,$00,$FF,$55,$00,$FF,$AA,$00,$FF,$FF
      Data.b $00,$FF,$00,$00
      ColorTableend:
   EndDataSection
Now the program runs fine here also with PB 5.11.

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

Posted: Sat May 04, 2013 2:59 pm
by wilbert
Here's also another fixed palette I like myself.
It especially works well when dithering an image.

Code: Select all

Procedure ColorTable()
  
  ; This palette uses 6 levels of red, 10 levels of green and
  ; 4 levels of blue. It also supports 16 levels of gray.
  ; The total amount of palette entries is 254.
  
  *palette = AllocateMemory(1024)
  *c.RGBQUAD = *palette
  For r = 0 To 5
    For g = 0 To 9
      For b = 0 To 3
        *c\rgbBlue  = b * 255 / 3
        *c\rgbGreen = g * 255 / 9
        *c\rgbRed   = r * 255 / 5 
        *c + 4
      Next
    Next
  Next
  For i = 14 To 1 Step -1
    l = i * 255 / 15
    *c\rgbBlue  = l
    *c\rgbGreen = l
    *c\rgbRed   = l 
    *c + 4
  Next
  ProcedureReturn *palette 
  
EndProcedure
For those interested in what the palette looks like, this shows it

Code: Select all

PaletteImage = CreateImage(#PB_Any, 122, 222, 32 | #PB_Image_Transparent)
StartDrawing(ImageOutput(PaletteImage))
DrawingMode(#PB_2DDrawing_AllChannels)
Box(0, 0, 120, 220, RGBA(0, 0, 0, 255))
Box(70, 200, 49, 19, RGBA(0, 0, 0, 0))
For r = 0 To 5
  For g = 0 To 9
    For b = 0 To 3
      c = RGBA(r * 255 / 5, g * 255 / 9, b * 255 / 3, 255)
      Box((b & 1) * 60 + r * 10, (b >> 1) * 100 + g * 10, 9, 9, c)
    Next
  Next
Next
For i = 0 To 13
  l = (14 - i) * 255 / 15
  c = RGBA(l, l, l, 255)
  Box((i % 7) * 10, 200 + Int(i / 7) * 10, 9, 9, c)
Next
Line(0, 0, 120, 1, RGBA(0, 0, 0, 255))
Line(0, 0, 1, 220, RGBA(0, 0, 0, 255))
StopDrawing()

OpenWindow(0, 0, 0, 140, 240, "6-10-4 Palette", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ImageGadget(0, 10, 10, 120, 220, ImageID(PaletteImage))
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

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

Posted: Sat May 04, 2013 7:50 pm
by luis
Doesn't PB now already calculate an optimal palette using quantization (NeuQuant algorithm) when reducing a 24 bit image to 8 bit ?

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

Posted: Sat May 04, 2013 7:54 pm
by Fred
It should.

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

Posted: Sat May 04, 2013 8:07 pm
by wilbert
luis wrote:Doesn't PB now already calculate an optimal palette using quantization (NeuQuant algorithm) when reducing a 24 bit image to 8 bit ?
Of course it does :)

For me it's just childhood memories.
8 bit computers with a fixed palette, a programmable sound generator and a cpu running at 3.5 MHz.
I can't help it but I still like those fixed palettes. :shock:

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

Posted: Sun May 05, 2013 12:42 am
by Little John
luis wrote:Doesn't PB now already calculate an optimal palette using quantization (NeuQuant algorithm) when reducing a 24 bit image to 8 bit ?
Fred wrote:It should.
But it only can do so when saving the image to disk, right?

For a future project that I've planned, it will be very advantageous when I convert images to 8 bit in memory (before doing some more stuff with them).

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

Posted: Sun May 05, 2013 12:49 am
by luis
wilbert wrote: I can't help it but I still like those fixed palettes. :shock:

I understand :)

About palettes (and palette rotation): I found this old demo I made in 1994 in turbo assembler (borland)

[image removed]

This one the same year, nothing to do with palettes but really cool (I implemented the distortion effect of the sphere reading something about newton lenses in a book of physics and I wrote the asm code for that!)

[image removed]

80286 and VGA required !
Then I gradually stopped coding in ASM and now I almost forgot everything :oops:
I run them using dosbox and captured the gifs using this -> http://www.purebasic.fr/english/viewtop ... 27&t=54388 :P

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

Posted: Sun May 05, 2013 12:52 am
by luis
Little John wrote: But it only can do so when saving the image to disk, right?
Oh, right, only a few plugins are supported, I forgot.
Little John wrote: For a future project that I've planned, it will be very advantageous when I convert images to 8 bit in memory (before doing some more stuff with them).

Try to look at this one too then -> http://www.purebasic.fr/english/viewtop ... 12&t=39606

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

Posted: Sun May 05, 2013 5:33 am
by wilbert
luis wrote:This one the same year, nothing to do with palettes but really cool (I implemented the distortion effect of the sphere reading something about newton lenses in a book of physics and I wrote the asm code for that!)
Nice examples :D
I remember palette rotation.
It was used quite often when you had to wait for something that was loading.

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

Posted: Sun May 05, 2013 8:32 am
by Little John
luis wrote:Try to look at this one too then -> http://www.purebasic.fr/english/viewtop ... 12&t=39606
I think that is what I've been looking for, especially since it is cross-platform. Many thanks!

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

Posted: Sat Jan 28, 2017 1:18 am
by netmaestro
Updated the posted code to work correctly with PB 5.5x and later. Thanks to Little John for providing me with an unpacked color table.

When I tried this code it wouldn't produce an image at all, which was confusing because it's always worked fine before. I went through it line by line until I came across this:

Code: Select all

 \bfType = PeekW(@"BM")
which of course doesn't work under unicode. Anyway, it's working again.