Date: 02-16-2022
Return to Index
created by gbSnippets
'Compiler Comments:
'This code is written to compile in PBWin10. To compile in PBWin9, split pt
'into pt.x and pt.y as arguments wherever the PtInRect() API is used (3 places).
'Compilable Example: (Jose Includes)
#Compiler PBWin 10
#Compile EXE
#Dim All
%Unicode=1
#Include "win32api.inc"
#Resource "gbsnippets.pbr"
Type gbPoint
x As Long 'new x position
y As Long 'new y position
col As Long 'color of pixel
End Type
%IDC_Graphic = 501
%IDC_LabelA = 502
%IDC_LabelB = 503
%IDC_Button1 = 504
%IDC_Button2 = 505
%IDC_Button3 = 506
Global hDlg,hBMP As Dword, ImageH, ImageW As Long, trc As Rect
Global ContainerW, ContainerH, XCenter, YCenter As Long
Function PBMain() As Long
Dialog New Pixels, 0, "Rotate Image",300,300,375,300, %WS_SysMenu, 0 To hDlg
Control Add Label, hDlg, %IDC_LabelA, "<timer results>", 10,10,100,20
Control Add Label, hDlg, %IDC_LabelB, "", 10,260,200,20
Control Add Button, hDlg, %IDC_Button1,"Set Pixel", 10,70,80,20
Control Add Button, hDlg, %IDC_Button2,"CVL / MKL", 10,100,80,20
Control Add Button, hDlg, %IDC_Button3,"Pointer", 10,130,80,20
Control Add Graphic, hDlg, %IDC_Graphic,"", 125,10,200,200
Dialog Show Modal hDlg Call DlgProc
End Function
CallBack Function DlgProc() As Long
Local T As Quad, i As Long
Static theta As Single
Select Case Cb.Msg
Case %WM_InitDialog
'put Resource image into memory bitmap - get WxH of the image
Graphic Bitmap Load "cowgirl", 0, 0 To hBMP
Graphic Attach hBMP, 0
Graphic Get Client To ImageW,ImageH
'get size of graphic control (must be big enough to hold rotated image)
Graphic Attach hDlg, %IDC_Graphic
Graphic Get Client To ContainerW, ContainerH 'HxW of graphic control
XCenter = ContainerW/2 : YCenter = ContainerH/2 'center of rotation in graphic control
theta = 0.3
trc.nleft = 0 : trc.nright = ImageW-1 : trc.ntop = 0 : trc.nbottom = ImageH-1 'orig image boundaries
Case %WM_LButtonDblClk
Graphic Attach hDlg, %IDC_Graphic
Graphic Clear
Case %WM_MouseWheel
Select Case Hi(Integer,Cb.WParam) 'note the use of Integer
Case > 0 : theta = theta + 0.2 : Graphic Attach hDlg, %IDC_Graphic,ReDraw : Graphic Clear : RotateImageC(theta)
Case < 0 : theta = theta - 0.2 : Graphic Attach hDlg, %IDC_Graphic,ReDraw : Graphic Clear : RotateImageC(theta)
End Select
Case %WM_Command
Select Case Cb.Ctl
Case %IDC_Button1 : Tix T : RotateImageA(theta) : Tix End T : Control Set Text hDlg, %IDC_LabelA, Format$(T, "###,###,###")
Case %IDC_Button2 : Tix T : RotateImageB(theta) : Tix End T : Control Set Text hDlg, %IDC_LabelA, Format$(T, "###,###,###")
Case %IDC_Button3 : Tix T : RotateImageC(theta) : Tix End T : Control Set Text hDlg, %IDC_LabelA, Format$(T, "###,###,###")
End Select
End Select
End Function
Sub RotateImageA(theta As Single)
Local x1,x2,y1,y2,x,y As Long, sintheta, costheta As Single
Local BoundW, BoundH, XStart, YStart, iColor As Long, pt as Point
'pre-calculate some values
sintheta = Sin(theta) : costheta = Cos(theta)
'get size of rectangle that will bound the rotated image
BoundW = ImageW*Abs(Costheta) + ImageH*Abs(Sintheta)
BoundH = ImageH*Abs(Costheta) + ImageW*Abs(Sintheta)
'calculate coordinates of the bounding box (enclosing the rotated points)
x1 =(ContainerW-BoundW)/2 : y1 =(ContainerH-BoundH)/2
x2 = x1 + BoundW - 1 : y2 = y1 + BoundH - 1
For x = x1 To x2
For y = y1 To y2
XStart = XCenter + (x - XCenter) * Costheta - (y - YCenter) * Sintheta 'unrotated x
YStart = YCenter + (x - XCenter) * Sintheta + (y - YCenter) * Costheta 'unrotated y
Graphic Attach hBMP, 0, Redraw
Graphic Get Pixel (XStart-XCenter/2,YStart-YCenter/2) To iColor
Graphic Attach hDlg, %IDC_Graphic, Redraw
pt.x = XStart-XCenter/2 : pt.y = YStart-YCenter/2
Graphic Set Pixel (x,y), IIF(PtInRect(trc, pt), iColor, %RGB_LightBlue)
Next y
Next x
Graphic Box (x1-1,y1-1)-(x2+1,y2+1),, %Red
Graphic ReDraw
Control Set Text hDlg, %IDC_LabelB, str$(ImageW) + str$(ImageH) + str$(ContainerW) + str$(ContainerH) + str$(BoundW) + str$(BoundH) + str$(x1) + str$(y1) + str$(x2) + str$(y2)
End Sub
Sub RotateImageB(theta As Single)
Local x1,x2,y1,y2,x,y As Long, sintheta, costheta As Single
Local BoundW, BoundH, XStart, YStart, iColor As Long, pt as Point
Local bmp_source$, bmp_target$
'pre-calculate some values
sintheta = Sin(theta) : costheta = Cos(theta)
'get size of rectangle that will bound the rotated image
BoundW = ImageW*Abs(Costheta) + ImageH*Abs(Sintheta)
BoundH = ImageH*Abs(Costheta) + ImageW*Abs(Sintheta)
'calculate coordinates of the bounding box (enclosing the rotated points)
x1 =(ContainerW-BoundW)/2 : y1 =(ContainerH-BoundH)/2
x2 = x1 + BoundW - 1 : y2 = y1 + BoundH - 1
'work with bit strings from each image
Graphic Attach hBMP, 0, Redraw : Graphic Get Bits To bmp_source$
Graphic Attach hDlg, %IDC_Graphic, Redraw : Graphic Get Bits To bmp_target$
For x = x1 To x2
For y = y1 To y2
XStart = XCenter + (x - XCenter) * Costheta - (y - YCenter) * Sintheta 'unrotated x
YStart = YCenter + (x - XCenter) * Sintheta + (y - YCenter) * Costheta 'unrotated y
iColor = Cvl(bmp_source$, ((yStart-YCenter/2)*ImageW+(xStart-XCenter/2))*4+8 )
pt.x = XStart-XCenter/2 : pt.y = YStart-YCenter/2
Mid$(bmp_target$,(y*ContainerW+x)*4+8,4) = IIF$(PtInRect(trc,pt),Mkl$(iColor),Mkl$(BGR(%RGB_LightGray)))
Next y
Next x
Graphic Set Bits bmp_target$
Graphic Box (x1-1,y1-1)-(x2+1,y2+1),, %Red
Graphic ReDraw
Control Set Text hDlg, %IDC_LabelB, str$(ImageW) + str$(ImageH) + str$(ContainerW) + str$(ContainerH) + str$(BoundW) + str$(BoundH) + str$(x1) + str$(y1) + str$(x2) + str$(y2)
End Sub
Sub RotateImageC(theta As Single)
Local x1,x2,y1,y2,x,y As Long, sintheta, costheta As Single
Local BoundW, BoundH, XStart, YStart, iColor As Long
Local bmp_source$, bmp_target$, pt as Point
Local PixelPTR_source, PixelPTR_target As Long PTR, iSource, iTarget As Long
'pre-calculate some values
sintheta = Sin(theta) : costheta = Cos(theta)
'get size of rectangle that will bound the rotated image
BoundW = ImageW*Abs(Costheta) + ImageH*Abs(Sintheta)
BoundH = ImageH*Abs(Costheta) + ImageW*Abs(Sintheta)
'calculate coordinates of the bounding box (enclosing the rotated points)
x1 =(ContainerW-BoundW)/2 : y1 =(ContainerH-BoundH)/2
x2 = x1 + BoundW - 1 : y2 = y1 + BoundH - 1
'work with bit strings from each image
Graphic Attach hBMP, 0, Redraw : Graphic Get Bits To bmp_source$
Graphic Attach hDlg, %IDC_Graphic, Redraw : Graphic Get Bits To bmp_target$
PixelPTR_source = StrPtr(bmp_source$) + 8 : iSource = PixelPTR_source
PixelPTR_target = StrPtr(bmp_target$) + 8 : iTarget = PixelPTR_target
For x = x1 To x2
For y = y1 To y2
XStart = XCenter + (x - XCenter) * Costheta - (y - YCenter) * Sintheta 'unrotated x
YStart = YCenter + (x - XCenter) * Sintheta + (y - YCenter) * Costheta 'unrotated y
PixelPTR_source = iSource + ((YStart-YCenter/2)*ImageW+(XStart-XCenter/2))*4
PixelPTR_target = iTarget + (y * ContainerW + x ) * 4
pt.x = XStart-XCenter/2 : pt.y = YStart-YCenter/2
@PixelPTR_target = IIf(PtInRect(trc,pt) , @PixelPTR_source, Bgr(%RGB_Moccasin))
Next y
Next x
Graphic Set Bits bmp_target$
Graphic Box (x1-1,y1-1)-(x2+1,y2+1),, %Red
Graphic ReDraw
Control Set Text hDlg, %IDC_LabelB, str$(ImageW) + str$(ImageH) + str$(ContainerW) + str$(ContainerH) + str$(BoundW) + str$(BoundH) + str$(x1) + str$(y1) + str$(x2) + str$(y2)
End Sub
'gbs_00911
'Date: 03-10-2012
http://www.garybeene.com/sw/gbsnippets.htm