xsharp.eu • Resize pictures
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.