Bild (ver-)zerren?
Bild (ver-)zerren?
Hallo Leute,
denke die meisten kennen MSPaint darum nem ich das jetzt mal als Beispiel, gibt es eine Funktion die der MSPaint Funktion "Zerren" entspricht?
Gruß
Scarabol
denke die meisten kennen MSPaint darum nem ich das jetzt mal als Beispiel, gibt es eine Funktion die der MSPaint Funktion "Zerren" entspricht?
Gruß
Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea
PB-V: 4
WinXP
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea
PB-V: 4
WinXP
klar wenn du dein Sprite zum Sprite3D machst kannst du mit
dein Bild verzerren.
Wenn dein Bild 64*64 z.B. ist dann kannst du das leicht nach rechts kippen lassen:
Das wäre dann genau das was Paint auch macht.
Code: Alles auswählen
TransformSprite3D(#Sprite3D, x1, y1, x2, y2, x3, y3, x4, y4)
Wenn dein Bild 64*64 z.B. ist dann kannst du das leicht nach rechts kippen lassen:
Code: Alles auswählen
von so :
__
| |
|__|
mit :
TransformSprite3D(#Sprite3D, 32, 0, 96, 0, 64, 64, 0, 64)
zu :
__
/ /
/__/
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
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Cool danke!
Ich probiers mal...
Hat vielleicht noch einer nen Code wie man sowas "manuell" machen kann?
Da mit Sprite3D neue Probs auf mich zu kommen
Gruß
Scarabol
Ich probiers mal...
Hat vielleicht noch einer nen Code wie man sowas "manuell" machen kann?
Da mit Sprite3D neue Probs auf mich zu kommen

Gruß
Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea
PB-V: 4
WinXP
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea
PB-V: 4
WinXP
Unter Windows lässt sich das mit
bewerkstellisgen wobei PlgPoints ein Zeiger auf ein Array mit drei Punkten ist, die ein Parallelogramm beschreiben.
Code: Alles auswählen
PlgBlt_(hdcDest.l, *PlgPoints.POINT, hdcSource.l, xSrc.l, ySrc.l, wSrc.l, hSrc.l, Mask.l, xMask.l, yMask.l)
Ich glaube das hilft ihm auch nicht weiter.
@Scarabol
Willst du jetzt so ne art Procedure wo du wie in PAINT sagen kannst :
Stecken (in px) (x,y)
und
Zerren (in Grad) (x,y)
@Scarabol
Willst du jetzt so ne art Procedure wo du wie in PAINT sagen kannst :
Stecken (in px) (x,y)
und
Zerren (in Grad) (x,y)
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
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Ja genau daran hatte ich gedacht wobei mir eigentlich auch schon eine RotateImage Procedure reichen würd. Hab sowas im Codearchiv gefunden aber da kann ich keinen Winkel angeben
.
[Edit]
Hab gerad in der API rumgestöbert und bin drauf gekommen das ich das wahrscheinlich manuell über die Winkelfunktionen mache. Bin aber offen für schnellere Varianten
.
[/Edit]
Gruß
Scarabol

[Edit]
Hab gerad in der API rumgestöbert und bin drauf gekommen das ich das wahrscheinlich manuell über die Winkelfunktionen mache. Bin aber offen für schnellere Varianten

[/Edit]
Gruß
Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea
PB-V: 4
WinXP
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea
PB-V: 4
WinXP
Code: Alles auswählen
Procedure DisplaySprite3D_Paint(Sprite, x, y, xZoom, yZoom, xZerr.f, yZerr.f, Trans)
xZerr = xZerr*(#PI/180)
yZerr = -yZerr*(#PI/180)
TransformSprite3D(Sprite, x+Tan(xZerr)*xZoom, y, x+xZoom+Tan(xZerr)*xZoom, y+Tan(yZerr)*xZoom, x+xZoom, y+yZoom+Tan(yZerr)*xZoom, x, y+yZoom)
DisplaySprite3D(Sprite, x, y, Trans)
EndProcedure
INFO:
xZoom, yZoom müssen in Pixel abgegeben werden (also die Sprite Größe)
xZerr, yZerr müssen in Grad angegeben werden, aber nur -89° bis 89°
Also wie in Paint
habe es auchgetestet, ergebnis ist wie in Paint

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
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
- 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
Hi Scarabol, ...
da Du ja immer nur von "Bild" aber nirgends von "Sprite" gesprochen hast, weiss ich natürlich nicht ob Du in Deinem Programm überhaupt Screens und Sprites benutzt und ob sich Dein Anliegen überhaupt mit den von Stargate vorgeschlagenen Sprite(3D) Befehlen realisieren lässt.
Falls es Dir also um die Rotation von Images und nicht von Sprites geht, kannst Du ja mal HIER nachschauen, ob Du mit der Routine was anfangen kannst.
Es gibt sowohl eine reine PB-Lösung (die Plattformübergreifend laufen sollte) als auch eine schnellere aber dafür eben auf Windows limitierte WinAPI-Version (weiter hinten im Thread).
Vermutlich ist das aber noch alles in PB3.94, so dass Du's noch auf PB4 umsetzen müsstest.
Gruß und viel Erfolg, PL.
da Du ja immer nur von "Bild" aber nirgends von "Sprite" gesprochen hast, weiss ich natürlich nicht ob Du in Deinem Programm überhaupt Screens und Sprites benutzt und ob sich Dein Anliegen überhaupt mit den von Stargate vorgeschlagenen Sprite(3D) Befehlen realisieren lässt.
Ich hatte damals mal eine Rotationsroutine (inkl. Filterung) geschrieben, mit der man Bilder in jedem beliebigen Winkel drehen kann.Scarabol hat geschrieben:... wobei mir eigentlich auch schon eine RotateImage Procedure reichen würd. Hab sowas im Codearchiv gefunden aber da kann ich keinen Winkel angeben.
Falls es Dir also um die Rotation von Images und nicht von Sprites geht, kannst Du ja mal HIER nachschauen, ob Du mit der Routine was anfangen kannst.
Es gibt sowohl eine reine PB-Lösung (die Plattformübergreifend laufen sollte) als auch eine schnellere aber dafür eben auf Windows limitierte WinAPI-Version (weiter hinten im Thread).
Vermutlich ist das aber noch alles in PB3.94, so dass Du's noch auf PB4 umsetzen müsstest.
Gruß und viel Erfolg, PL.

[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
Da er nicht mit 3DSprites arbeiten wollte würde PlgBlt schon etwas bringen. Ich habe mal ein kleines Beispiel dazu geschrieben, bei gleichen Winkeln für x und y geht auch drehen ohne Probleme.STARGÅTE hat geschrieben: Ich glaube das hilft ihm auch nicht weiter.
[...]
Code: Alles auswählen
EnableExplicit
UseJPEGImageDecoder()
;- Prozedur Zerren, verformt ein Bild in ImgSource zu hdcDest. Bezugspunkt ist die untere linke Ecke
; -> Source: ImageNr, falls *imgRect = 0 - Devicecontext des Sourceimage ansonsten
; *imgRect: Ausschnitt aus hdcSource, falls Source hdc, ansonsten 0, falls ImageNr. übergeben wird
; xAngle, yAngle: Winkel, um den verzerrt werden soll
; xZoom, yZoom: Faktor, um den skaliert werden soll
; Maske: Maske, die bestimmt, welche Bits berücksichtigt werden sollen (ImageID bzw. Bitmaphandle)
; mx, my: Startpunkt, ab der die Maske benutzt werden soll
Procedure Zerren(Source, hdcDest, *imgRect.RECT, xAngle.d, yAngle.d, xZoom.d = 1, yZoom.d = 1, Maske = 0, mx = 0, my = 0)
Protected x, y, w, h, hz, wz, hdcSrc
Dim Plg.POINT(2) ; Array für Paralelogramm
If *imgRect = 0
; Source ist ein Image, Abmessungen von Image holen
x = 0
y = 0
w = ImageWidth(Source)
h = ImageHeight(Source)
Else
; Source ist ein Devicekontext, Abmessungen aus *imgRect
x = *imgRect\left
y = *imgRect\top
w = (*imgRect\right - *imgRect\left)
h = (*imgRect\bottom - *imgRect\top)
EndIf
; Gezoomte Breite und Höhe bestimmen um damit das Parallelogramm zu berechnen
wz = w * xZoom
hz = h * yZoom
;Parallelogramm berechnen
Plg(0)\x = hz * Tan(xAngle)
Plg(0)\y = 0
Plg(1)\x = wz + hz * Tan(xAngle)
Plg(1)\y = wz * Tan(yAngle)
Plg(2)\x = 0
Plg(2)\y = hz
If Plg(0)\x < 0
;Falls gezerrtes Image nach links gestaucht wird so weit nach rechts verschieben bis kein negatives x vorhanden
Plg(1)\x + Plg(0)\x
Plg(2)\x + Plg(0)\x
Plg(0)\x = 0
EndIf
If Plg(1)\y < 0
;Falls gezerrtes Image nach oben gestaucht wird so weit nach unten verschieben bis kein negatives y vorhanden
Plg(0)\y + Plg(1)\y
Plg(2)\y + Plg(1)\y
Plg(1)\y = 0
EndIf
If *imgRect = 0
; hdcSrc muß erstellt werden, der einfachheit halber mit Hilfe des DestHDC
hdcSrc = CreateCompatibleDC_(hdcDest)
SelectObject_(hdcSrc, ImageID(Source))
Else
hdcSrc = Source
EndIf
PlgBlt_(hdcDest, @Plg(0), hdcSrc, x, y, w, h, Maske, mx, my)
EndProcedure
#WND_MAIN = 0
#ima_Picture = 0
#ima_Mask = 1
#ima_Dest = 2
; Gadgetkonstanten
Enumeration
#img_Picture
#btn_Load
#str_Picture
#btn_LoadMask
#str_Mask
#str_AngleX
#str_AngleY
#str_ZoomX
#str_ZoomY
#str_SrcLeft
#str_SrcTop
#str_SrcRight
#str_SrcBottom
#str_MaskLeft
#str_MaskTop
#btn_Start
EndEnumeration
;Konstanten für funktionslose Gadgets
Enumeration #PB_Compiler_EnumerationValue
#txt_AngleX
#txt_AngleY
#txt_ZoomX
#txt_ZoomY
#txt_SrcLeft
#txt_SrcTop
#txt_SrcRight
#txt_SrcBottom
#txt_MaskLeft
#txt_MaskTop
EndEnumeration
Define.l Event, hwnd, AngleX.d, AngleY.d, ZoomX.d, ZoomY.d, x, y, w, h
Define.l imaDest, hdcDest, hdcSrc, SrcRect.RECT
Define.s File, Mask
hwnd = OpenWindow(#WND_MAIN, 0, 0, 800, 600, "PlgBlt", #PB_Window_SystemMenu)
CreateGadgetList(hwnd)
ImageGadget(#img_Picture, 0, 0, 700, 600, 0, #PB_Image_Border)
ButtonGadget(#btn_Load, 710, 10, 80, 30, "Laden")
StringGadget(#str_Picture, 700, 45, 100, 20, "", #PB_String_ReadOnly)
ButtonGadget(#btn_LoadMask, 710, 75, 80, 30, "Maske")
StringGadget(#str_Mask, 700, 110, 100, 20, "", #PB_String_ReadOnly)
TextGadget(#txt_AngleX, 710, 140, 80, 15, "X Winkel")
StringGadget(#str_AngleX, 710, 160, 80, 20, "0")
TextGadget(#txt_AngleY, 710, 185, 80, 15, "Y Winkel")
StringGadget(#str_AngleY, 710, 205, 80, 20, "0")
TextGadget(#txt_ZoomX, 710, 235, 80, 15, "Zoom X")
StringGadget(#str_ZoomX, 710, 255, 80, 20, "1")
TextGadget(#txt_ZoomY, 710, 280, 80, 15, "Zoom Y")
StringGadget(#str_ZoomY, 710, 300, 80, 20, "1")
TextGadget(#txt_SrcLeft, 710, 330, 20, 20, "SL")
StringGadget(#str_SrcLeft, 735, 330, 55,20, "-1")
TextGadget(#txt_SrcTop, 710, 355, 20, 20, "ST")
StringGadget(#str_SrcTop, 735, 355, 55,20, "0")
TextGadget(#txt_SrcRight, 710, 380, 20, 20, "SR")
StringGadget(#str_SrcRight, 735, 380, 55,20, "0")
TextGadget(#txt_SrcBottom, 710, 405, 20, 20, "SB")
StringGadget(#str_SrcBottom, 735, 405, 55,20, "0")
TextGadget(#txt_MaskLeft, 710, 435, 20, 20, "ML")
StringGadget(#str_MaskLeft, 735, 435, 55,20, "0")
TextGadget(#txt_MaskTop, 710, 460, 20, 20, "SB")
StringGadget(#str_MaskTop, 735, 460, 55,20, "0")
ButtonGadget(#btn_Start, 710, 560, 80, 30, "Start")
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Gadget
Select EventGadget()
Case #btn_Load
File = OpenFileRequester("Bild wählen", "", "Bilddateien (*.jpg;*.jpeg;*.bmp)|*.jpg;*.jpeg;*.bmp|JPG Dateien (*.jpg;*.jpeg)|*.jpg;*.jpeg|Bitmap Dateien (*.bmp)|*.bmp|Alle Dateien (*.*)|*.*", 0)
If File <> ""
LoadImage(#ima_Picture, File)
If ImageWidth(#ima_Picture) > 700
ResizeImage(#ima_Picture, 700, ImageHeight(#ima_Picture) * 700 / ImageWidth(#ima_Picture))
EndIf
SetGadgetState(#img_Picture, ImageID(#ima_Picture))
SetGadgetText(#str_Picture, GetFilePart(File))
SetGadgetText(#str_SrcLeft, "0")
SetGadgetText(#str_SrcTop, "0")
SetGadgetText(#str_SrcRight, Str(ImageWidth(#img_Picture)))
SetGadgetText(#str_SrcBottom, Str(ImageHeight(#img_Picture)))
EndIf
Case #btn_LoadMask
File = OpenFileRequester("Bild wählen", "", "Bilddateien (*.jpg;*.jpeg;*.bmp)|*.jpg;*.jpeg;*.bmp|JPG Dateien (*.jpg;*.jpeg)|*.jpg;*.jpeg|Bitmap Dateien (*.bmp)|*.bmp|Alle Dateien (*.*)|*.*", 0)
If File <> ""
LoadImage(#ima_Mask, File)
SetGadgetText(#str_Mask, GetFilePart(File))
Else
FreeImage(#ima_Mask)
SetGadgetText(#str_Mask, "")
EndIf
Case #btn_Start
AngleX = ValD(GetGadgetText(#str_AngleX)) * 3.14159 / 180
AngleY = ValD(GetGadgetText(#str_AngleY)) * 3.14159 / 180
ZoomX = ValD(GetGadgetText(#str_ZoomX))
ZoomY = ValD(GetGadgetText(#str_ZoomY))
CreateImage(#ima_Dest, 700, 600)
hdcDest = StartDrawing(ImageOutput(#ima_Dest))
hdcSrc = CreateCompatibleDC_(hdcDest)
SelectObject_(hdcSrc, ImageID(#ima_Picture))
SrcRect\left = Val(GetGadgetText(#str_SrcLeft))
SrcRect\top = Val(GetGadgetText(#str_SrcTop))
SrcRect\right = Val(GetGadgetText(#str_SrcRight))
SrcRect\bottom = Val(GetGadgetText(#str_SrcBottom))
If IsImage(#ima_Mask)
Zerren(hdcSrc, hdcDest, @SrcRect, AngleX, AngleY, ZoomX, ZoomY, ImageID(#ima_Mask), Val(GetGadgetText(#str_MaskLeft)), Val(GetGadgetText(#str_MaskTop)))
Else
Zerren(hdcSrc, hdcDest, @SrcRect, AngleX, AngleY, ZoomX, ZoomY)
EndIf
DeleteDC_(hdcSrc)
StopDrawing()
SetGadgetState(#img_Picture, ImageID(#ima_Dest))
EndSelect
EndIf
Until Event = #PB_Event_CloseWindow
Sollen Drehwinkel über 90° zulässig sein muß der Teil wo die Koordinaten für das Parallelogramm berechnet werden entsprechend angepasst werden.