(Solved) math for resising images for screen display
- Fangbeast
- PureBasic Protozoa
- Posts: 4790
- Joined: Fri Apr 25, 2003 3:08 pm
- Location: Not Sydney!!! (Bad water, no goats)
(Solved) math for resising images for screen display
I want to take an image from a database (i can do that), resize it on screen to account for the window frame widths and titlebar height, resize it so it looks fairly 'natural' (Close to the original image) and centre on screen.
I am having a little trouble with the math though. The example below has vague references to gadgets and windows and is only attempting to illustrate my illogic and not reproduce the entire 11,000 line program.
Can anyone see where I am going wrong with my math? Yes, I know I don't know what I am doing when it comes to math calculations so tell me something I don't know:):)
ExamineDesktops()
..Get the desktop work area
DesktopWidth.i = DesktopWidth(0)
DesktopHeight.i = DesktopHeight(0)
..Get the menu and frame widths of the opened window
WinFrameWidth.i = (WindowWidth(#MyWindow, #PB_Window_FrameCoordinate) - WindowWidth(#MyWindow, #PB_Window_InnerCoordinate)) / 2
TitleBarHeight.i = GetWindowTitleBarDetails(#MyWindow)
..The original height and width of a picture loaded from a database blob
PictureHorizontal.i = 2022
PictureVertical.i = 800
..Do desktop related height and width calculations before displaying
HorizontalWidth.i = PictureHorizontal.i - (WinFrameWidth.i * 2)
VerticalHeight.i = PictureVertical.i - TitleBarHeight.i - (WinFrameWidth.i * 2)
..Some debug stuff for me
Debug "Current window frame width: " + Str(WinFrameWidth.i)
Debug "Current window titlebar height: " + Str(TitleBarHeight.i)
Debug "Original picture width: " + Picture\Horizontal
Debug "Original picture height: " + Picture\Vertical
Debug "Picture width minus frame: " + Str(HorizontalWidth.i)
Debug "Picture height minus frame: " + Str(VerticalHeight.i)
..Do desktop related height and width calculations before displaying
If HorizontalWidth.i > DesktopWidth ; If the horizontal width is greater than the desktop
NewWidth.i = DesktopWidth ; Resize it to the desktop width minus the menu bar and frame
ElseIf HorizontalWidth.i < DesktopWidth ; If the horizontal width is less than the desktop
NewWidth.i = PictureHorizontal) ; Resize it to the original picture width minus the menu bar and frame
EndIf
..
If VerticalHeight.i > DesktopHeight ; If the vertical height is greater than the desktop
NewHeight.i = DesktopHeight ; Resize it to the desktop height
ElseIf VerticalHeight.i < DesktopHeight ; If the vertical height is less than the desktop
NewHeight.i = PictureVertical ; Resize it To the original picture minus the menu bar And frame
EndIf
..Now set the resized image to the image gadget
If PictureHandle.i
ResizeWindow(#MyWindow, #PB_Ignore, #PB_Ignore, NewWidth.i, Newheight.i)
ResizeGadget(#MyGadget, #PB_Ignore, #PB_Ignore, NewWidth.i, Newheight.i)
ResizeImage(PictureHandle.i, NewWidth.i, Newheight.i, #PB_Image_Smooth)
SetGadgetState(#MyGadget, ImageID(PictureHandle.i))
EndIf
I am having a little trouble with the math though. The example below has vague references to gadgets and windows and is only attempting to illustrate my illogic and not reproduce the entire 11,000 line program.
Can anyone see where I am going wrong with my math? Yes, I know I don't know what I am doing when it comes to math calculations so tell me something I don't know:):)
ExamineDesktops()
..Get the desktop work area
DesktopWidth.i = DesktopWidth(0)
DesktopHeight.i = DesktopHeight(0)
..Get the menu and frame widths of the opened window
WinFrameWidth.i = (WindowWidth(#MyWindow, #PB_Window_FrameCoordinate) - WindowWidth(#MyWindow, #PB_Window_InnerCoordinate)) / 2
TitleBarHeight.i = GetWindowTitleBarDetails(#MyWindow)
..The original height and width of a picture loaded from a database blob
PictureHorizontal.i = 2022
PictureVertical.i = 800
..Do desktop related height and width calculations before displaying
HorizontalWidth.i = PictureHorizontal.i - (WinFrameWidth.i * 2)
VerticalHeight.i = PictureVertical.i - TitleBarHeight.i - (WinFrameWidth.i * 2)
..Some debug stuff for me
Debug "Current window frame width: " + Str(WinFrameWidth.i)
Debug "Current window titlebar height: " + Str(TitleBarHeight.i)
Debug "Original picture width: " + Picture\Horizontal
Debug "Original picture height: " + Picture\Vertical
Debug "Picture width minus frame: " + Str(HorizontalWidth.i)
Debug "Picture height minus frame: " + Str(VerticalHeight.i)
..Do desktop related height and width calculations before displaying
If HorizontalWidth.i > DesktopWidth ; If the horizontal width is greater than the desktop
NewWidth.i = DesktopWidth ; Resize it to the desktop width minus the menu bar and frame
ElseIf HorizontalWidth.i < DesktopWidth ; If the horizontal width is less than the desktop
NewWidth.i = PictureHorizontal) ; Resize it to the original picture width minus the menu bar and frame
EndIf
..
If VerticalHeight.i > DesktopHeight ; If the vertical height is greater than the desktop
NewHeight.i = DesktopHeight ; Resize it to the desktop height
ElseIf VerticalHeight.i < DesktopHeight ; If the vertical height is less than the desktop
NewHeight.i = PictureVertical ; Resize it To the original picture minus the menu bar And frame
EndIf
..Now set the resized image to the image gadget
If PictureHandle.i
ResizeWindow(#MyWindow, #PB_Ignore, #PB_Ignore, NewWidth.i, Newheight.i)
ResizeGadget(#MyGadget, #PB_Ignore, #PB_Ignore, NewWidth.i, Newheight.i)
ResizeImage(PictureHandle.i, NewWidth.i, Newheight.i, #PB_Image_Smooth)
SetGadgetState(#MyGadget, ImageID(PictureHandle.i))
EndIf
Last edited by Fangbeast on Fri Dec 18, 2015 7:24 am, edited 1 time in total.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
Re: math for resising images for screen display
Hi,
try this:
It took so long, cause I need to write a working code
But...
The height of the taskbar is not included.
Bernd
try this:
Code: Select all
#MyWindow = 0
#MyGadget = 0
Define.f WidthFactor, HeightFactor, Factor
ExamineDesktops()
;..Get the desktop work area
DesktopWidth = DesktopWidth(0)
DesktopHeight = DesktopHeight(0)
Debug "Desktop: " + Str(DesktopWidth) + " x " + Str(DesktopHeight)
OpenWindow(#MyWindow, 0, 0, 300, 200, "FangBeast Resizer", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ImageGadget(#MyGadget, 0, 0, 0, 0, 0)
WinFrameWidth.i = (WindowWidth(#MyWindow, #PB_Window_FrameCoordinate) - WindowWidth(#MyWindow, #PB_Window_InnerCoordinate))
WinFrameHeigth.i = (WindowHeight(#MyWindow, #PB_Window_FrameCoordinate) - WindowHeight(#MyWindow, #PB_Window_InnerCoordinate))
;..The original height And width of a picture loaded from a database blob
PictureHandle = CreateImage(#PB_Any, 4022, 1000)
PictureWidth = ImageWidth(PictureHandle)
PictureHeight = ImageHeight(PictureHandle)
NewWinWidth = PictureWidth + WinFrameWidth
NewWinHeight = PictureHeight + WinFrameHeigth
;..Do desktop related height And width calculations before displaying
WidthFactor = 1.0
HeightFactor = 1.0
Factor = 1.0
If NewWinWidth > DesktopWidth
Debug "A"
WidthFactor = DesktopWidth / NewWinWidth
EndIf
If NewWinHeight > DesktopHeight
Debug "B"
HeightFactor = DesktopWidth / NewWinHeight
EndIf
If WidthFactor < HeightFactor
Factor = WidthFactor
EndIf
If HeightFactor < WidthFactor
Factor = HeightFactor
EndIf
Debug Factor
;..Some Debug stuff For me
Debug "NewWindow (outer size): " + Str(NewWinWidth * Factor) + " x " + Str(NewWinHeight * Factor)
NewWinWidth = NewWinWidth * Factor - WinFrameWidth
NewWinHeight = NewWinHeight * Factor - WinFrameHeigth
Debug "NewWindow (inner size): " + Str(NewWinWidth) + " x " + Str(NewWinHeight)
;..Now set the resized image To the image gadget
If PictureHandle
Debug "Located at: " + Str((DesktopWidth - NewWinWidth - WinFrameWidth) / 2) + " / " + Str((DesktopHeight - NewWinHeight - WinFrameHeigth) / 2)
ResizeWindow(#MyWindow, (DesktopWidth - NewWinWidth - WinFrameWidth) / 2, (DesktopHeight - NewWinHeight - WinFrameHeigth) / 2, NewWinWidth, NewWinHeight)
ResizeImage(PictureHandle.i, NewWinWidth, NewWinHeight, #PB_Image_Smooth)
SetGadgetState(#MyGadget, ImageID(PictureHandle.i))
EndIf
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow

But...
The height of the taskbar is not included.
Bernd
Last edited by infratec on Wed Dec 16, 2015 11:48 am, edited 2 times in total.
Re: math for resising images for screen display
If, by looking fairly natural, you mean to proportionately display an image at full-screen size, this should do it:Fangbeast wrote:...resize it so it looks fairly 'natural' (Close to the original image) and centre on screen.
Code: Select all
LoadImage(0, #PB_Compiler_Home + "Examples/Sources/Data/Geebee2.bmp")
wFlags = #PB_Window_SystemMenu | #PB_Window_Maximize
OpenWindow(0, #PB_Any, #PB_Any, 400, 200, "ImageViewer", wFlags)
aspectRatio.f = ImageHeight(0) / ImageWidth(0)
imgWidth = WindowWidth(0)
imgHeight = imgWidth * aspectRatio
img_X = 0
img_Y = (WindowHeight(0) - imgHeight) / 2
If imgHeight > WindowHeight(0)
aspectRatio = ImageWidth(0) / ImageHeight(0)
imgHeight = WindowHeight(0)
imgWidth = imgHeight * aspectRatio
img_X = (WindowWidth(0) - imgWidth) / 2
img_Y = 0
EndIf
ResizeImage(0, imgWidth, imgHeight)
ImageGadget(0, img_X, img_Y, 0, 0, ImageID(0))
While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend
Code: Select all
UseJPEGImageDecoder()
UsePNGImageDecoder()
Procedure SizeImage()
CopyImage(1, 0)
aspectRatio.f = ImageHeight(0) / ImageWidth(0)
imgWidth = WindowWidth(0)
imgHeight = imgWidth * aspectRatio
img_X = 0
img_Y = (WindowHeight(0) - imgHeight) / 2
If imgHeight > WindowHeight(0)
aspectRatio = ImageWidth(0) / ImageHeight(0)
imgHeight = WindowHeight(0)
imgWidth = imgHeight * aspectRatio
img_X = (WindowWidth(0) - imgWidth) / 2
img_Y = 0
EndIf
If imgWidth And imgHeight
ResizeImage(0, imgWidth, imgHeight)
SetGadgetState(0, ImageID(0))
ResizeGadget(0, img_X, img_Y, #PB_Ignore, #PB_Ignore)
EndIf
EndProcedure
imgTypes.s = "Images|*.bmp;*.jpg;*.png | All files (*.*) | *.*"
If LoadImage(1, OpenFileRequester("Select Image:", "", imgTypes, 0))
wFlags = #PB_Window_MaximizeGadget | #PB_Window_Maximize |
#PB_Window_ScreenCentered | #PB_Window_SizeGadget
OpenWindow(0, #PB_Any, #PB_Any, 600, 400, "ImageViewer", wFlags)
ImageGadget(0, 0, 0, 0, 0, 0)
If ImageWidth(1) > WindowWidth(0) Or ImageHeight(1) > WindowHeight(0)
SizeImage()
Else
wFlags ! #PB_Window_Maximize
OpenWindow(0, #PB_Any, #PB_Any, ImageWidth(1), ImageHeight(1), "", wFlags)
ImageGadget(0, 0, 0, 0, 0, ImageID(1))
EndIf
BindEvent(#PB_Event_SizeWindow, @SizeImage())
While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend
EndIf

Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel 

Re: math for resising images for screen display
Ups..
forgot 'ScreenCentered'.
Is fixed now.
forgot 'ScreenCentered'.
Is fixed now.
Re: math for resising images for screen display
It looks like that ResizeWindow() is buggy at x and y.
It looks that the border of the window is not respected.
Hm....
Maybe it's a win7 behaviour, because if you maximize any program, you don't see the rounded edges of the windows.
Bernd
It looks that the border of the window is not respected.
Hm....
Maybe it's a win7 behaviour, because if you maximize any program, you don't see the rounded edges of the windows.
Bernd
- Fangbeast
- PureBasic Protozoa
- Posts: 4790
- Joined: Fri Apr 25, 2003 3:08 pm
- Location: Not Sydney!!! (Bad water, no goats)
Re: math for resising images for screen display
But something else went wrong with your code here. Desktop Height was 900, you created an image of 1000 as a height but resized it (vertically) to 1/3r'd of the desktop?infratec wrote:It looks like that ResizeWindow() is buggy at x and y.
It looks that the border of the window is not respected.
Hm....
Maybe it's a win7 behaviour, because if you maximize any program, you don't see the rounded edges of the windows.
Bernd
What I wanted to do was:
If image is smaller than the desktop, no resizing must occur, must be centred in the window
If image is larger than the desktop (vertical AND horizontal), it must be resized to the desktop size.
If image vertical OR horizontal is larger than the desktop, some sort of proportional resizing must occur.
Sometimes, only one dimension is larger than the desktop (Either vertical or horizontal) and resizing looks odd when I try it. (Squashed, squished, squashed).
Paint Shop Pro (Years ago) had a lovely image resampler for their resizing filter that made any image look good resized, even when it was stamp sized. Would have loved to have that.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
Re: math for resising images for screen display
Hi Fang
Taking the Task Bar Size & Position into consideration
With some modification it will be fantastic (Your turn now
)
# 1:
# 2:
No API
Edit :Enhanced and bugs fixed
Taking the Task Bar Size & Position into consideration
With some modification it will be fantastic (Your turn now

# 1:
Code: Select all
UsePNGImageDecoder()
UseJPEGImageDecoder()
UseJPEG2000ImageDecoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()
Procedure Sizeh()
If IsImage(0)
CopyImage(0,1)
GetClientRect_(WindowID(0),cr.RECT)
hScale.f = (cr\right-cr\left)/ImageWidth(1)
vScale.f = (cr\bottom-cr\top)/ImageHeight(1)
If hScale > vScale
Scale.f = vScale*0.9
Else
Scale.f = hScale*0.9
EndIf
ResizeImage(1,Scale*ImageWidth(1),Scale*ImageHeight(1))
x = (cr\right-cr\left-ImageWidth(1))/2
y = (cr\bottom-ImageHeight(1))/2
SetGadgetState(0,ImageID(1))
ResizeGadget(0,x,y,ImageWidth(1),ImageHeight(1))
ResizeGadget(1,10,cr\bottom-30,80,20)
Else
GetClientRect_(WindowID(0),cr.RECT)
ResizeGadget(1,10,cr\bottom-30,80,20)
EndIf
EndProcedure
OpenWindow(0,0,0,800,600,"Window & TaskBar",#PB_Window_SystemMenu| #PB_Window_MaximizeGadget| #PB_Window_ScreenCentered|#PB_Window_SizeGadget)
ImageGadget(0,0,0,40,40,0)
ButtonGadget(1,10,570,80,20,"Load Image")
BindEvent(#PB_Event_SizeWindow,@Sizeh())
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Quit = 1
Case #PB_Event_Gadget
Select EventGadget()
Case 1
FileName$ = OpenFileRequester("Open image", "", "All supported formats|*.bmp;*.gif;*.jpg;*.jpeg|BMP image (*.bmp)|*.bmp|JPEG image (*.jpg;*.jpeg)|*.jpg;*.jpeg|GIF image (*.gif)|*.gif", 0)
If FileName$
LoadImage(0,FileName$)
CopyImage(0,1)
GetClientRect_(WindowID(0),cr.RECT)
hScale.f = (cr\right-cr\left)/ImageWidth(1)
vScale.f = (cr\bottom-cr\top)/ImageHeight(1)
If hScale > vScale
Scale.f = vScale*0.9
Else
Scale.f = hScale*0.9
EndIf
ResizeImage(1,Scale*ImageWidth(1),Scale*ImageHeight(1))
x = (cr\right-cr\left-ImageWidth(1))/2
y = (cr\bottom-ImageHeight(1))/2
SetGadgetState(0,ImageID(1))
ResizeGadget(0,x,y,ImageWidth(1),ImageHeight(1))
ResizeGadget(1,10,cr\bottom-30,80,20)
EndIf
EndSelect
Case #PB_Event_MaximizeWindow
If IsImage(0)
CopyImage(0,1)
SystemParametersInfo_(#SPI_GETWORKAREA,0,r.RECT,0)
GetClientRect_(WindowID(0),cr.RECT)
hScale.f = (r\right-r\left)/ImageWidth(1)
vScale.f = (r\bottom-r\top)/ImageHeight(1)
If hScale > vScale
Scale.f = vScale
Else
Scale.f = hScale
EndIf
ResizeImage(1,Scale*ImageWidth(1),Scale*ImageHeight(1))
x = (cr\right-cr\left-ImageWidth(1))/2
y = (cr\bottom-ImageHeight(1))/2
SetGadgetState(0,ImageID(1))
ResizeGadget(0,x,y,ImageWidth(1),ImageHeight(1))
ResizeGadget(1,10,cr\bottom-30,80,20)
EndIf
EndSelect
Until Quit = 1
No API
Code: Select all
UsePNGImageDecoder()
UseJPEGImageDecoder()
UseJPEG2000ImageDecoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()
Procedure Sizeh()
If IsImage(0)
CopyImage(0,1)
hScale.f = WindowWidth(0,#PB_Window_InnerCoordinate)/ImageWidth(1)
vScale.f = WindowHeight(0,#PB_Window_InnerCoordinate)/ImageHeight(1)
If hScale > vScale
Scale.f = vScale*0.9
Else
Scale.f = hScale*0.9
EndIf
ResizeImage(1,Scale*ImageWidth(1),Scale*ImageHeight(1))
x = (WindowWidth(0,#PB_Window_InnerCoordinate)-ImageWidth(1))/2
y = (WindowHeight(0,#PB_Window_InnerCoordinate)-ImageHeight(1))/2
SetGadgetState(0,ImageID(1))
ResizeGadget(0,x,y,ImageWidth(1),ImageHeight(1))
ResizeGadget(1,10,WindowHeight(0,#PB_Window_InnerCoordinate)-30,80,20)
Else
ResizeGadget(1,10,WindowHeight(0,#PB_Window_InnerCoordinate)-30,80,20)
EndIf
EndProcedure
OpenWindow(0,0,0,800,600,"Window & TaskBar",#PB_Window_SystemMenu| #PB_Window_MaximizeGadget| #PB_Window_ScreenCentered|#PB_Window_SizeGadget)
ImageGadget(0,0,0,40,40,0)
ButtonGadget(1,10,570,80,20,"Load Image")
BindEvent(#PB_Event_SizeWindow,@Sizeh())
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Quit = 1
Case #PB_Event_Gadget
Select EventGadget()
Case 1
FileName$ = OpenFileRequester("Open image", "", "All supported formats|*.bmp;*.gif;*.jpg;*.jpeg|BMP image (*.bmp)|*.bmp|JPEG image (*.jpg;*.jpeg)|*.jpg;*.jpeg|GIF image (*.gif)|*.gif", 0)
If FileName$
LoadImage(0,FileName$)
CopyImage(0,1)
hScale.f = WindowWidth(0,#PB_Window_InnerCoordinate)/ImageWidth(1)
vScale.f = WindowHeight(0,#PB_Window_InnerCoordinate)/ImageHeight(1)
If hScale > vScale
Scale.f = vScale*0.9
Else
Scale.f = hScale*0.9
EndIf
ResizeImage(1,Scale*ImageWidth(1),Scale*ImageHeight(1))
x = (WindowWidth(0,#PB_Window_InnerCoordinate)-ImageWidth(1))/2
y = (WindowHeight(0,#PB_Window_InnerCoordinate)-ImageHeight(1))/2
SetGadgetState(0,ImageID(1))
ResizeGadget(0,x,y,ImageWidth(1),ImageHeight(1))
ResizeGadget(1,10,WindowHeight(0,#PB_Window_InnerCoordinate)-30,80,20)
EndIf
EndSelect
Case #PB_Event_MaximizeWindow
If IsImage(0)
CopyImage(0,1)
hScale.f = WindowWidth(0,#PB_Window_InnerCoordinate)/ImageWidth(1)
vScale.f = WindowHeight(0,#PB_Window_InnerCoordinate)/ImageHeight(1)
If hScale > vScale
Scale.f = vScale
Else
Scale.f = hScale
EndIf
ResizeImage(1,Scale*ImageWidth(1),Scale*ImageHeight(1))
x = (WindowWidth(0,#PB_Window_InnerCoordinate)-ImageWidth(1))/2
y = (WindowHeight(0,#PB_Window_InnerCoordinate)-ImageHeight(1))/2
SetGadgetState(0,ImageID(1))
ResizeGadget(0,x,y,ImageWidth(1),ImageHeight(1))
ResizeGadget(1,10,WindowHeight(0,#PB_Window_InnerCoordinate)-30,80,20)
EndIf
EndSelect
Until Quit = 1
Egypt my love
Re: math for resising images for screen display
Perfect! Exactly what I needed - a generic aspect ratio calculator. Thank you TI-994A!TI-994A wrote:Code: Select all
UseJPEGImageDecoder() UsePNGImageDecoder() Procedure SizeImage() CopyImage(1, 0) aspectRatio.f = ImageHeight(0) / ImageWidth(0) imgWidth = WindowWidth(0) imgHeight = imgWidth * aspectRatio img_X = 0 img_Y = (WindowHeight(0) - imgHeight) / 2 If imgHeight > WindowHeight(0) aspectRatio = ImageWidth(0) / ImageHeight(0) imgHeight = WindowHeight(0) imgWidth = imgHeight * aspectRatio img_X = (WindowWidth(0) - imgWidth) / 2 img_Y = 0 EndIf If imgWidth And imgHeight ResizeImage(0, imgWidth, imgHeight) SetGadgetState(0, ImageID(0)) ResizeGadget(0, img_X, img_Y, #PB_Ignore, #PB_Ignore) EndIf EndProcedure imgTypes.s = "Images|*.bmp;*.jpg;*.png | All files (*.*) | *.*" If LoadImage(1, OpenFileRequester("Select Image:", "", imgTypes, 0)) wFlags = #PB_Window_MaximizeGadget | #PB_Window_Maximize | #PB_Window_ScreenCentered | #PB_Window_SizeGadget OpenWindow(0, #PB_Any, #PB_Any, 600, 400, "ImageViewer", wFlags) ImageGadget(0, 0, 0, 0, 0, 0) If ImageWidth(1) > WindowWidth(0) Or ImageHeight(1) > WindowHeight(0) SizeImage() Else wFlags ! #PB_Window_Maximize OpenWindow(0, #PB_Any, #PB_Any, ImageWidth(1), ImageHeight(1), "", wFlags) ImageGadget(0, 0, 0, 0, 0, ImageID(1)) EndIf BindEvent(#PB_Event_SizeWindow, @SizeImage()) While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend EndIf

One question: why do you open the window and image gadget twice?

Re: math for resising images for screen display
Thanks, fromVB. Glad you find it useful.fromVB wrote:...why do you open the window and image gadget twice?
Rather than fiddling with desktops, the simplest approach would be to obtain the full-screen dimensions from a maximized window. This saves a lot of hassle, especially if there are multiple desktops.
However, if the image dimensions are smaller than a maximized window, the window (same window number) is re-initialised without the maximized flag, while still benefiting from the screen-centred flag. Again, this saves the hassle of fiddling with desktops to centre the window. Accordingly, if the window is re-initialised, the image gadget has to be as well.
It should also be noted that the DesktopWidth() and DesktopHeight() functions do not account for the desktop's taskbar.
Hope it answers your question.

Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel 

Re: math for resising images for screen display
@TI-994A,
An excellent, concise, example.
Thank you very much for sharing.
An excellent, concise, example.
Thank you very much for sharing.

DE AA EB
Re: math for resising images for screen display
A new try.
It was a nightmare to retrieve the taskbar size.
It works now on Win7 (others not tested)
But still:
If you place a window at 0 not the whole Frame is shown (on Win7) which results in 4 to 6 pixel offset.
Bernd
It was a nightmare to retrieve the taskbar size.
It works now on Win7 (others not tested)
Code: Select all
#PictureWidth = 1000
#PictureHeigth = 4000
#MyWindow = 0
#MyGadget = 0
Define.f WidthFactor, HeightFactor, Factor
ExamineDesktops()
DesktopWidth = DesktopWidth(0)
DesktopHeight = DesktopHeight(0)
Debug "Desktop: " + Str(DesktopWidth) + " x " + Str(DesktopHeight)
TestWin = OpenWindow(#PB_Any, 0, 0, 0, 0, "", #PB_Window_SystemMenu|#PB_Window_Invisible|#PB_Window_Maximize)
Debug "MaxWinInner: " + Str(WindowWidth(TestWin, #PB_Window_InnerCoordinate)) + " x " + Str(WindowHeight(TestWin, #PB_Window_InnerCoordinate))
Debug "MaxWinOuter: " + Str(WindowWidth(TestWin, #PB_Window_FrameCoordinate)) + " x " + Str(WindowHeight(TestWin, #PB_Window_FrameCoordinate))
Debug "WinLocation: " + Str(WindowX(TestWin)) + " / " + Str(WindowY(TestWin))
TaskBarHeight = WindowHeight(TestWin, #PB_Window_FrameCoordinate) - WindowHeight(TestWin, #PB_Window_InnerCoordinate) - WindowY(TestWin)
CloseWindow(TestWin)
Debug "Taskbarheight: " + Str(TaskBarHeight) + " horror to get this!"
OpenWindow(#MyWindow, 0, 0, 300, 200, "FangBeast Resizer", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ImageGadget(#MyGadget, 0, 0, 0, 0, 0)
WinFrameWidth.i = (WindowWidth(#MyWindow, #PB_Window_FrameCoordinate) - WindowWidth(#MyWindow, #PB_Window_InnerCoordinate))
WinFrameHeigth.i = (WindowHeight(#MyWindow, #PB_Window_FrameCoordinate) - WindowHeight(#MyWindow, #PB_Window_InnerCoordinate))
Debug "Winframewidth: " + Str(WinFrameWidth)
Debug "Winframeheight: " + Str(WinFrameHeigth)
;..The original height And width of a picture loaded from a database blob
PictureHandle = CreateImage(#PB_Any, #PictureWidth, #PictureHeigth)
PictureWidth = ImageWidth(PictureHandle)
PictureHeight = ImageHeight(PictureHandle)
MaxInnerWidth = DesktopWidth - WinFrameWidth
MaxInnerHeight = DesktopHeight - WinFrameHeigth - TaskBarHeight
Debug "MaxInner: " + Str(MaxInnerWidth) + " x " + Str(MaxInnerHeight)
;..Do desktop related height And width calculations before displaying
WidthFactor = 1.0
HeightFactor = 1.0
Factor = 1.0
If PictureWidth > MaxInnerWidth
Debug "A"
WidthFactor = MaxInnerWidth / PictureWidth
EndIf
If PictureHeight > MaxInnerHeight
Debug "B"
HeightFactor = MaxInnerHeight / PictureHeight
EndIf
If WidthFactor < HeightFactor
Factor = WidthFactor
EndIf
If HeightFactor < WidthFactor
Factor = HeightFactor
EndIf
Debug Factor
;..Some Debug stuff For me
NewWinWidth = PictureWidth * Factor
NewWinHeight = PictureHeight * Factor
Debug "NewWindow (inner size): " + Str(NewWinWidth) + " x " + Str(NewWinHeight)
;..Now set the resized image To the image gadget
If PictureHandle
Debug "Located at: " + Str((DesktopWidth - NewWinWidth - WinFrameWidth) / 2) + " / " + Str((DesktopHeight - NewWinHeight - WinFrameHeigth - TaskBarHeight) / 2)
ResizeWindow(#MyWindow, (DesktopWidth - NewWinWidth - WinFrameWidth) / 2, (DesktopHeight - NewWinHeight - WinFrameHeigth - TaskBarHeight) / 2, NewWinWidth, NewWinHeight)
ResizeImage(PictureHandle.i, NewWinWidth, NewWinHeight, #PB_Image_Smooth)
SetGadgetState(#MyGadget, ImageID(PictureHandle.i))
EndIf
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
If you place a window at 0 not the whole Frame is shown (on Win7) which results in 4 to 6 pixel offset.
Bernd
- Fangbeast
- PureBasic Protozoa
- Posts: 4790
- Joined: Fri Apr 25, 2003 3:08 pm
- Location: Not Sydney!!! (Bad water, no goats)
Re: math for resising images for screen display
Hi Bernd. While I doubt I will be able to understand anybody's code, I will do my best to integrate it into the picture database.
And, I found the following titlebar api in the forum and worked it into my code.
And, I found the following titlebar api in the forum and worked it into my code.
Code: Select all
; Windows title bar constants
#CCHILDREN_TITLEBAR = 5
; Title bar structure
Structure TITLEBARINFO
cbSize.l
rcTitleBar.RECT
rgstate.l[#CCHILDREN_TITLEBAR + 1]
EndStructure
; Get the current windows title bar height from a passed window
Procedure.i GetWindowTitleBarDetails(Window.i)
Protected TitleBarHeight.i
Protected pti.TITLEBARINFO
WindowHandle.i = WindowID(Window.i)
If WindowHandle.i
pti.TITLEBARINFO\cbSize = SizeOf(TITLEBARINFO)
GetTitleBarInfo_(WindowHandle.i, pti)
TitleBarHeight.i = pti\rcTitleBar\bottom - pti\rcTitleBar\top
EndIf
ProcedureReturn TitleBarHeight.i
EndProcedure
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
- Fangbeast
- PureBasic Protozoa
- Posts: 4790
- Joined: Fri Apr 25, 2003 3:08 pm
- Location: Not Sydney!!! (Bad water, no goats)
Re: math for resising images for screen display
Done! Thanks to all people for their valuable input. The below procedure is the fixed module based on Bernd's picture resizing.
Once I have checked the entire program over for any bugs, I will re-upload it to DropBox again.
Once I have checked the entire program over for any bugs, I will re-upload it to DropBox again.
Code: Select all
;====================================
; Show a bigger version of the stored picture
;============================
Procedure ViewCurrentPicture()
;------------------------------------------------------------------------------------------------
;
;------------------------------------------------------------------------------------------------
Program\CurrentLine = GetGadgetState(#Gadget_PiccyDb_Titles)
;------------------------------------------------------------------------------------------------
;
;------------------------------------------------------------------------------------------------
If Program\CurrentLine <> #NothingSelected
;----------------------------------------------------------------------------------------------
;
;----------------------------------------------------------------------------------------------
Program\CurrentRecord = GetGadgetItemText(#Gadget_PiccyDb_Titles, Program\CurrentLine, #RecordColumn)
;----------------------------------------------------------------------------------------------
;
;----------------------------------------------------------------------------------------------
If Program\CurrentRecord <> #EmptyString
;--------------------------------------------------------------------------------------------
; Check if an existing window is opened
;--------------------------------------------------------------------------------------------
If Program\WindowMutex <> #True
;------------------------------------------------------------------------------------------
; Try to open the data form window
;------------------------------------------------------------------------------------------
If Window_PiccyViewer()
;----------------------------------------------------------------------------------------
; Window was opened so set mutex to prevent other windows from opening
;----------------------------------------------------------------------------------------
Program\WindowMutex = #True
;----------------------------------------------------------------------------------------
; Prevent user input on the main window
;----------------------------------------------------------------------------------------
DisableWindow(#Window_PiccyDb, #True)
;----------------------------------------------------------------------------------------
; Setup the common add window message
;----------------------------------------------------------------------------------------
Message.s = "View Current Picture"
;----------------------------------------------------------------------------------------
; Set the last window message for the closure routine later
;----------------------------------------------------------------------------------------
Program\LastWindow = Message.s
;----------------------------------------------------------------------------------------
; Show new record number and status in the data window
;----------------------------------------------------------------------------------------
SetWindowTitle(#Window_PiccyViewer, Message.s)
;----------------------------------------------------------------------------------------
; Add the fast form close keyboard shortcut
;----------------------------------------------------------------------------------------
AddKeyboardShortcut(#Window_PiccyViewer, #PB_Shortcut_Escape, #Shortcut_CloseViewer)
AddKeyboardShortcut(#Window_PiccyViewer, #PB_Shortcut_Alt | #PB_Shortcut_X, #Shortcut_ExitViewer)
;----------------------------------------------------------------------------------------
;
;----------------------------------------------------------------------------------------
QueryString.s = "SELECT m.Title, m.Horizontal, m.Vertical, n.Picture "
QueryString.s + "FROM PictureInfo AS m, PictureData AS n "
QueryString.s + "WHERE n.Record_Id = m.Record_Id "
QueryString.s + "AND m.Record_Id = '" + Program\CurrentRecord + "'"
;----------------------------------------------------------------------------------------
;
;----------------------------------------------------------------------------------------
If DatabaseQuery(Program\DatabaseHandle, QueryString.s) <> #DatabaseQueryFail
;--------------------------------------------------------------------------------------
;
;--------------------------------------------------------------------------------------
While NextDatabaseRow(Program\DatabaseHandle)
;------------------------------------------------------------------------------------
;
;------------------------------------------------------------------------------------
Picture\Title = KillQuote(GetDatabaseString(Program\DatabaseHandle, 0))
Picture\Horizontal = GetDatabaseString(Program\DatabaseHandle, 1)
Picture\Vertical = GetDatabaseString(Program\DatabaseHandle, 2)
;------------------------------------------------------------------------------------
;
;------------------------------------------------------------------------------------
Picture_Length.i = DatabaseColumnSize(Program\DatabaseHandle, 3)
;------------------------------------------------------------------------------------
;
;------------------------------------------------------------------------------------
If Picture_Length.i <> #NoDataFound
*PhotoBlobBuffer = AllocateMemory(Picture_Length.i)
BlobResult.i = GetDatabaseBlob(Program\DatabaseHandle, 3, *PhotoBlobBuffer, Picture_Length.i)
EndIf
;------------------------------------------------------------------------------------
;
;------------------------------------------------------------------------------------
Wend
;--------------------------------------------------------------------------------------
;
;--------------------------------------------------------------------------------------
FinishDatabaseQuery(Program\DatabaseHandle)
;--------------------------------------------------------------------------------------
;
;--------------------------------------------------------------------------------------
SetWindowTitle(#Window_PiccyViewer, GetWindowTitle(#Window_PiccyViewer) + " - Title (" + Picture\Title + ")")
;--------------------------------------------------------------------------------------
;
;--------------------------------------------------------------------------------------
WindowsFrameWidth.i = (WindowWidth(#Window_PiccyViewer, #PB_Window_FrameCoordinate) - WindowWidth(#Window_PiccyViewer, #PB_Window_InnerCoordinate))
WindowsFrameHeigth.i = (WindowHeight(#Window_PiccyViewer, #PB_Window_FrameCoordinate) - WindowHeight(#Window_PiccyViewer, #PB_Window_InnerCoordinate))
TaskBarHeight.i = GetWindowTitleBarDetails(#Window_PiccyViewer)
;--------------------------------------------------------------------------------------
;
;--------------------------------------------------------------------------------------
PictureWidth.i = Val(Picture\Horizontal)
PictureHeight.i = Val(Picture\Vertical)
;--------------------------------------------------------------------------------------
;
;--------------------------------------------------------------------------------------
MaxInnerWidth.i = Program\DesktopWidth - WindowsFrameWidth.i
MaxInnerHeight = Program\DesktopHeight - WindowsFrameHeigth.i - TaskBarHeight.i
;--------------------------------------------------------------------------------------
;
;--------------------------------------------------------------------------------------
WidthFactor.f = 1.0
HeightFactor.f = 1.0
Factor.f = 1.0
;--------------------------------------------------------------------------------------
;
;--------------------------------------------------------------------------------------
If PictureWidth.i > MaxInnerWidth.i
WidthFactor.f = MaxInnerWidth.i / PictureWidth.i
EndIf
If PictureHeight.i > MaxInnerHeight.i
HeightFactor.f = MaxInnerHeight.i / PictureHeight.i
EndIf
If WidthFactor.f < HeightFactor.f
Factor.f = WidthFactor.f
EndIf
If HeightFactor.f < WidthFactor.f
Factor.f = HeightFactor.f
EndIf
;--------------------------------------------------------------------------------------
;
;--------------------------------------------------------------------------------------
NewWindowWidth.i = PictureWidth.i * Factor.f
NewWindowHeight.i = PictureHeight.i * Factor.f
;--------------------------------------------------------------------------------------
;
;--------------------------------------------------------------------------------------
If BlobResult.i <> #NoBlobFound
PictureHandle.i = CatchImage(#PB_Any, *PhotoBlobBuffer)
If PictureHandle.i <> #NoPictureHandle
ResizeWindow(#Window_PiccyViewer, (Program\DesktopWidth - NewWindowWidth.i - WindowsFrameWidth.i) / 2, (Program\DesktopHeight - NewWindowHeight.i - WindowsFrameHeigth.i - TaskBarHeight.i) / 2, NewWindowWidth.i, NewWindowHeight.i)
ResizeImage(PictureHandle.i, NewWindowWidth.i, NewWindowHeight.i, #PB_Image_Smooth)
SetGadgetState(#Gadget_PiccyViewer_picture, ImageID(PictureHandle.i))
EndIf
Else
ResizeImage(#Image_PiccyViewer_picture, #MainPictureWidth, #MainPictureHeight, #PB_Image_Smooth)
SetGadgetState(#Gadget_PiccyViewer_picture, ImageID(#Image_PiccyViewer_picture))
EndIf
;--------------------------------------------------------------------------------------
;
;--------------------------------------------------------------------------------------
SetInfoBarArea("Number", #EmptyString, Picture\RecordId)
;--------------------------------------------------------------------------------------
;
;--------------------------------------------------------------------------------------
Else
SetInfoBarArea("Headings", "Error", "Database query failed or was empty: " + DatabaseError(), "ViewCurrentPicture")
EndIf
;----------------------------------------------------------------------------------------
; Show new record number and status in the main window
;----------------------------------------------------------------------------------------
SetInfoBarArea("Headings", "Info", Message.s + " to the picture database")
;----------------------------------------------------------------------------------------
; Make sure the data form window is topmost
;----------------------------------------------------------------------------------------
SetActiveWindow(#Window_PiccyViewer)
;----------------------------------------------------------------------------------------
; Make sure the version field is selected
;----------------------------------------------------------------------------------------
SetActiveGadget(#Gadget_PiccyViewer_Picture)
;----------------------------------------------------------------------------------------
;
;----------------------------------------------------------------------------------------
Else
SetInfoBarArea("Headings", "Error", "The program window could not be opened.", "ViewCurrentPicture")
EndIf
;------------------------------------------------------------------------------------------
;
;------------------------------------------------------------------------------------------
Else
SetInfoBarArea("Headings", "Warn", "Another program window is still open, close that one first.", "ViewCurrentPicture")
EndIf
;--------------------------------------------------------------------------------------------
;
;--------------------------------------------------------------------------------------------
Else
ResizeImage(#Image_PiccyViewer_picture, #MainPictureWidth, #MainPictureHeight, #PB_Image_Smooth)
SetInfoBarArea("Headings", "Error", "No record number found on line: " + Str(Program\CurrentLine), "ViewCurrentPicture")
EndIf
;----------------------------------------------------------------------------------------------
;
;----------------------------------------------------------------------------------------------
Else
SetInfoBarArea("Headings", "Info", "There is no current line selected", "ViewCurrentPicture")
EndIf
;------------------------------------------------------------------------------------------------
;
;------------------------------------------------------------------------------------------------
EndProcedure
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
Re: math for resising images for screen display
I avoid API were I can to be crossplatform 

- Fangbeast
- PureBasic Protozoa
- Posts: 4790
- Joined: Fri Apr 25, 2003 3:08 pm
- Location: Not Sydney!!! (Bad water, no goats)
Re: math for resising images for screen display
That's fair enough but after you said "It was hell", I thought of an easier way:):)infratec wrote:I avoid API were I can to be crossplatform
This is my changelog for now. New version uploaded to DropBox, I think I gave the link a few posts ago.
1 I fixed the one bug Jumbuk reported in Piccy
2 Fixed a few other things that I had to do
3 Added a few more right click menus over various objects
4 Added double left click on picture in main screen to view the original size. (Also Alt + V)
5 Bernd (InfraTec) helped me fix up the proportional picture resizer, yay!
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet