Page 1 of 1

Copying Images

Posted: Sat Mar 20, 2010 11:48 pm
by toledo
I have been reading through this forum for the last month and also the help topics in the program and I am so stuck. I can't even get started.
I want to:
- write a program that lets you include a bitmap pic in the compiled program
- copy that pic to a hidden buffer so that changes can be made to the pic before it's displayed
- and draw the final pic to the window without using an image gadget

I don't want to draw the final pic to image gadgets because image gadgets cover buttons when the window paints

Heres my Common.pb code:

Code: Select all

; PureBasic Visual Designer v3.95 build 1485 (PB4Code)

;- Window Constants
;
Enumeration
  #SkinTest
EndEnumeration

;- Gadget Constants
;
Enumeration
  #iNewPic
  #ScrollX
  #ScrollY
  #bEnter
  #Chat
  #Entry
  #Slider
  #Back
  #DouBuf
EndEnumeration

;- Image Plugins

;- Image Globals
Global Image0
Global Image1
Global Image2

;- Catch Images
Image0 = CatchImage(0, ?Image0)
Image1 = CatchImage(1, ?Image1)
Image2 = CatchImage(2, ?Image2)

;- Images
DataSection
Image0:
  IncludeBinary ""
Image1:
  IncludeBinary "C:\SkinTest\Skin.bmp"
Image2:
  IncludeBinary ""
EndDataSection

