Page 1 of 2

(Solved) math for resising images for screen display

Posted: Wed Dec 16, 2015 5:06 am
by Fangbeast
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

Re: math for resising images for screen display

Posted: Wed Dec 16, 2015 8:29 am
by infratec
Hi,

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
It took so long, cause I need to write a working code :wink:

But...
The height of the taskbar is not included.

Bernd

Re: math for resising images for screen display

Posted: Wed Dec 16, 2015 9:23 am
by TI-994A
Fangbeast wrote:...resize it so it looks fairly 'natural' (Close to the original image) and centre on screen.
If, by looking fairly natural, you mean to proportionately display an image at full-screen size, this should do it:

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
Here's a slightly more fancy version that initially sizes the window to the dimensions of the image (if it's not bigger), and resizes and centres the image as the window is resized:

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
Hope it helps; assuming it's what you're looking for, of course. :wink:

Re: math for resising images for screen display

Posted: Wed Dec 16, 2015 11:44 am
by infratec
Ups..

forgot 'ScreenCentered'.

Is fixed now.

Re: math for resising images for screen display

Posted: Wed Dec 16, 2015 11:50 am
by infratec
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

Re: math for resising images for screen display

Posted: Wed Dec 16, 2015 11:47 pm
by Fangbeast
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
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?

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.

Re: math for resising images for screen display

Posted: Thu Dec 17, 2015 3:08 am
by RASHAD
Hi Fang
Taking the Task Bar Size & Position into consideration
With some modification it will be fantastic (Your turn now :D )

# 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
# 2:
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
Edit :Enhanced and bugs fixed

Re: math for resising images for screen display

Posted: Thu Dec 17, 2015 5:28 am
by fromVB
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
Perfect! Exactly what I needed - a generic aspect ratio calculator. Thank you TI-994A! :D

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

Re: math for resising images for screen display

Posted: Thu Dec 17, 2015 6:33 am
by TI-994A
fromVB wrote:...why do you open the window and image gadget twice?
Thanks, fromVB. Glad you find it useful.

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. :wink:

Re: math for resising images for screen display

Posted: Thu Dec 17, 2015 9:37 am
by davido
@TI-994A,

An excellent, concise, example.
Thank you very much for sharing. :D

Re: math for resising images for screen display

Posted: Thu Dec 17, 2015 10:10 am
by infratec
A new try.

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
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

Re: math for resising images for screen display

Posted: Thu Dec 17, 2015 10:37 am
by Fangbeast
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.

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

Re: math for resising images for screen display

Posted: Thu Dec 17, 2015 12:20 pm
by Fangbeast
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.

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

Re: math for resising images for screen display

Posted: Thu Dec 17, 2015 12:21 pm
by infratec
I avoid API were I can to be crossplatform :mrgreen:

Re: math for resising images for screen display

Posted: Thu Dec 17, 2015 1:06 pm
by Fangbeast
infratec wrote:I avoid API were I can to be crossplatform :mrgreen:
That's fair enough but after you said "It was hell", I thought of an easier way:):)

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!