Picture scale to fit width height of imagewell

How do you scale a picture in an ImageWell such that it fits in the dimensions of the ImageWell?

Windows ?? OSX ??

OSX
ImageWell.Open

declare sub setImageScaling lib "Cocoa" selector "setImageScaling:" _ ( handle as integer, value as integer ) setImageScaling( me.handle, 0 )

That sounds pretty Mac OS specific.

You may want to check the ProportionalScale method posted by Jay Madren at https://forum.xojo.com/17230-is-there-a-simple-way-such-as-property-method-to-scale-image-in

It can be used in a Desktop project, and works cross platform.

Hi Michel,

I am trying to use Jay Madren method at https://forum.xojo.com/17230-is-there-a-simple-way-such-as-property-method-to-scale-image-in as suggested by you in a Desktop project…

I created the function ProportionalScale
with Parameters extends Pic as Picture, Width as integer, Height as Integer
and Return Type Picture

I ran the project but got this…
“The extendsmodifiercannot be used a class method”

How can I fix that?

The code posted by Axel works great on Mac. Thanks Axel.

Is there a similar declare for Windows?

Thanks.

Lennox

I use this function for scaling:

Function ScaleImage(p as Picture, maxWidth as Integer, maxHeight as Integer) As Picture
  // Scales a Picture while keeping the correct aspect ratio
  If p <> Nil Then
    
    // Calculate the scale ratio
    Dim ratio As Double = min(maxHeight / p.height, maxWidth / p.width)
    
    // Create a new picture to return
    Dim newPic As New Picture(p.width * ratio, p.height * ratio)
    
    // Draw picture in the new size
    newPic.graphics.DrawPicture(p, 0, 0, newPic.width, newPic.height, 0, 0, p.width, p.height)
    
    Return newPic
    
  End If
End Function
2 Likes

Hi Marco,

I tried your function and called it like this in the DropObject event of the ImageWell

  Dim ThePicture as Picture
  ThePicture = Picture.Open(obj.folderitem)
  Me.Image = ScaleImage(ThePicture, 124, 124)

does not work, maybe I am doing something incorrectly.

Kindly advise.

Thanks.

Lennox

Oh wait, an ImageWell.
I think these handle the image drop automatically. I don’t use those but I think you need to either somehow grab the image before it’s handled or get it out, resize and then back in.

I suggest using a canvas for this. Not sure if it’s easier but at least you have full control over it. Like this:
https://dl.dropboxusercontent.com/u/609785/Xojo/Forum/dropJpeg.xojo_binary_project

I do it this way:

Dim p as Picture
'assign image to p
p = app.ResizeToFit(p, ImageWell1.Width, ImageWell1.Height)
ImageWell1.Image = p

Function ResizeToFit(p as Picture, maxWidth as Integer, maxHeight as Integer) As Picture
if p <> nil then
’ Calculate the scale ratio

dim ratio as Double = min( maxHeight/p.height, maxWidth/p.width)

' Calculate new size
dim w as integer = p.width * ratio
dim h as integer = p.height * ratio

' Create a new picture to return
dim newPic as new Picture(w, h, 32)

' Draw picture in the new size
newPic.graphics.DrawPicture(p, 0, 0, w, h, 0, 0, p.width, p.height)
return newPic

else
return nil
end if

End Function

[quote=261220:@Lennox Jacob]I ran the project but got this…
“The extendsmodifiercannot be used a class method”[/quote]

You simply want to attach the method to a module and it will work as expected.

Thanks Marco,

I tried your project and it works, but I prefer an image well.
If I cannot get the other suggestions to work I may very well have to use your code, thanks again Marco.

Thanks Tony and Michel,
I just cannot get your suggestions to work, maybe I am doing something wrong.

I put the function in app and I am calling it from the Drop object of the ImageWell.

  '' // ProportionalScale
         --  proportionalScale had to be modified like this - I deleted extends because it would not compile...
       "The extends modifier cannot be used a class method"

Function ProportionalScale(Pic as Picture, Width as integer, Height as Integer) As Picture
// Calculate scale factor
dim factor as Double = min( Height / Pic.Height, Width / Pic.Width )

// Calculate new size
dim w as integer = Pic.Width * factor
dim h as integer = Pic.Height * factor

// create new picture
dim NewPic as new Picture( w, h, 32 )

// draw picture in the new size
NewPic.Graphics.DrawPicture( Pic, 0, 0, w, h, 0, 0, Pic.Width, Pic.Height )

// return scaled image
Return NewPic

End Function

  Dim ThePicture as Picture
  ThePicture = Picture.Open(obj.folderitem)
  Me.Image = app.ProportionalScale( ThePicture, ThePicture.Width, ThePicture.Height )
  
   '// ScaleImage
  Dim ThePicture as Picture
  ThePicture = Picture.Open(obj.folderitem)
 // MyImageView.Picture = MyImage.ProportionalScale( MyImageView.Width, MyImageView.Height ) was modified like this...
 Me.Image = ScaleImage(ThePicture, 124, 124)   

I will try it again.
Thanks again.

Lennox

OK, for an ImageWell DropObject event this is the workaround
https://forum.xojo.com/6298-scaling-dragged-image-to-imagewell/0

Michael Allen 8 Dec 2013 Sunnyvale, CA or elsewhere.
For Cocoa (Mavericks, Xojo 2013r3.3) builds the Imagewell momentarily displays the correctly scaled picture but then displays the unscaled picture.

See bug report 27149 - Cocoa ImageWell automatically adds the image to the well when dragging over.

As the bug report suggests it you move the “iwImage.Image = pPictureOut” into a timer you can work around the problem.

Lennox

Lennox. Read my post.

Instead of putting the function in App, drag a Module in the project, and drag the function to the module. Make sure it is Global, and then it will work just fine.

Extends cannot be used when a method is in in App or attached to a window, or a class. Hence the error.

Thanks Michel, I did not know that… “Extends cannot be used when a method is in in App or attached to a window, or a class”.

I’ll try your suggestion.

Thanks again.

Lennox

extend methods have to be in a module

Thanks Norman.
Lennox

Thanks Michel,

I tried your suggestion and it worked well.

Thanks again.

Lennox

[quote]

I use this function for scaling:

Function ScaleImage(p as Picture, maxWidth as Integer, maxHeight as Integer) As Picture
// Scales a Picture while keeping the correct aspect ratio
If p <> Nil Then

// Calculate the scale ratio
Dim ratio As Double = min(maxHeight / p.height, maxWidth / p.width)

// Create a new picture to return
Dim newPic As New Picture(p.width * ratio, p.height * ratio)

// Draw picture in the new size
newPic.graphics.DrawPicture(p, 0, 0, newPic.width, newPic.height, 0, 0, p.width, p.height)

Return newPic

End If
End Function[/quote]

Hello Marco,

Is a similar method as vb Pic.Scale(x1,y1)-(x2,y2) in xojo ?

No idea. :slight_smile:
The routine I posted is super basic.
If you want to resize a 300x300 picture half the size you tell it to resize to 150x150 and you’re done.
However, if you tell it to resize to 100x150, it will return a 100x100 picture because it keeps the aspect ratio in tact.

If you want a more advanced and better quality resizer, check this routine from Beatrix: https://forum.xojo.com/34206-resize-images-gocomics-uses-xojo/p1#p279702

Check Graphics.DrawPicture. Using all the parameters you can obtain the same.