Linie zeichnen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
kernadec
Beiträge: 25
Registriert: 05.07.2009 17:51

Re: Linie zeichnen

Beitrag von kernadec »

Hallo
aktualisierten Code
Zeichnung mit einer transparenten Box
# PB_2DDrawing_AlphaBlend mit den RGBA-Modus
guten Tag
Benutzeravatar
Velindos
Beiträge: 598
Registriert: 15.11.2010 10:56

Re: Linie zeichnen

Beitrag von Velindos »

Hallo Leute, danke für die Tips!
Habe eine Requester für Color eingefügt.

Code: Alles auswählen

Color = ColorRequester(Color)
Die gewählte Farbe lässt sich nicht bei

Code: Alles auswählen

Box(Start\X, Start\Y, BoxBerechnungBreite, BoxBerechnungHoehe, $FF0000FF)
und

Code: Alles auswählen

Circle(Start\X, Start\Y, Radius , $FF0000FF) 
verwenden. Hat jemand einen Tip wie ich das beheben kann?

Gruss ... Velindos
Windows 7/8/8.1/10 (32/64-Bit) |Ubuntu 10.4 (64-Bit) |Purebasic 5.71 LTS (32/64-Bit)
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 »

Hab's jetzt nicht getestet, aber da der ColorRequester() nur einen RGB-Wert zurück gibt (und keinen RGBA - also ohne Alpha-Kanal) müsstest Du es vermutlich so machen:

Code: Alles auswählen

Color = ColorRequester(Color)
.....
Box(Start\X, Start\Y, BoxBerechnungBreite, BoxBerechnungHoehe, Color | $FF000000)
Circle(Start\X, Start\Y, Radius , Color | $FF000000)
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,
@ PureLust ... Danke für den Tip.
Habe nur das Problem das die Farbe nicht mit dem Requester übereinstimmt.
Gibt es die Procedure "BigLineXY" auch für Box und Circle?
Gruss ... Velindos
Windows 7/8/8.1/10 (32/64-Bit) |Ubuntu 10.4 (64-Bit) |Purebasic 5.71 LTS (32/64-Bit)
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 »

Velindos hat geschrieben:Gibt es die Procedure "BigLineXY" auch für Box und Circle?
Hab Dir nochmal ein kleines Beispiel mit Farbauswahl, Linien, Kreisen und Boxen gemacht.
Allerdings etwas anders als zuvor, wo ja die Liniendicke bei BigLineXY() angegeben wurde.
Und zwar kannst Du nun durch die Prozedur SetPen() einen "Stift" in beliebiger Dicke erstellen, mit dem dann die entsprechenden Figuren (Linien, Kreise, Rechtecke) gezeichnet werden.

Für Dein eigenes Programm musst Du also zuerst mit SetPen() einen "Stirt" erstellen und anschließend dann eine der API-Drawingroutinen aufrufen.

Code: Alles auswählen

EnableExplicit

Define FGColor.l = $0
Define NewColor.l
Define *hActPen
Define *hActBrush
Define Count.l

Enumeration
	#Window
	#Gadget
	#Image
	#SaveImage
	#ButtonColorSelect
	#ComboTypeSelect
	#ComboSizeSelect
EndEnumeration

