Page 1 of 2

Imagery to Alpha

Posted: Mon Jul 12, 2010 6:13 pm
by starax
Hi folks,

I see that it's possible to draw shapes to an alpha channel, but is it possible to draw images to an alpha channel?

Basically I need to be able to transfer either the red,green or blue channel of an image to the the alpha channel of another image.

Or to be even more clear - I'm looking to create a utility that will transfer a specular map stored in a texture to the alpha channel of a another texture. Unity 3D users will understand why. :)

I know that I could set each alpha pixel using Plot(), but that's way too slow. So unless there's a way to draw images into the alpha channel then I fear my only solution will be to access the image buffer directly... Ugh.. scary..

Re: Imagery to Alpha

Posted: Mon Jul 12, 2010 6:33 pm
by Trond

Code: Select all

DrawingMode(#PB_2DDrawing_AlphaChannel)
DrawImage(ImageID(I), 0, 0)
For separating the alpha channels you will probably have to use the plot way or access the image buffer directly.

Re: Imagery to Alpha

Posted: Mon Jul 12, 2010 6:53 pm
by starax
Trond wrote:

Code: Select all

DrawingMode(#PB_2DDrawing_AlphaChannel)
DrawImage(ImageID(I), 0, 0)
I had already tried this approach but it seems that only the alpha channel from the source image is copied to the alpha channel of the destination image. So in my situation the alpha channel in the source images doesn't contain any data at all. Only the red, green or blue channels contain the data that I want to transfer to the alpha channel. Doesn't really matter which one as they all contain the exact same data.

Re: Imagery to Alpha

Posted: Mon Jul 12, 2010 10:11 pm
by Fred
Please note than since 4.40, Plot() isn't that slow anymore, so it could worth a try.

Re: Imagery to Alpha

Posted: Mon Jul 12, 2010 11:29 pm
by netmaestro
Why not post a couple images and tell the desired results, let us have a play with it.

Re: Imagery to Alpha

Posted: Tue Jul 13, 2010 2:23 am
by Fluid Byte
Fred wrote:Please note than since 4.40, Plot() isn't that slow anymore, so it could worth a try.
It's still very slow and rather useless. Use Box() instead (can be used outside "drawing area" as well).

Code: Select all

InitSprite()
OpenWindow(0,0,0,640,480,"void",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0),0,0,640,480,0,0,0)
LoadSprite(0,#PB_Compiler_Home + "Examples\Sources\Data\Background.bmp")

IW = SpriteWidth(0) - 1 : IH = SpriteHeight(0) - 1

StartTime = ElapsedMilliseconds()

StartDrawing(SpriteOutput(0))
For x=0 To IW
	For y=0 To IH
		Plot(x,y,Point(x,y))
	Next
Next
StopDrawing()

MessageRequester("PLOT()","Time: " + Str(ElapsedMilliseconds() - StartTime) + " Ms",64)

StartTime = ElapsedMilliseconds()

StartDrawing(SpriteOutput(0))
For x=0 To IW
	For y=0 To IH
		Box(x,y,1,1,Point(x,y))
	Next
Next
StopDrawing()

MessageRequester("BOX()","Time: " + Str(ElapsedMilliseconds() - StartTime) + " Ms",64)

Re: Imagery to Alpha

Posted: Tue Jul 13, 2010 7:06 am
by Demivec
Fluid Byte wrote:
Fred wrote:Please note than since 4.40, Plot() isn't that slow anymore, so it could worth a try.
It's still very slow and rather useless. Use Box() instead (can be used outside "drawing area" as well).
@FluidByte: Interesting idea. My comparisons came up roughly 159x faster with Box() than with Plot(). I never would have guessed it. Thanks for the heads up.

Re: Imagery to Alpha

Posted: Tue Jul 13, 2010 7:15 am
by kernadec
ih,

code box with Two different speed ????? Behavior..
Multiple running and different time.
good day

Code: Select all

OpenWindow(0,0,0,640,480,"void",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)

StartTime = ElapsedMilliseconds()

StartDrawing(WindowOutput(0))
For x=0 To 100
  For y=0 To 100
    ; Plot(x,y,Point(x,y))
    Box(x,y,1,1,Point(x,y))
  Next
Next
StopDrawing()

MessageRequester("PLOT()","Time: " + Str(ElapsedMilliseconds() - StartTime) + " Ms",64)

StartTime = ElapsedMilliseconds()

StartDrawing(WindowOutput(0))
For x=0 To 100
  For y=0 To 100
    Box(x,y,1,1,Point(x,y))
  Next
Next
StopDrawing()

MessageRequester("BOX()","Time: " + Str(ElapsedMilliseconds() - StartTime) + " Ms",64)

Re: Imagery to Alpha

Posted: Tue Jul 13, 2010 7:47 am
by starax
Fred wrote:Please note than since 4.40, Plot() isn't that slow anymore, so it could worth a try.
I actually did it with Plot() before asking on the forum, the process was too slow. Plot would be okay if I was working with small images, but I'm dealing with images as large as 4096*4096.

I never really assumed that it was Purebasic's plot that was slow, but rather that it was the process of reading and writing individual pixels with the CPU that was slow.


Edit:

When I first tried it with Plot() I was using an older version of Purebasic. :oops: Just tried it again with the latest version and it's great!!

Re: Imagery to Alpha

Posted: Tue Jul 13, 2010 8:09 am
by starax
Fluid Byte wrote:
Fred wrote:Please note than since 4.40, Plot() isn't that slow anymore, so it could worth a try.
It's still very slow and rather useless. Use Box() instead (can be used outside "drawing area" as well).
[/code]
Seems drawing to a window produces unpredictable timing results. Try drawing to an image.

When drawing to an image with your test I found Plot() to be faster than Box().

Re: Imagery to Alpha

Posted: Tue Jul 13, 2010 8:43 am
by starax
Update:

I've realized I was using an older version of Purebasic when I first tried Plot(). :oops: Plot is fine with the latest version.

Problem solved :)

Re: Imagery to Alpha

Posted: Tue Jul 13, 2010 11:47 am
by Fluid Byte
What the hell ...

The reason Plot() is so slow is actually the use of Point() :!:

Without this command Plot() is faster than Box():

Code: Select all

InitSprite()
OpenWindow(0,0,0,640,480,"void",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0),0,0,640,480,0,0,0)
LoadSprite(0,#PB_Compiler_Home + "Examples\Sources\Data\Background.bmp")

IW = SpriteWidth(0) - 1 : IH = SpriteHeight(0) - 1

StartTime = ElapsedMilliseconds()

StartDrawing(SpriteOutput(0))
For x=0 To IW
   For y=0 To IH
      Plot(x,y,#Red)
   Next
Next
StopDrawing()

MessageRequester("PLOT()","Time: " + Str(ElapsedMilliseconds() - StartTime) + " Ms",64)

StartTime = ElapsedMilliseconds()

StartDrawing(SpriteOutput(0))
For x=0 To IW
   For y=0 To IH
      Box(x,y,1,1,#Red)
   Next
Next
StopDrawing()

MessageRequester("BOX()","Time: " + Str(ElapsedMilliseconds() - StartTime) + " Ms",64)
I'm confused ... :?

Re: Imagery to Alpha

Posted: Tue Jul 13, 2010 12:30 pm
by starax
Fluid Byte wrote:What the hell ...

The reason Plot() is so slow is actually the use of Point() :!:

Without this command Plot() is faster than Box():


I'm confused ... :?
Yeah strange... Point() must not like sprites. It seems fine with images. Plot(x,y,Point(x,y)) is faster than Box(x,y,1,1,Point(x,y)) when drawing into a image.

Re: Imagery to Alpha

Posted: Tue Jul 13, 2010 1:11 pm
by starax
I think there's a relationship problem with Plot() and Point() when used with sprites. It becomes more apparent when dealing with large sprites.

The code below will crash.

Code: Select all

InitSprite()
OpenWindow(0,0,0,640,480,"void",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0),0,0,640,480,0,0,0)

CreateSprite(0,512,512)
IW = SpriteWidth(0) - 1 : IH = SpriteHeight(0) - 1


StartDrawing(SpriteOutput(0))
For x=0 To IW
  For y=0 To IH
    
    Plot(x,y,Point(1,1))

   Next
Next
StopDrawing()

It just manages to complete before crashing if the sprites dimensions are reduced to 128*128

Re: Imagery to Alpha

Posted: Tue Jul 13, 2010 5:12 pm
by Thorium
starax wrote: I fear my only solution will be to access the image buffer directly... Ugh.. scary..
Dont be afraid about directly accessing the image buffer. PB comes with nativ support for that, and it's not that hard if you done it just once.

Here is a very simple example that copies the red channel of the source image to the alpha channel of the destination image by directly accessing the image buffers. It's only a example to show you that it's not that scary actualy.

Code: Select all

EnableExplicit

Structure Pixel_BGRA
  Blue.a
  Green.a
  Red.a
  Alpha.a
EndStructure

Procedure CopyRed2Alpha(SourceImage.i, DestImage.i)
  
  Protected.i x, y, SourcePitch, DestPitch, Width, Height, SourceBuffer, DestBuffer
  Protected.Pixel_BGRA *SourcePixel, *DestPixel
  
  StartDrawing(ImageOutput(SourceImage))
  SourceBuffer = DrawingBuffer()
  SourcePitch  = DrawingBufferPitch()
  StopDrawing()
  
  StartDrawing(ImageOutput(DestImage))
  DestBuffer = DrawingBuffer()
  DestPitch  = DrawingBufferPitch()
  StopDrawing()
  
  Width  = ImageWidth(SourceImage)
  Height = ImageHeight(SourceImage) - 1
  
  For y = 0 To Height
    
    *SourcePixel = SourceBuffer + (SourcePitch * y)
    *DestPixel   = DestBuffer + (DestPitch * y)
    
    For x = 1 To Width
      
      *DestPixel\Alpha = *SourcePixel\Red
      *SourcePixel + 4
      *DestPixel + 4
      
    Next
    
  Next
  
EndProcedure