[C#]Save van Bitmap gaat niet soepel

Pagina: 1
Acties:

  • degroot
  • Registratie: December 2003
  • Niet online
Ik ben bezig met een applicatie die images kan resizen.
Het resizen gebeurt dmv de volgende code
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
        public void resizeImagePercentage(string locatie,double percentage)
        {
            Bitmap bmp = new Bitmap(locatie);
            int width = Convert.ToInt32(bmp.Width * percentage);
            int heigth = Convert.ToInt32(bmp.Height * percentage);
     
            Bitmap resizedbmp = new Bitmap(bmp, new Size(width, heigth));
            bmp.Dispose();
            Thread.Sleep(3500);

            resizedbmp.Save(locatie);
            resizedbmp.Dispose();
        }

Deze code staat in de klasse resize.cs.
Vanuit het hoofdformulier word deze functie aangeroepen dmv deze code
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if (rdbtnResizeWH.Checked == true)
            {//function for resizing the image on the user given sizes
                try
                {   //
                    resize.resizeImagePercentage(txtModImage.Text, Convert.ToInt32(txtResizeHeigth.Text), Convert.ToInt32(txtResizeWidth.Text));
                    //show a message to the user when the image is successfully converted
                    MessageBox.Show("De afbeelding is succesvol geresized");
                    //show the new image into the previewscreen ,  with new width,heigth and size
                    picboxMod.Image = print.makeThumb(txtModImage.Text);
                }
                catch(Exception er)
                {//when the image fails to resize ,  provide the complete exception message to the user
                    string error = er.ToString();
                    MessageBox.Show(error);
                }


Zoals je ziet word de image geresized , dat gaat allemaal goed.
Alleen als hij hem wilt saven , dan begint de ellende.
De ene keer saved hij wel de image die geresized is , en de andere keer niet.
dit is gewoon willekeurig , dus er zit geen volgorde in.

Ik zat er dus aan te denken , dat voor het saven misschien niet alle resources goed worden gedisposed omdat dat misschien tijd in beslag neemt.
Dus heb ik er een Thread.sleep ingezet zoals je kunt zien.
Maar ook dit is allemaal zonder succes.
Er word gewoon weer willekeurig een exception gevangen , en de andere keer word er gewoon weer netjes gesaved.

Ik heb ook een screenie gemaakt van de gevangen exception.
[img=http://img143.imageshack.us/img143/7575/untitledwv6.th.jpg]

Het rare vind ik , dat ik deze error dus random krijg , en niet steeds iedere keer(of nog liever , iedere keer niet :9 )
Ik denk zelf dat het te maken heeft dus met het disposen van de resources , dat dat niet goed gaat, maar daarvoor had ik juist weer die thread.sleep ingebouwd.

Het heeft mij iig wel op een vreemd spor gezet :o

www.degroot-it.nl


  • whoami
  • Registratie: December 2000
  • Laatst online: 18:04
Die Sleep is iig nutteloos.

Als die foutmelding zich voordoet, kijk dan eens naar de InnerException bv, en kijk eens wat daar in staat.
Weet je ook wat regel 101 is ; de regel waar de exceptie gegooid wordt ?
Iig, wat hier nodig is, is dat jij een beetje je code gaat debuggen en evt tracen. Ga na op welke regel die exceptie exact gegooid wordt, log de exceptie, log de innerexception, en ga adhv die informatie op onderzoek uit.

Ik zou trouwens zowiezo, iig de bmp slechts disposen nadat je de resized bmp gesaved hebt.

een beetje googlen op de foutboodschap helpt ook meestal...
klik

[ Voor 49% gewijzigd door whoami op 17-11-2006 13:52 ]

https://fgheysels.github.io/


  • pjonk
  • Registratie: November 2000
  • Laatst online: 22-11 20:39
Wat ik altijd doe is eerst de boel naar een MemoryStream schrijven waarna je een byte array terugkrijgt. Deze byte array schrijf ik vervolgens in een binary file.
Probleem met Save aanroepen op een Filestream is dat je van die nietszeggende Generic GDI+ exceptions krijgt als bijv. een file opslaat op een path dat niet bestaat of waar je geen schrijfrechten hebt. Op deze manier kan je alle IO errors netjes afvangen.
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
MemoryStream ms = new MemoryStream();
bool isResized = false;
try {
    dstBmp.Save(ms, _jpgCodec, _jpgCodecParams);
    isResized = true;
}
catch (System.Runtime.InteropServices.ExternalException ex) {
    // a Generic GDI+ exception occurred
    _log.Error(string.Format("ImageID[{0}] unexpected error when making thumb ImageID[{0}], direction {1}", m_sImageID, direction), ex);
}
// Save the memory stream which contains the image data to a file
FileStream fs = null;
try {
    byte[] result = ms.ToArray();
    fs = System.IO.File.OpenWrite("c:\\bla.bmp");
    fs.Write(result, 0, result.Length);
}
catch (IOException ex) {
    _log.Error(string.Format("IOError when saving thumbnail {0}", saveFile), ex);
}
finally {
    if ((!fs == null))
    {
        fs.Close();
    }
}

It’s nice to be important but it’s more important to be nice


  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 20:39

TeeDee

CQB 241

offtopic:
nette oplossing pjonk. Ik gooi hem in mijn code snippets als je het niet erg vind ;)

Heart..pumps blood.Has nothing to do with emotion! Bored


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Ik dacht dat Bitmaps een raar verhaal waren onder .NET:
als je de originele bitmap disposed worden de unmanaged resources ter beschikking gesteld.
Afhankelijk van het finalizen zal je tweede object dus nog de bitmap handle kunnen aanspreken of niet.

Laat je origineel object dus leven tot na het opslaan.

ASSUME makes an ASS out of U and ME


  • degroot
  • Registratie: December 2003
  • Niet online
Wow , ik zie wel dat jullie mij al aardig op weg geholpen hebben.
Helaas heb ik mijn programmeer project morgen pas weer bij de hand , dus kan het nu helaas niet uit proberen.
Ik had zelf al wel het idee dat Bitmaps idd niet echt lekker soepel gaat in .Net , maar waarschijnlijk met de oplossing van de 2e post , schiet ik bes een eind op(wel beetje ingewikkeld , ben pas beginner)

Maar ik zal morgen zsm in deze post laten weten of het mij al een beetje gelukt is...
Moet haast wel lukken nu , en iig alvast bedankt voor de zuivere en snelle hulp

Morgen zullen julliue het resultaat zien ;)

www.degroot-it.nl


Verwijderd

Tip: alleen Dispose() aanroepen als 't echt noodzakelijk is. De garbage collector van .NET ruimt t.z.t. de objecten die niet meer worden gereferenced zelf wel op. Daar is 'ie voor aangenomen... ;)

