Page 1 of 3
Resize pictures
Posted: Thu Jan 14, 2021 12:51 pm
by Horst
Hallo
I need a tool to reduce the size of a picture and i found one in C#.
Now i translated it to xSharp and it works. But i am not sure if i realy did it well or if i will run into troubles. Because C# has many things i dont understand.
Can one of you check it ? The prg includes the c# code also is in the attachement.
Thanks Horst
Resize pictures
Posted: Thu Jan 14, 2021 1:27 pm
by SHirsch
Hello Horst,
you just ignored the using statement.
BEGIN USING oImage ....
BEGIN USING oNewImage ....
oNewImage:Save....
END USING
END USING
BEGIN USING oGraphics ....
oGraphics:Draw....
END USING
Otherwise the native resources will not be freed. So you built a classic memory leak.
You could also call oImage:Dispose at the end (and for oImage and oGrahics).
Stefan
Resize pictures
Posted: Thu Jan 14, 2021 1:47 pm
by Horst
Hello Stefan
Yes, because of this Using i wasnt sure and scared. So i changed it to :
FUNCTION ScaleAndSave(cFileIn AS STRING, cFileOut AS STRING) AS VOID
LOCAL oImage AS Image
LOCAL oNewImage AS Image
BEGIN USING oImage := Image:FromFile(cFileIn)
BEGIN USING oNewImage := ScaleImage(oImage, 350, 350)
oNewImage:Save(cFileOut , ImageFormat.Jpeg)
END USING
END USING
RETURN NIL
FUNCTION ScaleImage(oImage AS Image, maxWidth AS FLOAT, maxHeight AS FLOAT)
LOCAL oGraphics AS Graphics
LOCAL oNewImage AS Bitmap
LOCAL newWidth AS INT
LOCAL newHeight AS INT
LOCAL ratioX AS FLOAT
LOCAL ratioY AS FLOAT
LOCAL ratio AS USUAL
ratioX := maxWidth / oImage:Width
ratioY := maxHeight / oImage:Height
ratio := Math.Min(ratioX, ratioY)
newWidth := Integer (oImage:Width * ratio)
newHeight := Integer (oImage:Height * ratio)
oNewImage := Bitmap{newWidth, newHeight}
BEGIN USING oGraphics := Graphics.FromImage(oNewImage)
oGraphics:DrawImage(oImage, 0, 0, newWidth, newHeight)
END USING
RETURN oNewImage
i will use it with USING, so i have a example in my code. But i prefere the Dispose() like
Aclass := yx{parameter}
Aclass:Do()
Aclass:Dispose()
For me its more readable.
Thanks a lot
Resize pictures
Posted: Thu Jan 14, 2021 1:52 pm
by Horst
Still a little worried about Local
Once i learned a local variable will be removed after the return statement of a function .
So this is not allways true ?
Horst
Resize pictures
Posted: Thu Jan 14, 2021 1:59 pm
by SHirsch
What do you mean?
In ScaleAndSave you cannot access the local variable oGraphics whichs is using in ScaleImage. You can use oNewImage which is created in ScaleImage because this is your return value. The name of the variable in ScaleAndSave does not have to be oNewImage (which is the same as in ScaleImage). This could be called oScaledImage. So the reference of oNewImage in ScaleImage and oScaledImage (or in your case also oNewImage) in ScaleAndSave is the same.
Maybe this was your question?
Stefan
Resize pictures
Posted: Thu Jan 14, 2021 2:11 pm
by FFF
LOCAL oImage AS Image
LOCAL oNewImage AS Image
....
Return
I think he expected both locals to be destroyed after the Return by GC
Resize pictures
Posted: Thu Jan 14, 2021 2:17 pm
by Horst
Hi FFF
Yes thats what i expect
Resize pictures
Posted: Thu Jan 14, 2021 2:59 pm
by SHirsch
Horst,
the object is not destroyed because the reference is returned and still used in the calling method. When the calling method returns the object will be destroyed. Objects will be destroyed if it is not referenced any more.
Stefan
Resize pictures
Posted: Thu Jan 14, 2021 3:03 pm
by FFF
Stefan,
the locals ARE in the calling method, so after leaving the caller, they should be destroyed. If so, why the need for Using in ScaleAndSave()?
Resize pictures
Posted: Thu Jan 14, 2021 3:17 pm
by SHirsch
Than I did not understand the question.
A managed object is removed from memory when it's not referenced anymore.
This is the case for both variables in ScaleAndSave (oImage and oNewImage).
BUT in ScaleImage the object 'oNewImage' is NOT destroyed after returning to ScaleAndSave. Otherwise it could'nt be used in ScaleAndSave.
BEGIN USING ensures that 'Dispose' is called at the end of the USING block (even if an error is thrown). You can call Dispose manually as Horst has written. But the managed object still remains in memory until it is not referenced anymore. Dispose just frees all unmanaged resources that are used internally. In ScaleAndSave the object oNewImage will be destroyed after returning to the calling method.