Page 1 of 1
[PB5.40beta3x86] CreateImage with white background fails
Posted: Tue Sep 15, 2015 2:41 pm
by Didelphodon
The following code should create an image with WHITE (RGBA(255,255,255,255)) as a pre-defined background-color saving it in your temp-folder ...
Code: Select all
img.i = CreateImage(#PB_Any, 400, 400, 32, RGBA(255,255,255,255))
ShowLibraryViewer("Image", img)
SaveImage(img, GetTemporaryDirectory() + "test.bmp")
CallDebugger
On my machine the LibraryViewer shows a gray image and the image in the temp-folder is black.
However, if one of the 255-values is modified the background-color option works perfectly, though.
Re: [PB5.40beta3x86] CreateImage with white background fails
Posted: Tue Sep 15, 2015 3:07 pm
by Little John
Same behaviour here with the x64 version of PB 5.40 beta 3.
Re: [PB5.40beta3x86] CreateImage with white background fails
Posted: Tue Sep 15, 2015 4:38 pm
by kenmo
At first it seems like a design flaw of the CreateImage function:
Code: Select all
Debug RGBA(255, 255, 255, 255)
Debug #PB_Image_Transparent
; Opaque white = $FFFFFFFF = -1 = #PB_Image_Transparent
So CreateImage sees Opaque white as #PB_Image_Transparent, and creates a black image with 0 alpha (save as PNG to see).
BUT this does match the documentation for CreateImage:
The back RGB() color used when the image is created. This color can be set to #PB_Image_Transparent to create an image with the alpha channel set to full transparent.
CreateImage only says to use an RGB (24-bit) color OR #PB_Image_Transparent, not an RGBA color (32-bit).
Maybe the documentation should be more clear?
Re: [PB5.40beta3x86] CreateImage with white background fails
Posted: Thu Sep 17, 2015 12:24 am
by netmaestro
CreateImage only says to use an RGB (24-bit) color OR #PB_Image_Transparent, not an RGBA color (32-bit).
I'm not sure I understand why this isn't clear. You use either one of: A control constant (only one exists for now, #PB_Image_Transparent); Or a three-byte color constant for the background color if you're applying a color. No RGBA values. You can pass #PB_Image_Transparent as a control parameter if you want a transparent background but no conflict arises from sharing a value with RGBA(255,255,255,255) because for that parameter you never pass an RGBA value that is intended to be a color. Colors are three bytes only as specified in the doc.
As far as the black background on a PNG image from using #PB_Image_Transparent I initially thought you might be on to something there when I viewed the image using the Windows 10 Photo app, but it only shows black there. The legacy Windows Photo Viewer shows it transparent as does this fairly straightforward code:
Code: Select all
img.i = CreateImage(#PB_Any, 256, 256, 32, #PB_Image_Transparent)
UsePNGImageEncoder():UsePNGImageDecoder()
SaveImage(img, GetTemporaryDirectory() + "test.png", #PB_ImagePlugin_PNG)
LoadImage(0, GetTemporaryDirectory() + "test.png")
OpenWindow(0,0,0,256,256,"")
SetWindowColor(0, RGB(255,255,223))
ImageGadget(0,0,0,256,256,ImageID(0))
Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: [PB5.40beta3x86] CreateImage with white background fails
Posted: Thu Sep 17, 2015 8:33 am
by Didelphodon
netmaestro wrote:CreateImage only says to use an RGB (24-bit) color OR #PB_Image_Transparent, not an RGBA color (32-bit).
I'm not sure I understand why this isn't clear. You use either one of: A control constant (only one exists for now, #PB_Image_Transparent); Or a three-byte color constant for the background color if you're applying a color. No RGBA values. You can pass #PB_Image_Transparent as a control parameter if you want a transparent background but no conflict arises from sharing a value with RGBA(255,255,255,255) because for that parameter you never pass an RGBA value that is intended to be a color. Colors are three bytes only as specified in the doc.
As far as the black background on a PNG image from using #PB_Image_Transparent I initially thought you might be on to something there when I viewed the image using the Windows 10 Photo app, but it only shows black there. The legacy Windows Photo Viewer shows it transparent as does this fairly straightforward code:
Code: Select all
img.i = CreateImage(#PB_Any, 256, 256, 32, #PB_Image_Transparent)
UsePNGImageEncoder():UsePNGImageDecoder()
SaveImage(img, GetTemporaryDirectory() + "test.png", #PB_ImagePlugin_PNG)
LoadImage(0, GetTemporaryDirectory() + "test.png")
OpenWindow(0,0,0,256,256,"")
SetWindowColor(0, RGB(255,255,223))
ImageGadget(0,0,0,256,256,ImageID(0))
Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow
Well, I have to confess that I definitely missed that "RGB()"-note in the docs. However, in my opinion in terms of an 32-Bit-image the constant to result in a totally transparent image ("#PB_Image_Transparent") should be "rgba(0,0,0,0)" which imho is the "mother of transparency" considering the other 255^3 possibilities for full visual transparency.

Re: [PB5.40beta3x86] CreateImage with white background fails
Posted: Thu Sep 17, 2015 12:45 pm
by kenmo
netmaestro wrote:I'm not sure I understand why this isn't clear. You use either one of: A control constant (only one exists for now, #PB_Image_Transparent); Or a three-byte color constant for the background color if you're applying a color. No RGBA values.
Sure, it is clear once you run into a problem and look back at the documentation. But at first, you might think that when you specify 32-bit depth, you can specify a 32-bit background color in the very next parameter. (I have fallen for this mistake before.)
I don't see any reason 32-bit CreateImage should ignore alpha in background colors, EXCEPT so you can pass in a 24-bit color value like #Red and have it show up opaque rather than transparent. But if the programmer knows they're dealing with 32-bit images anyway, you could just use a function like Opaque(#Red).
netmaestro wrote:As far as the black background on a PNG image from using #PB_Image_Transparent I initially thought you might be on to something there when I viewed the image using the Windows 10 Photo app, but it only shows black there.
Seen this before too. It's a feature of (some components of) the Windows OS. If it loads an image and every pixel is fully transparent, it assumes the alpha channel is invalid/unintended and makes them all opaque instead.
Well, I have to confess that I definitely missed that "RGB()"-note in the docs. However, in my opinion in terms of an 32-Bit-image the constant to result in a totally transparent image ("#PB_Image_Transparent") should be "rgba(0,0,0,0)"
I fully agree. It would be nice to allow RGBA values in CreateImage. #PB_Image_Transparent changing from $FFFFFFFF to $00000000 would be backwards compatible. (24-bit images would ignore any alpha of course.)
Maybe I will write a Feature Request and see what happens

Re: [PB5.40beta3x86] CreateImage with white background fails
Posted: Thu Sep 17, 2015 12:58 pm
by Michael Vogel
What I do when I need an alpha channel (to be added to jpg images etc.) is seen below:
Code: Select all
Procedure ImageAlphaPlane(Image,Alpha=0)
Protected *mem,size
Protected w,h
Protected TemporaryDC
Protected TemporaryBitmap.BITMAP
Protected TemporaryBitmapInfo.BITMAPINFO
w=ImageWidth(Image)
h=ImageHeight(Image)
size=w*h<<2
*mem=AllocateMemory(size)
If *mem
TemporaryDC=CreateDC_("DISPLAY",#NULL$,#NULL$,#Null)
GetObject_(ImageID(Image),SizeOf(BITMAP),TemporaryBitmap.BITMAP)
TemporaryBitmapInfo\bmiHeader\biSize=SizeOf(BITMAPINFOHEADER)
TemporaryBitmapInfo\bmiHeader\biWidth=TemporaryBitmap\bmWidth
TemporaryBitmapInfo\bmiHeader\biHeight=-TemporaryBitmap\bmHeight
TemporaryBitmapInfo\bmiHeader\biPlanes=1
TemporaryBitmapInfo\bmiHeader\biBitCount=32
TemporaryBitmapInfo\bmiHeader\biCompression=#BI_RGB
GetDIBits_(TemporaryDC,ImageID(Image),0,TemporaryBitmap\bmHeight,*mem,TemporaryBitmapInfo,#DIB_RGB_COLORS)
alpha<<24
While size
size-4
PokeL(*mem+size,PeekL(*mem+size)&$FFFFFF|alpha)
Wend
CreateImage(Image,w,h,32)
SetDIBits_(TemporaryDC,ImageID(Image),0,TemporaryBitmap\bmHeight,*mem,TemporaryBitmapInfo,#DIB_RGB_COLORS)
DeleteDC_(TemporaryDC)
EndIf
EndProcedure
CreateImage(0,200,200,24)
StartDrawing(ImageOutput(0))
Circle(100,100,50,#Blue)
Box(40,40,40,80,#Green)
Box(100,140,80,40,#Yellow)
StopDrawing()
CopyImage(0,1)
ImageAlphaPlane(1,100)
OpenWindow(0,0,0,400,200,"Increase image depth and set transparency")
;SetWindowColor(0,#Red); #Black,...
ImageGadget(0,0,0,200,200,ImageID(0))
ImageGadget(1,200,0,200,200,ImageID(1))
Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
Feel free to optimize the code or to create a feature request for an internal purebasic command

Re: [PB5.40beta3x86] CreateImage with white background fails
Posted: Thu Sep 17, 2015 2:24 pm
by kenmo
That's a useful way to add alpha to a 24-bit image. But the feature I'm asking for isn't a command to do that, it's just for CreateImage to accept background color alpha, in an image we already know is 32-bit.
Just for convenience. It's not an important request. There are plenty of ways to add a transparent background color AFTER calling CreateImage().
PS. Cross platform, less efficient function for your example:
Code: Select all
Procedure Make32BitImage(Source.i, Dest.i, Alpha.i = 255)
If CreateImage(Dest, ImageWidth(Source), ImageHeight(Source), 32)
If StartDrawing(ImageOutput(Dest))
DrawImage(ImageID(Source), 0, 0)
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0, 0, OutputWidth(), OutputHeight(), RGBA(0, 0, 0, Alpha))
StopDrawing()
EndIf
EndIf
EndProcedure
Re: [PB5.40beta3x86] CreateImage with white background fails
Posted: Thu Nov 19, 2015 12:55 pm
by Fred
Moved to feature and request