Linie zeichnen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Linie zeichnen

Beitrag von STARGÅTE »

@Velindos, Ja hab ich, aber ich bin auch Beta-Nutzer, deswegen ja neu ^^

@bobobo, jo danke für das down-date^^

@Velindos, das ImageGadget muss in diesem Fall deaktiviert werden, damit es keine eigenen Event empfängt/sendet, damit man über das Fenster die UP/DOWN Events bekommt.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Linie zeichnen

Beitrag von ts-soft »

STARGÅTE hat geschrieben:das mir GetGadgetAttribute(#Gadget, #PB_Canvas_Image) keine gültige Image-Nummer zurück gibt.
purebasic.chm hat geschrieben:Note: The returned value is only valid until changes are made to the gadget by resizing it or drawing to it, so it should only be used directly in a command like DrawImage() and not stored for future use
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Velindos
Beiträge: 598
Registriert: 15.11.2010 10:56

Re: Linie zeichnen

Beitrag von Velindos »

Hallo bobobo, du bist ja eine Wucht, DANKE! Funktioniert, wie bekomme ich die Linie noch dicker, ähnlich eines Marker-Stiftes etc.
Nochwas Stargate .. verstehe ich das richtig, das es sich um PB 4.6 beta in englisch handelt?
Gruss ... Velindos
Windows 7/8/8.1/10 (32/64-Bit) |Ubuntu 10.4 (64-Bit) |Purebasic 5.71 LTS (32/64-Bit)
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Linie zeichnen

Beitrag von STARGÅTE »

@TS-Soft:
Oke, das heißt, um den Inhalt eines CanvasGadget zu speichern, muss ich den Inhalt mit DrawImage() auf ein eigenes Image zeichen.

@Velindos
Die Linien bekommt man mit Line() nicht dicker ... dazu müsstest du selber mehrere Linien neeneinander zeichen, oder selbst eine Prozedure dafür schreiben.
>>verstehe ich das richtig, das es sich um PB 4.6 beta in englisch handelt?
Ja, zumindest die Hilfe ist in Englisch, da die deutsche Hilfe erst danach aktuallisiert wird.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Linie zeichnen

Beitrag von STARGÅTE »

EDIT: Hier mal das Beispiel von bobobo mit dicker Linie.

Code: Alles auswählen

Enumeration
  #Window
  #Gadget
  #Image
  #SaveImage
EndEnumeration

OpenWindow(#Window, 0, 0, 512, 512, "Fenster", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
ImageGadget(#Gadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window),0)
;CanvasGadget(#Gadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window))
DisableGadget(#Gadget,1)
Global ShowLine.i, Start.Point

CreateImage(#SaveImage, 512, 512)
StartDrawing(ImageOutput(#SaveImage))
Box(0,0,512,512,$FFFFFF)
StopDrawing()
CopyImage(#SaveImage,#Image)
SetGadgetState(#Gadget, ImageID(#Image))

Procedure ThickLineXY(X1.i, Y1.i, X2.i, Y2.i, Thickness.i, Color.i)
	Protected Length.i = Sqr((X2-X1)*(X2-X1)+(Y2-Y1)*(Y2-Y1))
	Protected I, DeltaX.i, DeltaY.i
	If Length = 0
		Circle(X1, Y1, Thickness/2, Color)
	Else
		For I = 0 To Length
			DeltaX = (X2-X1)*I/Length
			DeltaY = (Y2-Y1)*I/Length
			Circle(X1+DeltaX, Y1+DeltaY, Thickness/2, Color)
		Next
	EndIf
EndProcedure

Repeat
	
	Event = WaitWindowEvent()
	Debug event
	Select Event
			
		Case #PB_Event_CloseWindow
			End
			
			
		Case #WM_LBUTTONDOWN
			ShowLine = #True
			Start\X = WindowMouseX(#Window)
			Start\Y = WindowMouseY(#Window)
		Case #WM_MOUSEMOVE
			If ShowLine
				StartDrawing(ImageOutput(#Image))
				DrawImage(ImageID(#SaveImage), 0, 0)
				ThickLineXY(WindowMouseX(#Window), WindowMouseY(#Window), Start\X, Start\Y, 5, $000000)
				StopDrawing()
				SetGadgetState(#Gadget,ImageID(#Image))
			EndIf
		Case #WM_LBUTTONUP
			ShowLine = #False
			StartDrawing(ImageOutput(#SaveImage))
			ThickLineXY(WindowMouseX(#Window),WindowMouseY(#Window), Start\X, Start\Y, 5, $000000)
			StopDrawing()
			SetGadgetState(#Gadget,ImageID(#SaveImage))
			
	EndSelect
	
ForEver
PS: natürlich kann man sowas noch "exakter" machen (mit Kantenglättung usw.), aber ich denke das reicht dir ^^
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Velindos
Beiträge: 598
Registriert: 15.11.2010 10:56

Re: Linie zeichnen

Beitrag von Velindos »

Hallo Stargate, das funkt ja supi! Wusste nicht das mit der dicken Linie es so umfangreich ist, also nochmals "Danke" Jungs!
Gruss ... Velindos
Windows 7/8/8.1/10 (32/64-Bit) |Ubuntu 10.4 (64-Bit) |Purebasic 5.71 LTS (32/64-Bit)
Benutzeravatar
bobobo
jaAdmin
Beiträge: 3873
Registriert: 13.09.2004 17:48
Kontaktdaten:

Re: Linie zeichnen

Beitrag von bobobo »

einen noch
etwas erweitert durch einen Löschmodus mit rechter Maustaste

Code: Alles auswählen

Enumeration
  #Window
  #Gadget
  #Image
  #SaveImage
EndEnumeration

OpenWindow(#Window, 0, 0, 512, 512, "Fenster", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
ImageGadget(#Gadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window),0)
;CanvasGadget(#Gadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window))
DisableGadget(#Gadget,1)
Global ShowLine.i, Start.Point

CreateImage(#SaveImage, 512, 512)
StartDrawing(ImageOutput(#SaveImage))
  Box(0,0,512,512,$FFFFFF)
StopDrawing()
CopyImage(#SaveImage,#Image)
SetGadgetState(#Gadget, ImageID(#Image))

Procedure ThickLineXY(X1.i, Y1.i, X2.i, Y2.i, Thickness.i, Color.i)
  Protected Length.i = Sqr((X2-X1)*(X2-X1)+(Y2-Y1)*(Y2-Y1))
  Protected I, DeltaX.i, DeltaY.i
  If Length = 0
    Circle(X1, Y1, Thickness/2, Color)
  Else
    For I = 0 To Length
      DeltaX = (X2-X1)*I/Length
      DeltaY = (Y2-Y1)*I/Length
      Circle(X1+DeltaX, Y1+DeltaY, Thickness/2, Color)
    Next
  EndIf
EndProcedure

Repeat
  
  Event = WaitWindowEvent()
  Debug event
  Select Event
      
    Case #PB_Event_CloseWindow
      End
      
      
    Case #WM_RBUTTONDOWN
      Deleter = #True
      Start\X = WindowMouseX(#Window)
      Start\Y = WindowMouseY(#Window)
    Case #WM_LBUTTONDOWN
      ShowLine = #True
      Start\X = WindowMouseX(#Window)
      Start\Y = WindowMouseY(#Window)
    Case #WM_MOUSEMOVE
      If ShowLine
        StartDrawing(ImageOutput(#Image))
          DrawImage(ImageID(#SaveImage), 0, 0)
          ThickLineXY(WindowMouseX(#Window), WindowMouseY(#Window), Start\X, Start\Y, 5, $000000)
        StopDrawing()
        SetGadgetState(#Gadget,ImageID(#Image))
      EndIf
      If Deleter
        StartDrawing(ImageOutput(#Image))
          DrawImage(ImageID(#SaveImage), 0, 0)
          Circle(WindowMouseX(#Window), WindowMouseY(#Window), 10, $FFFFFF)
        StopDrawing()
        SetGadgetState(#Gadget,ImageID(#Image))
        CopyImage(#Image,#Saveimage)
      EndIf
    Case #WM_LBUTTONUP
      ShowLine = #False
      StartDrawing(ImageOutput(#SaveImage))
        ThickLineXY(WindowMouseX(#Window),WindowMouseY(#Window), Start\X, Start\Y, 5, $000000)
      StopDrawing()
      SetGadgetState(#Gadget,ImageID(#SaveImage))
    Case #WM_RBUTTONUP
      Deleter = #False
  EndSelect
ForEver
‮pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
Benutzeravatar
kernadec
Beiträge: 25
Registriert: 05.07.2009 17:51

Re: Linie zeichnen

Beitrag von kernadec »

Hallo

@ Stargate danken Ihnen für die Linien mit einer Dicke

guten Tag

Code: Alles auswählen

;###################################################################
;####         kernadec juin 2011 Forum français  ver 4.60 b3
;####   exemple canvas de dessin avec souris bouton Gauche relaché
;####                 et bouton droit annule              
;###################################################################
Enumeration
  #Window
  #Image0  
  #Image1
  #Scroll
  #canvas
  #menu0
  #menu1
  #menu2
  #menu3
  #menu4
  #menu5
  #menu6
  #menu7
  #menu8
EndEnumeration

Procedure ThickLineXY(X1.i, Y1.i, X2.i, Y2.i, Thickness.i, Color.i,rand.i) 
  ; Procedure épaisseur de : STARGATE  forum Purebasic Allemand
  Protected Length.i = Sqr((X2-X1)*(X2-X1)+(Y2-Y1)*(Y2-Y1)) 
  Protected I, DeltaX.i, DeltaY.i 
  If Length = 0 
    Circle(X1, Y1, Thickness/2, Color) 
  Else 
    For I = 0 To Length 
      DeltaX = (X2-X1)*I/Length 
      DeltaY = (Y2-Y1)*I/Length 
      If rand=0
        Circle(X1+DeltaX, Y1+DeltaY,Thickness/2, Color) 
      Else
        Circle(X1+DeltaX, Y1+DeltaY, Random(Thickness/2), Color) 
      EndIf  
    Next 
  EndIf
EndProcedure 
Procedure elipse(x0,y0,x1,y1,r1,r2,a1,a2,Thickness,color,rand.i)
  For i=0 To 359
    r3=(Sqr(Pow(x1,2)+Pow(y1,2)))
    x2.i=x0+r3*Cos(Radian(i))
    y2.i=y0+r3*Sin(Radian(i))
    If rand=0
      Circle(X2,Y2,Thickness/2,Color) 
    Else
      Circle(X2,Y2,Random(Thickness/2),Color) 
    EndIf
  Next i
EndProcedure 
titre$="CanvasGadget"
menu=2                 ; menu defaut
CreateImage(#Image0, 1000, 1000, 24)
CreateImage(#Image1, 1000, 1000, 24)
If OpenWindow(#Window, 0, 0,600,600,titre$, #PB_Window_SystemMenu | #PB_Window_ScreenCentered| #PB_Window_MinimizeGadget | #PB_Window_SizeGadget) 
  ScrollAreaGadget(#Scroll, 0, 0, 600,600, 1000, 1000, 30)         
  CanvasGadget(#canvas, 0, 0,  1000, 1000, #PB_Canvas_ClipMouse)
  SetWindowColor(#Window,#White) 
  SetGadgetColor(#Scroll,#PB_Gadget_BackColor,#White)
  SetGadgetAttribute(#Scroll,#PB_ScrollArea_X,200)
  SetGadgetAttribute(#Scroll,#PB_ScrollArea_Y,200)
  If CreateMenu(#menu0, WindowID(0))   
    MenuTitle("Choix")
    MenuItem(#menu1, "Ligne Thick Rand")
    MenuItem(#menu2, "Ligne Thick")
    MenuItem(#menu3, "Cercle")
    MenuItem(#menu4, "Cercle vide")
    MenuItem(#menu5, "Cercle vide Rand")
    MenuItem(#menu6, "Box")
    MenuItem(#menu7, "Point")
    MenuItem(#menu8, "Point rand")
  EndIf
  Repeat
    event=WaitWindowEvent()
    
    X = GetGadgetAttribute(#canvas, #PB_Canvas_MouseX)
    Y = GetGadgetAttribute(#canvas, #PB_Canvas_MouseY)
    StartDrawing(CanvasOutput(#canvas))
    If Clic_Gauche=#True
      If EventType() =  #PB_EventType_MouseMove
        DrawImage(ImageID(#Image0), 0, 0)
        DrawingMode(#PB_2DDrawing_AlphaBlend)              ; transparence avec couleur RGBA
        
        ; calcul des distances pixels entre DepartX,DepartY du debut et X,Y actuel = taille de l'élipse
        If x > DepartX:rx = x - DepartX:Else:rx = DepartX - x:EndIf       
        If y > DepartY:ry = y - DepartY:Else:ry = DepartY - y:EndIf
        If menu=1
          ThickLineXY(DepartX, DepartY, x, y, 25, lColor,1) 
          ;LineXY(DepartX, DepartY, x, y, color)            ; ligne simple
          FinX=x:FinY=y
        EndIf
        If menu=2
          ThickLineXY(DepartX, DepartY, x, y, 20, lColor,0) 
          FinX=x:FinY=y
        EndIf
        If menu=3
          Ellipse(DepartX, DepartY, rx, ry, color)
          FinX=x:FinY=y
        EndIf
        If menu=4
          elipse(DepartX,DepartY,x-DepartX,y-DepartY,r1,r2,a1,a2,16,lcolor,0)
          FinX=x:FinY=y
        EndIf
        If menu=5
          elipse(DepartX,DepartY,x-DepartX,y-DepartY,r1,r2,a1,a2,25,lcolor,1)
          FinX=x:FinY=y
        EndIf
        If menu=6
          Box(DepartX, DepartY,x-DepartX,y-DepartY,color) 
          FinX=x:FinY=y
        EndIf
      EndIf
    EndIf
    If (FinX=0 And FinY=0)                              ; mode clic gauche appuyé
      If EventType() =  #PB_EventType_MouseMove  
        DrawingMode(#PB_2DDrawing_AlphaBlend)
        Clic_Gauche=#False 
        If GetGadgetAttribute(#Canvas, #PB_Canvas_Buttons) &  #PB_Canvas_LeftButton
          If menu=7
            Circle(X,Y, 5, lcolor)
          EndIf
          If menu=8
            Circle(X,Y,Random(20), lcolor)
          EndIf
        EndIf 
      EndIf
      FinX=0:FinY=0
    EndIf   
    If EventType() = #PB_EventType_RightButtonDown And Clic_Gauche=#True
      Clic_Gauche=#False                                   ; annule fin du dessin en cours
      DrawImage(ImageID(#Image1),0,0)                      ; restore le dessin precedent
      FinX=0:FinY=0                                        ; remise à zero pour test fin ligne
    EndIf
    StopDrawing()
    Select EventType()
        
      Case #PB_EventType_LeftButtonDown
        
        If StartDrawing(ImageOutput(#Image0))
          DrawImage(GetGadgetAttribute(#canvas,#PB_Canvas_Image),0,0) ;fixe le dessin 
          StopDrawing()
        EndIf
        If Clic_Gauche=#False                               ; valide la fin du dessin avec le click gauche = 0
          Clic_Gauche=#True                                 ; debut du dessin avec le click gauche = 1
          color= RGBA(Random(255), Random(255),Random(255),150)  ; couleur aléatoire
          lcolor= RGBA(Random(255), Random(255),Random(255),150/6) 
          titre$="CanvasGadget       Color="+Str(Red(color))+"|"+Str(Green(color))+"|"+Str(Blue(color))+"|"+Str(Alpha(color))+" /6= "+Str(Alpha(lcolor)) 
          SetWindowTitle(0,titre$)
          CopyImage(#Image0,#Image1)                        ; copie Image pour eventuelle annulation
        Else
          Clic_Gauche=#False                                ; valide la fin du dessin avec le click gauche = 0
        EndIf
        DepartX = X                                         ; coordonnée DepartX Clic_Gauche
        DepartY = Y                                         ; coordonnée DepartY Clic_Gauche
        If menu=1 Or menu=2
          If (FinX<>0 And FinY<>0)
            Clic_Gauche=#True                               ; reactive le clic_Gauche pour ligne suivante
            CopyImage(#Image0,#Image1)                      ; copie Image pour eventuelle annulation
            DepartX = FinX                                  ; transfert dernier clic_Gauche FinX vers DepartX suivant mode line chainée
            DepartY = FinY                                  ; transfert dernier clic_Gauche FinY vers DepartY suivant
          EndIf
        EndIf
        
    EndSelect 
    Select event
      Case #PB_Event_Menu      
        Select EventMenu()  
          Case #menu1: menu=1:FinX=0:FinY=0  ;FinX=0:FinY=0 mis à zero = choix clic (1 ou 2)
          Case #menu2: menu=2:FinX=0:FinY=0
          Case #menu3: menu=3:FinX=0:FinY=0
          Case #menu4: menu=4:FinX=0:FinY=0
          Case #menu5: menu=5:FinX=0:FinY=0  
          Case #menu6: menu=6:FinX=0:FinY=0  
          Case #menu7: menu=7:FinX=0:FinY=0  
          Case #menu8: menu=8:FinX=0:FinY=0    
        EndSelect       
      Case #PB_Event_SizeWindow                             ; redimensione le scroll avec la fenetre
        ResizeGadget(#Scroll,#PB_Ignore,#PB_Ignore,WindowWidth(#Window),WindowHeight(#Window)-20)   ; -20 = scroll horizontal et menu
        SetGadgetColor(#Scroll,#PB_Gadget_BackColor,#White)
      Case #PB_Event_CloseWindow
        quit=1
    EndSelect  
  Until quit
EndIf
Zuletzt geändert von kernadec am 05.07.2011 14:49, insgesamt 3-mal geändert.
Benutzeravatar
PureLust
Beiträge: 1145
Registriert: 21.07.2005 00:02
Computerausstattung: Hab aktuell im Grunde nur noch 'nen Lenovo Yoga 2 Pro im Einsatz.
Wohnort: am schönen Niederrhein

Re: Linie zeichnen

Beitrag von PureLust »

Hiho zusammen,

am frühen Morgen noch mal eine etwas abgewandelte bo³-Version mit einer dicken Linie per GDI.
(Dürfte etwas performanter sein, als die Version mit den Kreisen.)

Code: Alles auswählen

EnableExplicit

Enumeration
	#Window
	#Gadget
	#Image
	#SaveImage
EndEnumeration

Procedure	BigLineXY(X1, Y1, X2, Y2, Color.l, PenSize.l, *hDC)
	Protected	*hPen
	*hPen = CreatePen_(#PS_SOLID, PenSize, Color)
	If *hPen
		If SelectObject_(*hDC, *hPen)
			MoveToEx_(*hDC, X1, Y1, 0)
			LineTo_(*hDC, X2, Y2)
		EndIf
		DeleteObject_(*hPen)
	EndIf		
EndProcedure


OpenWindow(#Window, 0, 0, 512, 512, "Fenster", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
ImageGadget(#Gadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window),0)
;CanvasGadget(#Gadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window))
DisableGadget(#Gadget,1)
Global ShowLine.i, Start.Point

CreateImage(#SaveImage, 512, 512)
StartDrawing(ImageOutput(#SaveImage))
Box(0,0,512,512,$FFFFFF)
StopDrawing()
CopyImage(#SaveImage,#Image)
SetGadgetState(#Gadget, ImageID(#Image))

Define Event, *hDC

Repeat
	
	Event = WaitWindowEvent()
	; Debug Event
	Select Event
			
		Case #PB_Event_CloseWindow
			
			End
			
		Case #WM_LBUTTONDOWN
			
			ShowLine = #True
			Start\X = WindowMouseX(#Window)
			Start\Y = WindowMouseY(#Window)
			
		Case #WM_MOUSEMOVE
			
			If ShowLine
				*hDC = StartDrawing(ImageOutput(#Image))
				If *hDC
					DrawImage(ImageID(#SaveImage), 0, 0)
					BigLineXY(WindowMouseX(#Window), WindowMouseY(#Window), Start\X, Start\Y, $000000, 10, *hDC)
					StopDrawing()
					SetGadgetState(#Gadget,ImageID(#Image))
				EndIf
			EndIf
			
		Case #WM_LBUTTONUP
			
			ShowLine = #False
				*hDC = StartDrawing(ImageOutput(#SaveImage))
				If *hDC
					BigLineXY(WindowMouseX(#Window), WindowMouseY(#Window), Start\X, Start\Y, $000000, 10, *hDC)
					StopDrawing()
					SetGadgetState(#Gadget,ImageID(#SaveImage))
				EndIf
				
	EndSelect
	
ForEver
Grüße, PL.
[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
Benutzeravatar
Velindos
Beiträge: 598
Registriert: 15.11.2010 10:56

Re: Linie zeichnen

Beitrag von Velindos »

Hallo Leute, Danke für die Unterstützung. Woran ich noch tüfftle ist, dass man die Linie transparent macht, ähnlich eines "Marker-Stiftes". Vielleicht hat jemand noch nen Tip?
Gruss ... Velindos
Windows 7/8/8.1/10 (32/64-Bit) |Ubuntu 10.4 (64-Bit) |Purebasic 5.71 LTS (32/64-Bit)
Antworten