Code: Alles auswählen
EnableExplicit
; 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
#btn_Pull
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
#Mode_Pull = 0
#Mode_Rotate = 1
#WND_MAIN = 0
Enumeration
#ima_Picture
#ima_Mask
#ima_MaskTmp
#ima_Dest
EndEnumeration
UseJPEGImageDecoder()
;- Prozedur Zerren, verformt ein Bild in ImgSource zu hdcDest. Bezugspunkt ist die untere linke Ecke
; -> Mode: #Mode_Pull: Verzerren; #Mode_Rotate: Drehen
; 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(Mode, Source, hdcDest, *imgRect.RECT, xAngle.d, yAngle.d = 0 , xZoom.d = 1, yZoom.d = 1, Maske = 0, mx = 0, my = 0)
Protected x, y, w, h, hz, wz, d, wk.d, hdcSrc , sz, xmin, xma, ymin, ymax
Dim Plg.POINT(2) ; Array für Paralelogramm
sz = ElapsedMilliseconds()
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 = Int(w * xZoom)
hz = Int(h * yZoom)
;Parallelogramm berechnen
If Mode = #Mode_Pull
Plg(0)\x = Int(hz * Tan(xAngle))
Plg(0)\y = 0
Plg(1)\x = wz + Int(hz * Tan(xAngle))
Plg(1)\y = Int(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)\x < 0
;Falls gezerrtes Image nach links gestaucht wird so weit nach rechts verschieben bis kein negatives x vorhanden
Plg(0)\x - Plg(1)\x
Plg(2)\x - Plg(1)\x
Plg(1)\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
ElseIf Mode = #Mode_Rotate
Plg(0)\x = Int(hz * Sin(xAngle))
Plg(0)\y = hz - Int(hz * Cos(xAngle))
d = Sqr(hz * hz + wz * wz)
wk = ATan(wz / hz)
Plg(1)\x = Int(d * Sin(xAngle + wk))
Plg(1)\y = hz - Int(d * Cos(xAngle + wk))
Plg(2)\x = 0
Plg(2)\y = hz
; Kleinsten x - Wert herausfinden
xmin = Plg(0)\x
If Plg(1)\x < xmin : xmin = Plg(1)\x : EndIf
If Plg(2)\x < xmin : xmin = Plg(2)\x : EndIf
If (Plg(1)\x + Plg(2)\x - Plg(0)\x) < xmin : xmin = Plg(1)\x + Plg(2)\x - Plg(0)\x : EndIf
Plg(0)\x - xmin
Plg(1)\x - xmin
Plg(2)\x - xmin
ymin = Plg(0)\y
If Plg(1)\y < ymin : ymin = Plg(1)\y : EndIf
If Plg(2)\y < ymin : ymin = Plg(2)\y : EndIf
If (Plg(1)\y + Plg(2)\y - Plg(0)\y) < ymin : ymin = Plg(1)\y + Plg(2)\y - Plg(0)\y : EndIf
Plg(0)\y - ymin
Plg(1)\y - ymin
Plg(2)\y - ymin
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)
If *imgRect = 0
DeleteDC_(hdcSrc)
EndIf
SetWindowTitle(#WND_MAIN, "PlgBlt - " + Str(ElapsedMilliseconds() - sz))
EndProcedure
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, "Drehen")
ButtonGadget(#btn_Pull, 710, 525, 80, 30, "Zerren")
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_MaskTmp, File)
If IsImage(#ima_Mask)
FreeImage(#ima_Mask)
EndIf
CreateImage(#ima_Mask, 700, 600, 1)
StartDrawing(ImageOutput(#ima_Mask))
DrawImage(ImageID(#ima_MaskTmp), 0, 0)
StopDrawing()
SetGadgetText(#str_Mask, GetFilePart(File))
Else
If IsImage(#ima_Mask) : FreeImage(#ima_Mask) : EndIf
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(#Mode_Rotate, hdcSrc, hdcDest, @SrcRect, AngleX, AngleY, ZoomX, ZoomY, ImageID(#ima_Mask), Val(GetGadgetText(#str_MaskLeft)), Val(GetGadgetText(#str_MaskTop)))
Else
Zerren(#Mode_Rotate, hdcSrc, hdcDest, @SrcRect, AngleX, AngleY, ZoomX, ZoomY)
EndIf
DeleteDC_(hdcSrc)
StopDrawing()
SetGadgetState(#img_Picture, ImageID(#ima_Dest))
Case #btn_Pull
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(#Mode_Pull, hdcSrc, hdcDest, @SrcRect, AngleX, AngleY, ZoomX, ZoomY, ImageID(#ima_Mask), Val(GetGadgetText(#str_MaskLeft)), Val(GetGadgetText(#str_MaskTop)))
Else
Zerren(#Mode_Pull, hdcSrc, hdcDest, @SrcRect, AngleX, AngleY, ZoomX, ZoomY)
EndIf
DeleteDC_(hdcSrc)
StopDrawing()
SetGadgetState(#img_Picture, ImageID(#ima_Dest))
EndSelect
EndIf
Until Event = #PB_Event_CloseWindow