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
Resize pictures
- Attachments
-
- ScaleAndSave.txt
- (1.93 KiB) Downloaded 137 times
Resize pictures
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
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
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
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
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
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
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
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
LOCAL oImage AS Image
LOCAL oNewImage AS Image
....
Return
I think he expected both locals to be destroyed after the Return by GC
LOCAL oNewImage AS Image
....
Return
I think he expected both locals to be destroyed after the Return by GC
Regards
Karl
(on Win8.1/64, Xide32 2.20, X#2.20.0.3)
Karl
(on Win8.1/64, Xide32 2.20, X#2.20.0.3)
Resize pictures
Hi FFF
Yes thats what i expect
Yes thats what i expect
Resize pictures
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
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
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()?
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()?
Regards
Karl
(on Win8.1/64, Xide32 2.20, X#2.20.0.3)
Karl
(on Win8.1/64, Xide32 2.20, X#2.20.0.3)
Resize pictures
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.
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.