Page 1 of 1

SetDIBColorTable_() not working with PB 4.4 beta 2 - win x86

Posted: Sun Aug 30, 2009 12:11 pm
by srod
Hi,

I guess really I am aiming this at Freak having just read the latest PB blog regarding the new 2d drawing library etc.

Timo, I use the following to quickly convert an image to 8-bit gray-scale which works fine for my purposes with earlier versions of PB :

Code: Select all

ProcedureDLL ImageTo8bit(imageIn) 
  Protected imageOut, color, width, height, hdc
  Protected Dim colors.l(255) 
  width = ImageWidth(imageIn) : height = ImageHeight(imageIn)
  If width And height
    ;Set up a 'grey' colortable.
      For color = 0 To 255
        colors(color) = color + color<<8 + color<<16
      Next
    ;Create an 8-bit image.
      imageOut = CreateImage(#PB_Any, width, height, 8)
    If imageOut
      ;Convert the original image to gray-scale by simply setting the new image's color table and then copying the first image.
        hdc = StartDrawing(ImageOutput(imageOut))
        If hdc
          SetDIBColorTable_(hdc, 0, 256, @colors())
          DrawImage(ImageID(imageIN),0,0)
          StopDrawing()
        Else
          FreeImage(imageOut)
          imageOut = 0
        EndIf
    EndIf
  EndIf
  ProcedureReturn imageOut
EndProcedure
However, with the new image lib etc. the code is failing because SetDIBColorTable_() is failing with an 'invalid handle' error.

My unserstanding is that the new images are all DIB sections and of course the SetDIBColorTable_() is designed to work with these kinds of images - or at least I thought it was? :)

Any idea what might be afoot here? I could of course switch back to ddb's via api, but I would rather work with PB commands as much as possible.

Thanks.

Posted: Sun Aug 30, 2009 12:23 pm
by freak
The problem is that the new image drawing routines only work on 24bit or 32bit at the moment. So the 8bit image is converted to 24bit for the drawing.

The SetDIBColorTable_() does not work because a 24bit image has no color table.

Posted: Sun Aug 30, 2009 12:39 pm
by srod
Ah I see, yes that explains it. I have the code working now with a couple of additional lines thrown in to ensure that the 8-bit image receives the change of color table.

So, just to make sure I understand you correctly; the StartDrawing() command creates a temporary 24-bit image which is then selected into the DC etc? The result of all drawing is then copied back to the 8-bit image when appropriate?

If so, are there plans to offer up direct drawing to images with bitcounts < 24 without using these temporary images?

Thanks Timo.

**EDIT : By the way, GetDiBits_() seems to work fine with images created with PB 4.4.

Posted: Sun Aug 30, 2009 12:53 pm
by Trond
Sorry to distrupt, but why would one want 8-bit images?

Posted: Sun Aug 30, 2009 12:56 pm
by srod
Smaller size on disc and in resource sections for one.

Posted: Sun Aug 30, 2009 1:04 pm
by Trond
But you still could draw on it as 24-bit and save it as 8-bit.

Posted: Sun Aug 30, 2009 1:09 pm
by srod
Which isn't a problem now that I understand more of how the new drawing library is structured etc. The fact is that I am in need of setting the color table for an 8-bit image and now I understand why this process fails when using a HDC returned from StartDrawing() etc. means that I can proceed with what I was doing. :)

The extra steps I have had to employ because of the changes to PB's drawing library would not be required if the internal pixel routines could draw directly to an image of any depth rather than having to create a temporary 24-bit image first etc. Not that it is a big deal, but it is always nice to know how things work and why they sometimes fail to work. :)

Posted: Sun Aug 30, 2009 4:04 pm
by akj
@srod:

I would be grateful if you would provide the extra code used "to ensure that the 8-bit image receives the change of color table".

Posted: Sun Aug 30, 2009 8:37 pm
by srod
akj wrote:@srod:

I would be grateful if you would provide the extra code used "to ensure that the 8-bit image receives the change of color table".
I actually modified my code more than I needed to ensure the correct use of SetDIBColorTable_() so I won't post that code.

All you need do, however, is create a memory DC (with CreateCompatibleDC_()), select your image into this DC and then apply the SetDIBColorTable_() funtion to this DC etc. It works fine.

Posted: Sun Aug 30, 2009 8:53 pm
by netmaestro
I've modified my code here: http://www.purebasic.fr/english/viewtop ... 564#270564

to be compatible with PureBasic v4.40, you may find something useful in it.

Posted: Sun Aug 30, 2009 9:23 pm
by srod
netmaestro wrote:I've modified my code here: http://www.purebasic.fr/english/viewtop ... 564#270564

to be compatible with PureBasic v4.40, you may find something useful in it.
No, nothing useful in it whatsoever!

:twisted:

Posted: Sun Aug 30, 2009 9:27 pm
by freak
srod wrote:So, just to make sure I understand you correctly; the StartDrawing() command creates a temporary 24-bit image which is then selected into the DC etc? The result of all drawing is then copied back to the 8-bit image when appropriate?
Exactly.

> If so, are there plans to offer up direct drawing to images with bitcounts < 24 without using these temporary images?

I am not sure about that. Images < 24bit are only supported on Windows anyway, so it may be a bit much effort for a small benefit only.

> **EDIT : By the way, GetDiBits_() seems to work fine with images created with PB 4.4.

Yes, but the function is documented to work on DDBs only. So i am not sure if you can rely on this.

Posted: Sun Aug 30, 2009 9:31 pm
by srod
Thanks Freak, much appreciated.

On reflection I think that I would agree with your sentiments regarding drawing directly to 8-bit images etc. I have some idea of just how much work the new drawing library would have involved and so yes, so much work for so little gain when thinking about 8-bit images. I have to agree with you there.

Might be an idea to add a comment or two in the help manual about the use of these temporary 24-bit images etc. when StartDrawing() is used on an 8-bit image and so on. Might avoid a repetition of my question. :)