Verwijderd

Verwijderd schreef op zaterdag 18 november 2006 @ 00:22:
Tip: alleen Dispose() aanroepen als 't echt noodzakelijk is. De garbage collector van .NET ruimt t.z.t. de objecten die niet meer worden gereferenced zelf wel op. Daar is 'ie voor aangenomen... ;)
Tip: Doe precies het tegenovergestelde van bovenstaande tip.

Objecten die IDisposable implementeren doen dat (meestal) niet voor niets en gebruiken 'kostbare' al dan niet unmanaged resources. Zulke objecten moet je liefst zo snel mogelijk disposen, tenzij het echt niet anders kan.
Doe een Dispose bij voorkeur in een finally-block, zodat je object ook vrijgegeven wordt als er een exceptie optreedt. Of gebruik het (in mijn ogen superhandige) 'using'-statement.

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Inderdaad. Dispose kan je het best zo snel mogenlijk aanroepen. Dispose doet meestal niet meer als je native resources vrij geven. De garbage collector zal er daarna op een moment dat hij dat geschikt acht alsnog de managed resources vrij geven.

Objecten die IDisposable implementeren gebruik ik dan meestal ook in een using blok of ik dispose ze in de dispose van mijn eigen object als ik ze over meerdere methoden nodig heb.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Pagina: 1