Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB.NET: [VB2008] ja kuvien pienentäminen

Sivun loppuun

AimoKulaus [10.12.2008 14:25:44]

#

Hirmu läjä kuvia pitäisi saada pienennettyä. Koodi kyllä toimii, mutta aina jossain kohtaa tulee ilmoitus Out of memory. Mikäpä neuvoksi?

Testissä on noin 300 kpl 10 megapikselin kuvaa hakemistossa C:\tmp, pikkukuvat pitäisi saada hakemistoon C:\tmp\pikkukuvat\ (Ja Irfanview yms ei nyt tule kysymykseen :-)

VB:ssä formille kaksi pictureboxia ja button, sekä alla oleva koodi

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim a As String
    Dim Hakemisto As String = "C:\tmp\"
    Dim PikkukuvaHakemisto As String = "C:\tmp\pikkukuvat\"

    a = Dir(Hakemisto + "*.jpg")

    Do Until a = ""
        If Microsoft.VisualBasic.Left(a, 2) <> "t_" Then

            Dim fileExists As Boolean
            fileExists = My.Computer.FileSystem.FileExists(PikkukuvaHakemisto + "t_" + a)
            If fileExists = False Then
                PictureBox1.Image = Image.FromFile(Hakemisto + a)
                ResizeKuva(400, 300)
                PictureBox2.Image.Save(PikkukuvaHakemisto + "t_" + a, System.Drawing.Imaging.ImageFormat.Jpeg)
                PictureBox2.Refresh()
            End If
        End If
        a = Dir()
    Loop
End Sub


Private Sub ResizeKuva(ByVal _leveys As Integer, ByVal _korkeus As Integer)
    ' Resize the image.
    Dim sourceBitmap As New Bitmap(PictureBox1.Image)
    Dim destBitmap As New Bitmap(_leveys, _korkeus)
    Dim destGraphic As Graphics = Graphics.FromImage(destBitmap)
    destGraphic.DrawImage(sourceBitmap, 0, 0, destBitmap.Width + 1, destBitmap.Height + 1)
    PictureBox2.Image = destBitmap
End Sub

Grez [10.12.2008 15:09:02]

#

Mitäs jos sanoisit tuolla resizekuva lopussa destGraphic.Dispose(), destBitmap.Dispose() ja sourceBitmap.Dispose()

Kyllähän tuo pitäisi tapahtua automaattisestikin kun menee pois näkyvyysalueelta, mutta siltä varalta että se vapauttelee niitä viiveellä niin tuota voisi kokeilla. En siis takaa että auttaa mitenkään.

AimoKulaus [10.12.2008 15:28:37]

#

Olen kokeillut sitäkin, mutta eipä auta sekään. Myöskään samoihin kohtiin destGraphic = Nothing ja vastaavat ei auta.

neau33 [10.12.2008 22:39:30]

#

Heippa AimoKulaus!

laittaisin ton napin koodin hieman eri muotoon...

Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
   Dim Hakemisto As New System.IO.DirectoryInfo("C:\temp\")
   Dim filut() As System.IO.FileInfo = Hakemisto.GetFiles("*.jpg")
   Dim PikkukuvaHakemisto As String = "C:\tmp\pikkukuvat\"
   If filut.length > 0 Then
      For i As Integer = 0 To filut.GetUpperBound(0)
         If filut(i).ToString.IndexOf("t_") <> 0 Then
            If Dir(PikkukuvaHakemisto + _
            "t_" + filut(i).ToString) = "" Then
               PictureBox1.Image = _
               Image.FromFile(Hakemisto + filut(i).ToString)
               ResizeKuva(400, 300)
               PictureBox2.Refresh()
               Try
                  PictureBox2.Image.Save(PikkukuvaHakemisto + _
                  "t_" + filut(i).ToString, _
                  System.Drawing.Imaging.ImageFormat.Jpeg)
                  Do While Dir(PikkukuvaHakemisto + _
                  "t_" + filut(i).ToString) = ""
                     Application.DoEvents
                  Loop
               Catch ex As Exception
               End Try
            End If
         End If
      Next
   End If
   Hakemisto = Nothing: filut = Nothing
   PikkukuvaHakemisto = Nothing
End Sub

neau33 [11.12.2008 04:24:52]

#

Sorry AimoKulaus!

jäi muuttamatta toi prompti string-muotoon...

...
Image.FromFile(Hakemisto.ToString + ...

AimoKulaus [11.12.2008 19:10:07]

#

Tutkailin alkuperäistä ohjelmaa Tehtävienhallinnan avulla. Muistin käyttö muistutti ohjelmoijan sydänkäyrää, eli välillä käyrä nousi ylöspäin, kunnes putosi taas alas, nousi ylös, putosi alas jne, eli sahanterää. Näin kai sen pitääkin mennä, eli ohjelma varailee muistia, kunnes se loppuu, tekee sitten roskien keruun eli Garbage collectionin ja jatkaa taas. Jostain syystä tuo ei aina toimi, ja ohjelma pysähtyi virheeseen. (Siis Microsoftin vika ;-)

Homman saa näköjään onnistumaan kun pakottaa Garbage collectionin joka kuvan jälkeen, eli alkuperäiseen ohjelmakoodiin lisäys tuon Dirrin eteen:

GC.Collect()
a = Dir()

Tämä kai hidastaa ohjelman toimintaa, mutta parempi sekin kuin ei toimintaa ollenkaan. (Tosin en ole ihan varma tuon Garbage collectionin toiminnasta kaikkine sukupolvineen ja generationeineen...)

neau33 [12.12.2008 01:58:18]

#

Heippa taas AimoKulaus!

tutki piruuttas mitä tapahtuu joka kerta kun painat nappia...

'...
Dim a As String = Dir(Hakemisto + "*.jpg")
MsgBox(a) 'tsekkaa tällä
'...

AimoKulaus [12.12.2008 08:21:47]

#

Tää on helppo: Joka kerran tulee sama tiedosto. Siksipä seuraavan kerran pitää olla "tyhjä" Dir. Alkuperäisessäkin ohjelmassa on tämä rakenne

Dim hakemisto As String = "C:\tmp\"
Dim a As String
a= Dir(Hakemisto + "*.jpg")
Do Until a = ""
   MsgBox(a) 'tsekkaa tällä
   a = Dir()
Loop

Dirrillä tiedostot tulevat epämääräisessä järjestyksessä, luultavasti luontijärjestyksessä. Tosin tällä ei nyt ole tässä tapauksessa väliä.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta