Thank you very much Steve for the update, so far I found no issues on my side (Windows7 Home).
@Petr
Your question 2.) about dithering to 256 colors, it's FUNCTION RemapImageFS&(), which is originated from my GuiTools Framework and used (with permission) in Steve's library. It does Floyd-Steinberg dithering of any given image using the current 256 color palette of the designated 8-bit destination image (or screen).
Note, SaveImage offers you a few options which Rho's Function doesn't have, all by itself. As per the notes inside the demo:
'CONST ConvertToStandard256Palette = 0
' Set the value to 0 (FALSE) to preserve the color information perfectly, using its default palette.
' If the CONST is set (TRUE), then we convert our colors to as close of a match as possible, while
' preserving the standard QB64 256-color palette.
' Commented here, simply to help folks know that it exists for use when converting a 32 bit image
' down to 256 colors, such as what the GIF routine has to do for us (GIFs are limited to 256 color images)
SaveImage comes prepackaged with a nice toggle CONST, which is rather quite ingenius, if I say so myself. ;)
When CONST ConvertToStandard256Palette = False, SaveImage tries its best to save your image palette as close to perfect as it can. This ends up producing a non-standard QB64 palette, where each number is remapped to whatever suits the image itself the best, to try and preserve the brightest and most vibrant image which is as true to the original, as possible.
When CONST ConvertToStandard256Palette = True, SaveImage dithers the original image so that it has to work with the original QB64 256 color palette, as it normally exists for us. This option is real useful if we want to use an image and then print on the screen, using our standard color palette.
With ConvertToStandard256Palette False, Color 40 might be a shade of some oddish purple, to help the picture look as close to the original as possible. When ConvertToStandard256Palette is False, COLOR 40 is going to be RED -- the same color which it always is for us, when we _LOADIMAGE (x, y, 256) a 256 color screen.
Note, all this is done and takes place in our helper FUNCTION here:
'This routine can benefit/be altered if the user sets a CONST or DIM SHARED variable name ConvertToStandard256Palette, as so:
' CONST ConvertToStandard256Palette = -1
' Set the value to 0 (FALSE) to preseve the color information perfectly, using its default palette.
' If the CONST is set (TRUE), then we convert our colors to as close of a match as possible, while
' preserving the standard QB64 256-color palette.
n
AS LONG 'number of times it appears DO 'get the palette and number of colors used _MEMGET m
(0), m
(0).OFFSET
+ o
, t
'Get the colors from the original screen FOR i
= 0 TO colors
'check to see if they're in the existing palette we're making Pal(colors) = t
colors = colors + 1 'increment the index for the new color found
IF colors
> 255 THEN 'no need to check any further; it's not a normal QB64 256 color image Image32To256 = RemapImageFS(image&, I256)
EXIT FUNCTION 'and we're done, with 100% image compatability saved o = o + 4
' we might be working with a standard qb64 256 color screen
' check for that first
colors = colors - 1 'back up one, as we found our limit and aren't needing to set another
FOR i
= 0 TO colors
'comparing palette against QB64 256 color palette t = Pal(i)
IF NSCU
THEN 'it's not a standard QB64 256 color palette, but it's still less than 256 total colors. IF ConvertToStandard256Palette
THEN TI256 = RemapImageFS(image&, I256)
I256 = TI256 'replace with the new image
m
(1) = _MEMIMAGE(I256
) 'and point the mem block to the new image 'If we didn't change the palette above, we should work 100% with qb64's internal 256 color palette
o = 0
DO 'Get the colors, put them to a 256 color screen, as is _MEMGET m
(0), m
(0).OFFSET
+ o
+ 3, a
_MEMGET m
(0), m
(0).OFFSET
+ o
+ 2, r
_MEMGET m
(0), m
(0).OFFSET
+ o
+ 1, g
_MEMGET m
(0), m
(0).OFFSET
+ o
+ 0, b
o = o + 4
Image32To256 = I256
Rather than just calling Rho's dithering routine directly, instead SaveImage calls FUNCTION Image32To256 (image&), which does some serious decision making for us.
First, it determines if an image contains less than 256 colors to begin with. If so, there's no need to dither anything -- we have fewer colors than our possible palette limit already.
Then it determines if those 256 colors align to the standard QB64 palette values. If so, there's no need to shuffle the palette and make it hard to reference. It'll use the standard values that we'd normally see for a QB64 screen.
And then, only if it's necessary, it listens to what we told it wanted with ConvertToStandard256Palette = True/False, so it can dither down to either the best, or easiest, image to work with, as I described above).
You can use Rho's routine directly for dithering, if you want, but I'd recommend to use the FUNCTION Image32To256 for its helper functionality, if you want to create images for use inside QB64 itself. ;)