Procedure   SetPen(Color.l, PenSize.l, *hDC)
	Static *hPen
	
	If *hPen
		DeleteObject_(*hPen)
	EndIf
	
	*hPen = CreatePen_(#PS_SOLID, PenSize, Color)
	If *hPen
		SelectObject_(*hDC, *hPen)
	EndIf      
	
EndProcedure

OpenWindow(#Window, 0, 0, 512, 512, "Fenster", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
ImageGadget(#Gadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window)-30,0)
;CanvasGadget(#Gadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window))
ButtonGadget(#ButtonColorSelect,   5, WindowHeight(#Window)-28, 300, 22, "Farbauswahl")
ComboBoxGadget(#ComboTypeSelect, 310, WindowHeight(#Window)-28, 105 , 22)
ComboBoxGadget(#ComboSizeSelect, 420, WindowHeight(#Window)-28, WindowWidth(#Window)-425, 22)
;DisableGadget(#Gadget,1)
Global ShowLine.i, Start.Point

AddGadgetItem(#ComboTypeSelect, -1, "  Linie")
AddGadgetItem(#ComboTypeSelect, -1, "  Kreis")
AddGadgetItem(#ComboTypeSelect, -1, "  Box")
AddGadgetItem(#ComboTypeSelect, -1, "  Runde Box")
SetGadgetState(#ComboTypeSelect,1)

For Count = 1 To 40
	AddGadgetItem(#ComboSizeSelect, -1, "  "+Str(Count))
	SetGadgetItemData(#ComboSizeSelect, CountGadgetItems(#ComboSizeSelect)-1, Count)
Next
SetGadgetState(#ComboSizeSelect,4)

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

Define Event, *hDC

Repeat
	
	Event = WaitWindowEvent()
	; Debug Str(Event) + " - " +  Str(EventGadget()) + " - " + Str(EventType)
	Select Event
			

		Case #PB_Event_CloseWindow
			
			End
			
		Case #PB_Event_Gadget
			
			Select EventGadget()
					
				Case	#ButtonColorSelect
					
					NewColor = ColorRequester(FGColor)
					If NewColor >= 0
						FGColor = NewColor
					EndIf
					
				Case #Gadget
					
						ShowLine = #True
						Start\X = WindowMouseX(#Window)
						Start\Y = WindowMouseY(#Window)
						
				EndSelect
			
		Case #WM_MOUSEMOVE
			
			If ShowLine
				
				*hDC = StartDrawing(ImageOutput(#Image))
				
				If *hDC
					
					DrawImage(ImageID(#SaveImage), 0, 0)
					SetPen(FGColor, GetGadgetItemData(#ComboSizeSelect, GetGadgetState(#ComboSizeSelect)), *hDC)
					
					Select GetGadgetState(#ComboTypeSelect)
							
						Case 0	; ----- Line
							
							MoveToEx_(*hDC, Start\x, Start\y, 0)
							LineTo_(*hDC, WindowMouseX(#Window), WindowMouseY(#Window))
							
						Case 1	; ----- Circle
							
							Ellipse_(*hDC, Start\X, Start\Y, WindowMouseX(#Window), WindowMouseY(#Window))
							
						Case 2	; ----- Box
							
							Rectangle_(*hDC, Start\X, Start\Y, WindowMouseX(#Window), WindowMouseY(#Window))
							
						Case 3	; ----- Box mit runden Ecken
							
							RoundRect_(*hDC, Start\X, Start\Y, WindowMouseX(#Window), WindowMouseY(#Window), 40, 40)
							
					EndSelect
					StopDrawing()
					SetGadgetState(#Gadget,ImageID(#Image))
				EndIf
			EndIf
			
		Case #WM_LBUTTONUP
			
			If ShowLine
				*hDC = StartDrawing(ImageOutput(#SaveImage))
				If *hDC
					DrawImage(ImageID(#SaveImage), 0, 0)
					SetPen(FGColor, GetGadgetItemData(#ComboSizeSelect, GetGadgetState(#ComboSizeSelect)), *hDC)
					
					Select GetGadgetState(#ComboTypeSelect)
							
						Case 0	; ----- Line
							
							MoveToEx_(*hDC, Start\x, Start\y, 0)
							LineTo_(*hDC, WindowMouseX(#Window), WindowMouseY(#Window))
							
						Case 1	; ----- Circle
							
							Ellipse_(*hDC, Start\X, Start\Y, WindowMouseX(#Window), WindowMouseY(#Window))
							
						Case 2	; ----- Box
							
							Rectangle_(*hDC, Start\X, Start\Y, WindowMouseX(#Window), WindowMouseY(#Window))
							
						Case 3	; ----- Box mit runden Ecken
							
							RoundRect_(*hDC, Start\X, Start\Y, WindowMouseX(#Window), WindowMouseY(#Window), 40, 40)
							
					EndSelect
					StopDrawing()
					SetGadgetState(#Gadget,ImageID(#Image))
				EndIf
				ShowLine = #False
			EndIf
			
	EndSelect
	
ForEver
Ich hoffe, Du kommst damit klar. ;)

Gruß, PL.
[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: Linie zeichnen

Beitrag von Danilo »

Velindos hat geschrieben:Gibt es die Procedure "BigLineXY" auch für Box und Circle?
Hier mal die Funktionen gLine, gLineXY, gBox, gPie, gArc, gEllipse, gCircle, gBezier und gPoly.
Das ganze über GDI+ und mit Antialiasing.
Funktioniert im Grunde wie die PB-Befehle, nur ist der letzte (optionale) Parameter
die Stiftdicke wenn Du im Outlined-Modus zeichnest.

Code: Alles auswählen

EnableExplicit

;>----- START INCLUDE ---------------------------------------
;
;-[ antialiased PB compatible drawing functions using GDI+ ]-
;
; by Danilo, July 2011
;
Prototype DebugEventProc(level, *message.Ascii)
Prototype NotificationHookProc(*token.Long)
Prototype NotificationUnhookProc(token.l)

Structure GdiplusStartupInput
    GdiPlusVersion.l
    *DebugEventCallback.DebugEventProc
    SuppressBackgroundThread.l
    SuppressExternalCodecs.l
EndStructure

Structure GdiplusStartupOutput
    *NotificationHook.NotificationHookProc
    *NotificationUnhook.NotificationUnhookProc
EndStructure

Enumeration ; CompositingMode
    #CompositingModeSourceOver = 0 ;   // 0
    #CompositingModeSourceCopy = 1 ;   // 1
EndEnumeration

Enumeration ; QualityMode
    #QualityModeInvalid   = -1
    #QualityModeDefault   =  0
    #QualityModeLow       =  1  ; Best performance
    #QualityModeHigh      =  2  ; Best rendering quality
EndEnumeration

Enumeration ; CompositingQuality
    #CompositingQualityInvalid          = #QualityModeInvalid
    #CompositingQualityDefault          = #QualityModeDefault
    #CompositingQualityHighSpeed        = #QualityModeLow
    #CompositingQualityHighQuality      = #QualityModeHigh
    #CompositingQualityGammaCorrected
    #CompositingQualityAssumeLinear
EndEnumeration

Enumeration ; SmoothingMode
    #SmoothingModeInvalid     = #QualityModeInvalid
    #SmoothingModeDefault     = #QualityModeDefault
    #SmoothingModeHighSpeed   = #QualityModeLow
    #SmoothingModeHighQuality = #QualityModeHigh
    #SmoothingModeNone
    #SmoothingModeAntiAlias
;#if (GDIPVER >= 0x0110)
    #SmoothingModeAntiAlias8x4 = #SmoothingModeAntiAlias
    #SmoothingModeAntiAlias8x8
;#endif //(GDIPVER >= 0x0110) 
EndEnumeration

Enumeration ; InterpolationMode
    #InterpolationModeInvalid          = #QualityModeInvalid
    #InterpolationModeDefault          = #QualityModeDefault
    #InterpolationModeLowQuality       = #QualityModeLow
    #InterpolationModeHighQuality      = #QualityModeHigh
    #InterpolationModeBilinear
    #InterpolationModeBicubic
    #InterpolationModeNearestNeighbor
    #InterpolationModeHighQualityBilinear
    #InterpolationModeHighQualityBicubic
EndEnumeration

Enumeration ; PixelOffsetMode
    #PixelOffsetModeInvalid     = #QualityModeInvalid
    #PixelOffsetModeDefault     = #QualityModeDefault
    #PixelOffsetModeHighSpeed   = #QualityModeLow
    #PixelOffsetModeHighQuality = #QualityModeHigh
    #PixelOffsetModeNone     ; No pixel offset
    #PixelOffsetModeHalf     ; Offset by -0.5, -0.5 For fast anti-alias perf
EndEnumeration

Enumeration ; LineCap
    #LineCapFlat             = 0
    #LineCapSquare           = 1
    #LineCapRound            = 2
    #LineCapTriangle         = 3

    #LineCapNoAnchor         = $10 ; corresponds To flat cap
    #LineCapSquareAnchor     = $11 ; corresponds To square cap
    #LineCapRoundAnchor      = $12 ; corresponds To round cap
    #LineCapDiamondAnchor    = $13 ; corresponds To triangle cap
    #LineCapArrowAnchor      = $14 ; no correspondence

    #LineCapCustom           = $ff ; custom cap

    #LineCapAnchorMask       = $f0 ; mask To check For anchor Or Not.
EndEnumeration

Prototype.l GdiplusStartup(*token.Long, *input.GdiplusStartupInput, *output.GdiplusStartupOutput)
Prototype.l GdiplusShutdown(token.l)

Prototype.l GdipCreateFromHDC(*hDC, *graphics)
Prototype.l GdipDeleteGraphics(*graphics)

Prototype.l GdipGraphicsClear(*graphics, color.l)

Prototype.l GdipSetSmoothingMode        (*graphics, smoothingMode.l)
Prototype.l GdipSetCompositingMode      (*graphics, compositingMode.l)
Prototype.l GdipSetCompositingQuality   (*graphics, compositingQuality.l)
Prototype.l GdipSetInterpolationMode    (*graphics, interpolationMode.l)
Prototype.l GdipSetPixelOffsetMode      (*graphics, pixelOffsetMode.l)


Prototype.l GdipCreatePen1    (color.l, Width.f, unit.l, *pen)
Prototype.l GdipDeletePen     (*pen)
Prototype.l GdipSetPenStartCap(*pen, startCap.l)
Prototype.l GdipSetPenEndCap  (*pen, endCap.l)

Prototype.l GdipCreateSolidFill(color.l, *brush)
Prototype.l GdipDeleteBrush(*brush)


Prototype.l GdipDrawRectangleI(*graphics, *pen  , x.l , y.l , width.l, height.l)
Prototype.l GdipFillRectangleI(*graphics, *brush, x.l , y.l , width.l, height.l)
Prototype.l GdipDrawLineI     (*graphics, *pen  , x1.l, y1.l, x2.l   , y2.l    )
Prototype.l GdipDrawPieI      (*graphics, *pen  , x.l , y.l , width.l, height.l, startAngle.f, sweepAngle.f)
Prototype.l GdipFillPieI      (*graphics, *brush, x.l , y.l , width.l, height.l, startAngle.f, sweepAngle.f)
Prototype.l GdipDrawArcI      (*graphics, *pen  , x.l , y.l , width.l, height.l, startAngle.f, sweepAngle.f)
Prototype.l GdipDrawEllipseI  (*graphics, *pen  , x.l , y.l , width.l, height.l)
Prototype.l GdipFillEllipseI  (*graphics, *pen  , x.l , y.l , width.l, height.l)
Prototype.l GdipDrawBezierI   (*graphics, *pen  , x1.l, y1.l, x2.l   , y2.l    , x3.l, y3.l, x4.l, y4.l)
Prototype.l GdipDrawPolygonI  (*graphics, *pen  , *points.POINT, count.l)
Prototype.l GdipFillPolygon2I (*graphics, *brush, *points.POINT, count.l)

Macro DoubleQuote
    "
EndMacro

Macro setFunc(_name_)
    Global _name_#_._name_
    _name_#_ = GetFunction(__dll,DoubleQuote#_name_#DoubleQuote)
EndMacro

Macro toARGB(color)
    ( (color & $FF00FF00) | ( (color & $FF) << 16 ) | ((color >> 16) & $FF) )
EndMacro

Global __dll,__gdiplusToken.l,__drawingMode.l,__graphics,__lineCapStart,__lineCapEnd

Procedure gInit()
    __dll = OpenLibrary(#PB_Any, "gdiplus.dll")
    If Not __dll : ProcedureReturn 0 : EndIf
   
    setFunc(GdiplusStartup)
    setFunc(GdiplusShutdown)
    setFunc(GdipCreateFromHDC)
    setFunc(GdipDeleteGraphics)
    setFunc(GdipGraphicsClear)
    setFunc(GdipSetSmoothingMode)
    setFunc(GdipSetCompositingMode)
    setFunc(GdipSetCompositingQuality)
    setFunc(GdipSetInterpolationMode)
    setFunc(GdipSetPixelOffsetMode)
    setFunc(GdipCreatePen1)
    setFunc(GdipDeletePen)
    setFunc(GdipSetPenStartCap)
    setFunc(GdipSetPenEndCap)
    setFunc(GdipCreateSolidFill)
    setFunc(GdipDeleteBrush)
    setFunc(GdipDrawRectangleI)
    setFunc(GdipFillRectangleI)
    setFunc(GdipDrawLineI)
    setFunc(GdipDrawPieI)
    SetFunc(GdipFillPieI)
    setFunc(GdipDrawArcI)
    setFunc(GdipDrawEllipseI)
    SetFunc(GdipFillEllipseI)
    SetFunc(GdipDrawBezierI)
    SetFunc(GdipDrawPolygonI)
    SetFunc(GdipFillPolygon2I)

    ; Initialize GDI+.
    Protected gdiplusStartupInput.GdiplusStartupInput
    
    gdiplusStartupInput\GdiplusVersion              = 1
    gdiplusStartupInput\DebugEventCallback          = #Null
    gdiplusStartupInput\SuppressBackgroundThread    = #False
    gdiplusStartupInput\SuppressExternalCodecs      = #False
    
    If Not GdiplusStartup_(@__gdiplusToken, @gdiplusStartupInput, #Null)
        ProcedureReturn #True
    EndIf
EndProcedure

Procedure gEnd()
    GdiplusShutdown_(__gdiplusToken)
    If __dll
        CloseLibrary(__dll)
    EndIf
EndProcedure

Procedure gStartDrawing( out )
    Protected hDC

    hDC = StartDrawing(out)
    If Not hDC : ProcedureReturn 0 : EndIf
    
    GdipCreateFromHDC_(hDC ,@__graphics)
    If Not __graphics
        StopDrawing()
        ProcedureReturn 0
    EndIf
    
    __drawingMode  = #PB_2DDrawing_Default
    __lineCapStart = #LineCapFlat
    __lineCapEnd   = #LineCapFlat
    GdipSetSmoothingMode_     (__graphics,#SmoothingModeAntiAlias8x8)
    GdipSetCompositingMode_   (__graphics,#CompositingModeSourceOver)
    GdipSetCompositingQuality_(__graphics,#CompositingQualityGammaCorrected)
    GdipSetInterpolationMode_ (__graphics,#InterpolationModeHighQualityBicubic)
    GdipSetPixelOffsetMode_   (__graphics,#PixelOffsetModeHighQuality)
    ProcedureReturn hDC
EndProcedure

Procedure gStopDrawing()
    If __graphics
        GdipDeleteGraphics_( __graphics )
        __graphics = 0
    EndIf
    StopDrawing()
EndProcedure

Procedure gDrawingMode( newMode.l )
    __drawingMode = newMode
EndProcedure

Procedure gCapMode( lineCapStart.l, lineCapEnd.l )
    __lineCapStart = lineCapStart
    __lineCapEnd   = lineCapEnd
EndProcedure


Procedure gAntiAliasMode( newMode.l )
    If __graphics
        GdipSetSmoothingMode_(__graphics,newMode)
    EndIf
EndProcedure


Procedure gClear(color.l)
    If __graphics
        GdipGraphicsClear_(__graphics, toARGB(color))    
    EndIf
EndProcedure

Procedure gBox(x.l, y.l, width.l, height.l, color.l, penwidth.l=1)
    If __graphics
        If __drawingMode & #PB_2DDrawing_Outlined
            Protected *pen
            GdipCreatePen1_(toARGB(color),penwidth,2,@*pen)
            GdipDrawRectangleI_(__graphics,*pen,x,y,width,height)
            GdipDeletePen_(*pen)
        Else
            Protected *brush
            GdipCreateSolidFill_(toARGB(color),@*brush)
            GdipFillRectangleI_(__graphics,*brush,x,y,width,height)
            GdipDeleteBrush_(*brush)
        EndIf
    EndIf
EndProcedure


Procedure gLineXY(x1.l, y1.l, x2.l, y2.l, color.l, penwidth.l=1)
    If __graphics
        Protected *pen
        GdipCreatePen1_(toARGB(color),penwidth,2,@*pen)
        GdipSetPenStartCap_(*pen, __lineCapStart)
        GdipSetPenEndCap_  (*pen, __lineCapEnd  )
        GdipDrawLineI_(__graphics,*pen,x1,y1,x2,y2)
        GdipDeletePen_(*pen)
    EndIf
EndProcedure

Procedure gLine(x.l, y.l, width.l, height.l, color.l, penwidth.l=1)
    gLineXY(x,y,x+width,y+height,color,penwidth)
EndProcedure

Procedure gPie(x.l, y.l, radiusX.l, radiusY.l, startAngle.f, sweepAngle.f, color.l, penwidth.l=1)
    If __graphics
        If __drawingMode & #PB_2DDrawing_Outlined
            Protected *pen
            GdipCreatePen1_(toARGB(color),penwidth,2,@*pen)
            GdipDrawPieI_(__graphics,*pen,x-radiusX,y-radiusY,radiusX*2,radiusY*2,startAngle,sweepAngle)
            GdipDeletePen_(*pen)
        Else
            Protected *brush
            GdipCreateSolidFill_(toARGB(color),@*brush)
            GdipFillPieI_(__graphics,*brush,x-radiusX,y-radiusY,radiusX*2,radiusY*2,startAngle,sweepAngle)
            GdipDeleteBrush_(*brush)
        EndIf
    EndIf
EndProcedure

Procedure gArc(x.l, y.l, radiusX.l, radiusY.l, startAngle.f, sweepAngle.f, color.l, penwidth.l=1)
    If __graphics
        Protected *pen
        GdipCreatePen1_(toARGB(color),penwidth,2,@*pen)
        GdipSetPenStartCap_(*pen, __lineCapStart)
        GdipSetPenEndCap_  (*pen, __lineCapEnd  )
        GdipDrawArcI_(__graphics,*pen,x-radiusX,y-radiusY,radiusX*2,radiusY*2,startAngle,sweepAngle)
        GdipDeletePen_(*pen)
    EndIf
EndProcedure

Procedure gEllipse(x.l, y.l, radiusX.l, radiusY.l, color.l, penwidth.l=1)
    If __graphics
        If __drawingMode & #PB_2DDrawing_Outlined
            Protected *pen
            GdipCreatePen1_(toARGB(color),penwidth,2,@*pen)
            GdipDrawEllipseI_(__graphics,*pen,x-radiusX,y-radiusY,radiusX*2,radiusY*2)
            GdipDeletePen_(*pen)
        Else
            Protected *brush
            GdipCreateSolidFill_(toARGB(color),@*brush)
            GdipFillEllipseI_(__graphics,*brush,x-radiusX,y-radiusY,radiusX*2,radiusY*2)
            GdipDeleteBrush_(*brush)
        EndIf
    EndIf
EndProcedure

Procedure gCircle(x.l, y.l, radius.l, color.l, penwidth.l=1)
    gEllipse(x,y,radius,radius,color,penwidth)
EndProcedure

Procedure gBezier(x1.l, y1.l, x2.l, y2.l, x3.l, y3.l, x4.l, y4.l, color.l, penwidth.l=1)
    If __graphics
        Protected *pen
        GdipCreatePen1_(toARGB(color),penwidth,2,@*pen)
        GdipSetPenStartCap_(*pen, __lineCapStart)
        GdipSetPenEndCap_  (*pen, __lineCapEnd  )
        GdipDrawBezierI_(__graphics,*pen,x1,y1,x2,y2,x3,y3,x4,y4)
        GdipDeletePen_(*pen)
    EndIf
EndProcedure

Procedure gPoly(x1.l, y1.l, x2.l, y2.l, x3.l, y3.l, color.l, penwidth.l=1)
    If __graphics
        Dim points.POINT(3)
        points(0)\x = x1
        points(0)\y = y1
        points(1)\x = x2
        points(1)\y = y2
        points(2)\x = x3
        points(2)\y = y3
        If __drawingMode & #PB_2DDrawing_Outlined
            Protected *pen
            GdipCreatePen1_(toARGB(color),penwidth,2,@*pen)
            GdipDrawPolygonI_(__graphics,*pen,@points(),3)
            GdipDeletePen_(*pen)
        Else
            Protected *brush
            GdipCreateSolidFill_(toARGB(color),@*brush)
            GdipFillPolygon2I_(__graphics,*brush,@points(),3)
            GdipDeleteBrush_(*brush)
        EndIf
    EndIf
EndProcedure

;>----- END INCLUDE -----------------------------------------

;- Program

Global img, currentColor, drawMode
Global startPos.POINT
Global endPos.POINT
Global mainWin, imgWin, modeWin
Define i.l, mouseDown.l, copy
Global currentColor = RGBA($00,$00,$FF,$80)
Global currentPenSize = 15

Procedure redraw(image)
    If gStartDrawing( ImageOutput(image) )
        If image <> img
            DrawImage(ImageID(img),0,0)
        EndIf
        gCapMode(#LineCapRound,#LineCapRound)
        gDrawingMode(#PB_2DDrawing_Outlined)
        Select drawMode
            Case 0 : gLineXY(startPos\x,startPos\y,endPos\x,endPos\y,currentColor,currentPenSize)
            Case 1 : gBox(startPos\x,startPos\y,endPos\x-startPos\x,endPos\y-startPos\y,currentColor,currentPenSize)
            Case 2 : gEllipse(startPos\x,startPos\y,endPos\x-startPos\x,endPos\y-startPos\y,currentColor,currentPenSize)
            Case 3 : gCircle(startPos\x,startPos\y,endPos\x-startPos\x,currentColor,currentPenSize)
        EndSelect
        gStopDrawing()
        If IsGadget(imgWin)
            SetGadgetState(imgWin,ImageID(image))
        EndIf
    EndIf
EndProcedure


If gInit()
    img = CreateImage(#PB_Any,850,600,24)
    If gStartDrawing( ImageOutput(img) )
        gClear( RGBA($80,$80,$80,$FF) )
        gDrawingMode(#PB_2DDrawing_Outlined)
        gBox(50,50,100,100,RGBA($40,$40,$40,$FF),5)
        gLineXY(160,50,260,150,RGBA($00,$00,$FF,$FF),5)
        gDrawingMode(#PB_2DDrawing_Default)
        gPie(320,100,49,49,-90,110,RGBA($FF,$FF,$00,$FF))
        gPie(320,100,49,49, 20, 50,RGBA($00,$FF,$FF,$FF))
        gPie(320,100,49,49, 70, 60,RGBA($00,$00,$FF,$FF))
        gDrawingMode(#PB_2DDrawing_Outlined)
        gPie(320,100,50,50,-90,220,RGBA($00,$00,$00,$FF),3)
        For i = 0 To 260 Step 20
            gArc(430,100,50,50,-90+i,15,RGBA($00,$00,$00,$FF),3)
        Next i
        gDrawingMode(#PB_2DDrawing_Default)
        gEllipse(540,100,50,25,RGBA($FF,$FF,$FF,$FF))
        gCircle(540,100,25,RGBA($00,$FF,$00,$FF))
        gCircle(540,100,10,RGBA($00,$00,$00,$FF))
        gDrawingMode(#PB_2DDrawing_Outlined)
        gEllipse(540,100,50,25,RGBA($00,$00,$00,$FF),2)
        gCircle(540,100,25,RGBA($00,$00,$00,$FF),2)
        gBezier(600,50,800,100,500,100,700,150,RGBA($00,$FF,$FF,$FF),2)
        gPoly(710,50,730,150,780,80,RGBA($FF,$00,$FF,$FF),2)

        gDrawingMode(#PB_2DDrawing_Default)
        gBox(70,100,100,100,RGBA($00,$00,$00,$80))
        gPie(340,150,50,50,-90,220,RGBA($00,$00,$00,$80))
        gEllipse(570,150,50,25,RGBA($00,$00,$00,$80))
        gPoly(730,100,750,200,800,130,RGBA($00,$00,$00,$80))

        gCapMode(#LineCapRound,#LineCapArrowAnchor)
        gLineXY(190,100,290,200,RGBA($00,$00,$00,$80),15)
        For i = 0 To 260 Step 40
            gArc(460,150,50,50,-90+i,30,RGBA($00,$00,$00,$80),7)
        Next i
        gBezier(620,100,820,150,520,150,720,200,RGBA($00,$00,$00,$80),7)


        gStopDrawing()
    EndIf
    
    mainWin = OpenWindow(#PB_Any,0,0,850,620,"Draw!",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    
    modeWin = ComboBoxGadget(#PB_Any,0,600,100,20)
    AddGadgetItem(modeWin,-1,"Line")
    AddGadgetItem(modeWin,-1,"Box")
    AddGadgetItem(modeWin,-1,"Ellipse")
    AddGadgetItem(modeWin,-1,"Circle")
    SetGadgetState(modeWin,0)
    
    imgWin  = ImageGadget(#PB_Any,0,00,850,600,ImageID(img))
    DisableGadget(imgWin,1)
    
    Repeat
        Select WaitWindowEvent()
            Case #PB_Event_CloseWindow
                Break
            Case #PB_Event_Gadget
                Select EventGadget()
                    Case modeWin    : drawMode = GetGadgetState(modeWin)
                EndSelect
            Case #WM_LBUTTONDOWN
                GetCursorPos_(@startPos)
                ScreenToClient_(GadgetID(imgWin),@startPos)
                If startPos\y < 600
                    SetCapture_(WindowID(mainWin))
                    mouseDown = 1
                    endPos\x = startPos\x+1
                    endPos\y = startPos\y+1
                    If copy : FreeImage(copy) : EndIf
                    copy = CopyImage(img,#PB_Any)
                EndIf
            Case #WM_LBUTTONUP
                If mouseDown
                    ReleaseCapture_()
                    mouseDown = 0
                    redraw(img)
                EndIf
            Case #WM_MOUSEMOVE
                If mouseDown
                    GetCursorPos_(@endPos)
                    ScreenToClient_(GadgetID(imgWin),@endPos)
                    redraw(copy)
                EndIf
        EndSelect
    ForEver

    gEnd()
EndIf
EDIT 2: hatte CloseLibrary vergessen
Zuletzt geändert von Danilo am 06.07.2011 12:35, insgesamt 2-mal geändert.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
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 »

:allright: sehr schön!

Leider ein kleiner Flüchtigkeitsfehler (WindowID versus ImageID)

Code: Alles auswählen

Procedure redraw(image)
    If gStartDrawing( ImageOutput(image) )
        If image <> img
            DrawImage(ImageID(img),0,0)
        EndIf
        gCapMode(#LineCapRound,#LineCapRound)
        gDrawingMode(#PB_2DDrawing_Outlined)
        Select drawMode
            Case 0 : gLineXY(startPos\x,startPos\y,endPos\x,endPos\y,currentColor,currentPenSize)
            Case 1 : gBox(startPos\x,startPos\y,endPos\x-startPos\x,endPos\y-startPos\y,currentColor,currentPenSize)
            Case 2 : gEllipse(startPos\x,startPos\y,endPos\x-startPos\x,endPos\y-startPos\y,currentColor,currentPenSize)
            Case 3 : gCircle(startPos\x,startPos\y,endPos\x-startPos\x,currentColor,currentPenSize)
        EndSelect
        gStopDrawing()
        If IsGadget(imgWin)
            SetGadgetState(imgWin,ImageID(image)); geändert!
        EndIf
    EndIf
EndProcedure
Gruß
Thomas
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
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: Linie zeichnen

Beitrag von Danilo »

ts-soft hat geschrieben::allright: sehr schön!

Leider ein kleiner Flüchtigkeitsfehler (WindowID versus ImageID)
Vielen Dank, habe es geändert!
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
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 »

@Danilo: Sehr geil !!! :allright:

Hättest Du das nicht mal 3 Wochen früher posten können?
Dann hätte ich mir meine eigene Drawing-Lib und das Einarbeiten in die GDI-Funktionen sparen können. >_< . . . :mrgreen:

Kleine Anmerkung hätte ich aber noch:
Code von Danilo hat geschrieben:;-[ antialiased PB compatible drawing functions using GDI+ ]-
Deine GDI+ Funktionen sind zwar in der Syntax kompatibel zu den PB-Derivaten - bei der erzeugten Grafik besteht zu der durch PB-Befehle erstellten Gafik jedoch ein Unterschied.

So wird z.B. bei dem Line-Befehl von GDI und auch GDI+ keine Linie (Punkt) gezeichnet, wenn der Start- und der Endpunkt identisch sind.
gLineXY(10,10,10,10,Color) zeichnet also kein Punkt, das "Original" von PB jedoch schon (musste ich bei meiner Lib auch erst abfangen - hatte das gleiche Problem).
Auch zeichnen die PB-Befehle bei Line() keine Linie, wenn Breite oder Höhe = 0 sind - die GDI und GDI+ Befehle jedoch schon.

Weiterhin entstehen durch den bei gStartDrawing() voreingestellten PixelOffsetMode (#PixelOffsetModeHighQuality) fast immer Pixelabweichungen von 1 Pixel zu den PB-Befehlen.
Hier würde eine Voreinstellung von '#PixelOffsetModeNone' dem "Original" eher entsprechen.

Um den PixelOffsetMode nach Bedarf anpassen zu können wäre ja vielleicht noch eine entsprechende Funktion sinnvoll:

Code: Alles auswählen

Procedure gPixelOffsetMode( newMode.l)
    If __graphics
        GdipSetPixelOffsetMode_(__graphics,newMode)
    EndIf
EndProcedure
Aber ansonsten eine seeeeehr geile Lib !!!

Und da (wie ich jetzt sehe) GDI+ scheinbar einiges mehr an Möglichkeiten bietet als GDI (auch wenn GDI um einiges schneller ist als GDI+), werde ich jetzt wohl auch auf Deine Routinen (oder zumindest auf GDI+) umschwenken. ;)

BIG Thanks for sharing and inspiration !!! :allright:
Zuletzt geändert von PureLust am 06.07.2011 16:08, insgesamt 1-mal geändert.
[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Linie zeichnen

Beitrag von STARGÅTE »

Danke für das Beispiel mit GDI+.
Kann die sachen gut für meine Vektorgrafik-Render-Include nutzen.

Aber:
Hier mal die Funktionen gLine, gLineXY, gBox, gPie, gArc, gEllipse, gCircle, gBezier und gPoly.
Das ganze über GDI+ und mit Antialiasing.
Ich frage mich aber, wieso alle Positionen/Größen in LONG sind ?
ich meine wenn Antialiasing enthalten ist, sollte es noch möglich sein, auch Linien "dazwischen" zu zeichen, die dann geglättet werden.

Und vorallem bei Linienstärken wäre FLOATs sehr von nöten, denn zwischen 1 und 2 liegen "welten"
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
Antworten