[PB5.40beta3x86] CreateImage with white background fails

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
Didelphodon
PureBasic Expert
PureBasic Expert
Posts: 448
Joined: Sat Dec 18, 2004 11:56 am
Location: Vienna - Austria
Contact:

[PB5.40beta3x86] CreateImage with white background fails

Post 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.
Go, tell it on the mountains.
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: [PB5.40beta3x86] CreateImage with white background fails

Post by Little John »

Same behaviour here with the x64 version of PB 5.40 beta 3.
User avatar
kenmo
Addict
Addict
Posts: 1967
Joined: Tue Dec 23, 2003 3:54 am

Re: [PB5.40beta3x86] CreateImage with white background fails

Post 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?
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8433
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: [PB5.40beta3x86] CreateImage with white background fails

Post 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
BERESHEIT
User avatar
Didelphodon
PureBasic Expert
PureBasic Expert
Posts: 448
Joined: Sat Dec 18, 2004 11:56 am
Location: Vienna - Austria
Contact:

Re: [PB5.40beta3x86] CreateImage with white background fails

Post 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. :-)
Last edited by Didelphodon on Thu Sep 17, 2015 1:03 pm, edited 1 time in total.
Go, tell it on the mountains.
User avatar
kenmo
Addict
Addict
Posts: 1967
Joined: Tue Dec 23, 2003 3:54 am

Re: [PB5.40beta3x86] CreateImage with white background fails

Post 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 :)
User avatar
Michael Vogel
Addict
Addict
Posts: 2677
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: [PB5.40beta3x86] CreateImage with white background fails

Post 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 :)
User avatar
kenmo
Addict
Addict
Posts: 1967
Joined: Tue Dec 23, 2003 3:54 am

Re: [PB5.40beta3x86] CreateImage with white background fails

Post 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
Fred
Administrator
Administrator
Posts: 16681
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: [PB5.40beta3x86] CreateImage with white background fails

Post by Fred »

Moved to feature and request
Post Reply