Procedure Open_SkinTest()
  If OpenWindow(#SkinTest, 359, 105, 561, 288, "Skin Test",  #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
    If CreateGadgetList(WindowID(#SkinTest))
      ImageGadget(#iNewPic, 10, 10, 272, 216, Image0)
      ScrollBarGadget(#ScrollX, 10, 226, 272, 16, 0, 100, 33)
      ScrollBarGadget(#ScrollY, 280, 10, 16, 216, 0, 100, 33, #PB_ScrollBar_Vertical)
      ButtonGadget(#bEnter, 240, 250, 57, 20, "Enter")
      EditorGadget(#Chat, 10, 10, 289, 235)
      StringGadget(#Entry, 10, 250, 219, 19, "")
      TrackBarGadget(#Slider, 310, 250, 246, 25, 0, 100)
      ImageGadget(#Back, 0, 560, 562, 288, Image1)
      ImageGadget(#DouBuf, 0, 560, 807, 557, Image2)
    EndIf
  EndIf
EndProcedure
and heres my Skin.pb code

Code: Select all

; PureBasic Visual Designer v3.95 build 1485 (PB4Code)

IncludeFile "Common.pb"

Open_SkinTest()

;copy image from Back (later will be input from a file) to DouBuf
StartDrawing(ImageOutput(Image2) )
  DrawImage(ImageID(Image1),0,0)
StopDrawing()

Repeat ; Start of the event loop
  
  Event = WaitWindowEvent() ; This line waits until an event is received from Windows
  
  WindowID = EventWindow() ; The Window where the event is generated, can be used in the gadget procedures
  
  GadgetID = EventGadget() ; Is it a gadget event?
  
  EventType = EventType() ; The event type
  
  ;You can place code here, and use the result as parameters for the procedures
  
  If Event = #PB_Event_Gadget
    
    If GadgetID = #iNewPic
      
    ElseIf GadgetID = #ScrollX
      
    ElseIf GadgetID = #ScrollY
      
    ElseIf GadgetID = #bEnter
      
    ElseIf GadgetID = #Chat
      
    ElseIf GadgetID = #Entry
          ;temporary code To test the concept of drawing from the Buffer To the screen
          ;copy image from DouBuf to #SkinTest
          StartDrawing(ImageOutput(Image2) )
          DrawImage(ImageID(Image1),0,0)
          StopDrawing()
  
    ElseIf GadgetID = #Slider
      
    ElseIf GadgetID = #Back
      
    ElseIf GadgetID = #DouBuf
      
    EndIf
    
  EndIf
  
Until Event = #PB_Event_CloseWindow ; End of the event loop

End
;
Can anybody help me? Is it even possible to do what I want to do?

Also, the compiler says CreateGadgetList was depreciated. So I took that line out and the error went away. Is that really all I had to do?

Re: Copying Images

Posted: Sun Mar 21, 2010 12:09 am
by Kaeru Gaman
I don't want to draw the final pic to image gadgets because image gadgets cover buttons when the window paints
use an ImageGadget and deactivate it, then the ImageGadget is a background.
write a program that lets you include a bitmap pic in the compiled program
you can include a BMP into the exe while compiling. use IncludeBinary.
catch the Image using CatchImage, copy it to a second image using CopyImage.
draw what you want on the second image, you can restore it by copying it again.
assign it to the ImageGadget again when you have applied changes.

Re: Copying Images

Posted: Mon Mar 22, 2010 9:36 am
by toledo
use an ImageGadget and deactivate it, then the ImageGadget is a background.
If I do that, will my controls be hidden everytime part of the window is covered and then uncovered?

Also, is it better to use a deactivated imagegadget for a background than it is to use the window background? I'll do it if it is. But I already figured out how to copy from an imagegadget to the window's background and I don't yet know how to copy part of an image from one imagegadget to another imagegadget with CopyImage.

Can you give me a code example of how to copy just a 20x20 pixel area of #Back to #DouBuf using CopyImage?

Re: Copying Images

Posted: Mon Mar 22, 2010 9:57 am
by c4s
I noticed that if you have a deactivated ImageGadget, a button over it and then change the used image often, the button will flicker and mostly be invisible.

So using a deactivated ImageGadget isn't always the best. But when you don't use an ImageGadget you have to redraw the window background if it gets invalid, right?
Seems to be pretty tricky...I'm also interested in a nice solution.

Re: Copying Images

Posted: Mon Mar 22, 2010 1:25 pm
by Kaeru Gaman
c4s wrote:I noticed that if you have a deactivated ImageGadget, a button over it and then change the used image often, the button will flicker and mostly be invisible.
I did not believe it was that bad, I made a test and the buttons vanished completely...
so you're right, it's of no use.

redrawing "manually" on #WM_PAINT may lead to some flicker, too, but I did not test this yet.
would be some screwing with a callback to handle it properly, to redraw the back manually and make Windows redraw the buttons afterwards.

there also was a solution for backgrounds using an API function to set the window's background image property (Win only).
seen it some time ago, must be somewhere in this forums. maybe this would work best to let the OS fully handle the redrawings.
Can you give me a code example of how to copy just a 20x20 pixel area of #Back to #DouBuf using CopyImage?
you can't use CopyImage for that, use DrawImage.
create #DouBuf in the size you finally want it, Draw #Back on it with coordinates ( - XOffs, - YOffs )
#DouBuf
if you want some DoubleBuffering Stuff with appropriate framerate, better use a WindowedScreen (no gadgets on it possible, tho)
an Image is only suitable for framerates of 20 FpS max 25 FpS.

Re: Copying Images

Posted: Mon Mar 22, 2010 8:55 pm
by netmaestro
But when you don't use an ImageGadget you have to redraw the window background if it gets invalid, right?
Are you on Windows? If so, a better approach is to use a background brush:

Code: Select all

  hBrush = CreatePatternBrush_( ImageID(<>) )
  SetClassLongPtr_(WindowID(<>), #GCL_HBRBACKGROUND, hBrush)
  InvalidateRect_(WindowID(<>), 0, 1)
That's all there is to it, Windows will manage repainting the background without flicker from here on in.

Re: Copying Images

Posted: Mon Mar 22, 2010 9:14 pm
by Trond
Redrawing the image on repaint events is rather simple:

Code: Select all

OpenWindow(0, 0, 0, 512, 384, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_Repaint
      StartDrawing(WindowOutput(0))
        ; DrawImage(ImageID(0), 0, 0) ; use this to draw an image
        ; I want to draw a box instead:
        color = RGB(WindowWidth(0)/5, 255-WindowHeight(0)/4, WindowHeight(0)/4)
        Box(0, 0, WindowWidth(0), WindowHeight(0), color)
      StopDrawing()
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver

Re: Copying Images

Posted: Mon Mar 22, 2010 9:26 pm
by Kaeru Gaman
@netmaestro

now... how about altering the image on-the-fly...?

full procedure again?
the brush has to be newly created, right?
would recreating the brush + invalidating the window be sufficent?

... oh, and additional... does the invalidate only get visible on the next Event-processing?

Re: Copying Images

Posted: Mon Mar 22, 2010 9:28 pm
by netmaestro
Yes, you'd need to re-execute all 3 lines. It's very fast though, a couple of milliseconds at most.

Re: Copying Images

Posted: Mon Mar 22, 2010 10:02 pm
by toledo

Code: Select all

  hBrush = CreatePatternBrush_(ImageID(<>)
  SetClassLongPtr_(WindowID(<>), #GCL_HBRBACKGROUND, hBrush)
  InvalidateRect_(WindowID(<>), 0, 1)
Where do I put this code? And do I have to change ImageID to #Back or anything like that?

Re: Copying Images

Posted: Mon Mar 22, 2010 10:58 pm
by netmaestro
Right after you open the window is fine. And you don't need a constant for the image number, that's a matter of your preference. But something like #Back is a good idea.

Re: Copying Images

Posted: Tue Mar 23, 2010 12:07 am
by toledo
So ImageID should be changed to #Back (from the code example I posted)?
And that's the only change I need to make?

Re: Copying Images

Posted: Tue Mar 23, 2010 12:45 am
by netmaestro
It would be:

Code: Select all

hBrush = CreatePatternBrush_( ImageID(#Back) )

Re: Copying Images

Posted: Tue Mar 23, 2010 10:11 pm
by toledo
Thankyou very much everybody, especially netmaestro. With your help, I was able to get the screen to redraw. Works like magic.

There are still some problems that I'll have try to tackle later. Like the buttons and other gadgets don't redraw after the window is covered and then uncovered. And all of the gadgets have a grey background color that can't be changed. But I'll try to tackle that later.

For now, I still have to write my software in a timely manner and I've gotten a bit behind. I've been using RealBasic and I'm familiar with it. So I need to stick with it for now.

But I have heard a lot of good things about PureBasic. I've even heard that it's faster and more stable than RealBasic. I just don't have the time right now to pursue it. I'll have to come back to it later.

If you have any advice for me on PureBasic, I'd love to hear it.