Page 1 of 1

How to Replace RGB(0, 0, 0) to Other Color by DrawImage()?

Posted: Sat Sep 07, 2013 1:01 am
by Benares
How to Replace RGB(0, 0, 0) to Other Color by DrawImage() ?

Re: How to Replace RGB(0, 0, 0) to Other Color by DrawImage(

Posted: Sat Sep 07, 2013 2:52 am
by IdeasVacuum
Well, one way is to find the pixels that are RGB(0,0,0) using Point(x,y), then changing them to the colour required using Plot(x,y,MyColour). So, If you have an image that is 100 x 100, something like this:

Code: Select all

StartDrawing(ImageOutput(#MyImage)) 

   For x = 0 To 99
   
           For y = 0 To 99
           
                        iColour = Point(x,y)
                     If(iColour = RGB(0,0,0) : Plot(x,y,RGB(255,255,255)) : EndIf
           Next y
   Next x

StopDrawing()

Re: How to Replace RGB(0, 0, 0) to Other Color by DrawImage(

Posted: Sat Sep 07, 2013 1:51 pm
by Benares
Thank You, but I need read thousands of pictures, so I'm afraid I have no efficiency.

Re: How to Replace RGB(0, 0, 0) to Other Color by DrawImage(

Posted: Sat Sep 07, 2013 2:06 pm
by ts-soft

Code: Select all

Procedure FilterCallback(x, y, SourceColor, DestColor)
  If SourceColor = RGB(0, 0, 0) : SourceColor = RGB(255, 255, 255) : EndIf
  ProcedureReturn SourceColor
EndProcedure

CreateImage(0, 100, 100)
StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_CustomFilter)      
CustomFilterCallback(@FilterCallback())
For x = 0 To 99
  
  For y = 0 To 99
    If y % 2
      Plot(x, y, RGB(0, 0, 0))
    Else
      Plot(x, y, RGB(128, 128, 128))
    EndIf  
  Next
Next

StopDrawing()

OpenWindow(0, #PB_Ignore, #PB_Ignore, 200, 200, "")
ImageGadget(0, 50, 50, 100, 100, ImageID(0))

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

Re: How to Replace RGB(0, 0, 0) to Other Color by DrawImage(

Posted: Sat Sep 07, 2013 3:03 pm
by netmaestro
@ts-soft: Looks like it should be Plot(y, x..[] based on your loops. It's matterless here as w and h are the same but as soon as they aren't there will be a crash.

Re: How to Replace RGB(0, 0, 0) to Other Color by DrawImage(

Posted: Sat Sep 07, 2013 8:36 pm
by luis
netmaestro wrote:@ts-soft: Looks like it should be Plot(y, x..[] based on your loops.
Uh ? Why ? Looks ok to me.

Re: How to Replace RGB(0, 0, 0) to Other Color by DrawImage(

Posted: Sat Sep 07, 2013 8:43 pm
by netmaestro
Because x is used for the outer loop and Plot() is xloc,yloc. See if this works without using Plot(y,x):

Code: Select all

Procedure FilterCallback(x, y, SourceColor, DestColor)
  If SourceColor = RGB(0, 0, 0) : SourceColor = RGB(255, 255, 255) : EndIf
  ProcedureReturn SourceColor
EndProcedure

CreateImage(0, 200, 100)
StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_CustomFilter)      
CustomFilterCallback(@FilterCallback())
For x = 0 To ImageHeight(0)-1
  
  For y = 0 To ImageWidth(0)-1
    If y % 2
      Plot(x, y, RGB(0, 0, 0))
    Else
      Plot(x, y, RGB(128, 128, 128))
    EndIf  
  Next
Next

StopDrawing()

OpenWindow(0, #PB_Ignore, #PB_Ignore, 200, 200, "")
ImageGadget(0, 50, 50, 100, 100, ImageID(0))

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
I don't think I've lost my mind on this (but it is possible) :D

Re: How to Replace RGB(0, 0, 0) to Other Color by DrawImage(

Posted: Sat Sep 07, 2013 8:46 pm
by luis
ehm... didn't you swap ImageWidth/ImageHeight ? :mrgreen:

As long as the ranges for the loops are correct, you can even swap the two loops (inner <-> outer) without consequences.

Re: How to Replace RGB(0, 0, 0) to Other Color by DrawImage(

Posted: Mon Sep 09, 2013 3:12 am
by Benares
Thanks

Re: How to Replace RGB(0, 0, 0) to Other Color by DrawImage(

Posted: Sun Nov 20, 2016 1:00 pm
by Keya
i have mild allergies to using Point/Plot over every pixel so have to use direct buffer manipulation but i ♥ it :D
This version supports 24 & 32bit images, doesn't matter if ReversedY as not relevant to this procedure. For 32bit pics it ignores the Alpha channel when comparing colors but preserves its original value (Alpha channel shouldn't change). Only fast addition and bitwise operations are used in the main loop, cos that's how we roll!

Code: Select all

Procedure ReplaceColor(hImg,  width, height, FindColor.l, ReplaceColor.l, bytesperpixel) ;bytesperpixel=3 or 4 (24/32bit)
  Protected x,y, *pixel.Long, steprow, FindColorOnly = FindColor & $00FFFFFF
  If hImg
    If StartDrawing(ImageOutput(hImg))
      *pixel = DrawingBuffer()
      steprow = (DrawingBufferPitch() - (width * bytesperpixel))
      For y = 1 To height
        For x = 1 To width          
          If (*pixel\l & $00FFFFFF) = FindColorOnly
            *pixel\l = ReplaceColor | (*pixel\l & $FF000000)             
          EndIf
          *pixel + bytesperpixel
        Next x
        *pixel + steprow
      Next y
      StopDrawing()
    EndIf 
  EndIf
EndProcedure
FindColor/ReplaceColor are expected to be in the same BGRA/RGBA order as the image (DrawingBufferPixelFormat()) - I think it's best that the program establishes that byte order, not this function, because chances are it already knows and therefore would be a wasteful doubleup. But anyway here's a conversion if needed!

Code: Select all

Procedure RGBAtoBGRA(pixel) ;and vice versa
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    !mov rax, [p.v_pixel]
  CompilerElse
    !mov eax, [p.v_pixel]
  CompilerEndIf  
  !bswap eax
  !ror eax, 8  ;restore Alpha
  ProcedureReturn ;eax/rax
EndProcedure

Re: How to Replace RGB(0, 0, 0) to Other Color by DrawImage(

Posted: Sun Nov 20, 2016 5:26 pm
by Michael Vogel
Just to add a code version including the DrawImage command... (please ignore the DummyImage procedure at the beginning, it's only to create an image for testing)

Code: Select all

#SwapBlackColor=1

Procedure DummyImage(id,x=0,y=0)

	Protected i,z
	#VoxMin=320 : #VoxMax=640 : #VoyMin=240 : #VoyMax=480

	If x=0 : x=#VoxMin+Random(#VoxMax-#VoxMin) : EndIf
	If y=0 : y=#VoyMin+Random(#VoyMax-#VoyMin) : EndIf

	z=CreateImage(id,x,y)
	If z
		If id=#PB_Any
			id=z
		EndIf
		StartDrawing(ImageOutput(id))
		DrawingMode(#PB_2DDrawing_AlphaBlend)
		For i=0 To x>>3
			Circle(Random(x),Random(y),Random(x>>4),$60000000|Random(#White))
		Next i
		StopDrawing()
		ProcedureReturn z
	EndIf

	ProcedureReturn #Null

EndProcedure
Procedure FilterCallback(x,y,SourceColor,DestColor)

	If SourceColor&$FFFFFF
		ProcedureReturn SourceColor
	Else
		ProcedureReturn #Red
	EndIf

EndProcedure

OpenWindow(0, 0, 0, 800,600, "-", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ImageGadget(1,0,0,800,600,0)

CreateImage(1,800,600)
DummyImage(2,640,400)

StartDrawing(ImageOutput(1))

If #SwapBlackColor
	DrawingMode(#PB_2DDrawing_CustomFilter)
	CustomFilterCallback(@FilterCallback())
EndIf

DrawImage(ImageID(2),80,100)
StopDrawing()

SetGadgetState(1,ImageID(1))

Repeat
	Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow