Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB.NET: Data muuttuu kuvaan tallennettaessa

Hennkka [10.05.2011 20:08:01]

#

Yritän tehdä ohjelmaa, joka tallentaa tekstiä kuvaan ja sitten lukee tekstin kuvasta. Nyt sitten törmäsin ongelmaan: Kun tallennan datan kuvaan, tallennan kuvan levylle, luen kuvan levyltä ja muutan kuvan takaisin dataksi, data on muuttunut. Mistä tämä johtuu? Tässä koodi:

Private Function TekstiKuvaksi(ByVal Teksti As String) As Image
    'Muutetaan teksti taulukkoon
    Dim textData() As Byte = System.Text.Encoding.UTF8.GetBytes(Teksti)

    'Pituus
    Dim pituus As Integer = textData.Length + 4

    'Lasketaan tulevan kuvan koko niin, että kuva on neliö ja mahdollisimman pieni
    Dim koko As Integer = Math.Round(Math.Sqrt(pituus / 3) + 0.5)

    'Valms data-taulukko
    Dim data((koko ^ 2) * 3 - 1) As Byte

    'Tehdään tyhjää tilaa pituutta varten
    Array.Copy(textData, 0, data, 4, textData.Length)

    'Tyhjennetään textData
    textData = Nothing

    'Lisätään tiedoston pituus ensimmäisiin neljään tavuun
    Dim pituusData() As Byte = BitConverter.GetBytes(Net.IPAddress.HostToNetworkOrder(pituus - 4))
    Array.Copy(pituusData, 0, data, 0, 4)

    'Kuva johon piirretään
    Dim kuva As New Bitmap(koko, koko, Imaging.PixelFormat.Format24bppRgb)



    'Laitetaan data kuvaan
    Dim bitmapData As Imaging.BitmapData = kuva.LockBits(New Rectangle(Point.Empty, kuva.Size), _
                                                         Imaging.ImageLockMode.WriteOnly, _
                                                         kuva.PixelFormat)

    Runtime.InteropServices.Marshal.Copy(data, 0, bitmapData.Scan0, data.Length)

    kuva.UnlockBits(bitmapData)

    'Otetaan data kuvasta
    bitmapData = kuva.LockBits(New Rectangle(Point.Empty, kuva.Size), _
                                                         Imaging.ImageLockMode.ReadOnly, _
                                                         kuva.PixelFormat)

    'Palautetaan kuva
    Return kuva
End Function

Private Function KuvaTekstiksi(ByVal Kuva As Bitmap) As String
    'Otetaan data kuvasta
    Dim bitmapData As Imaging.BitmapData = Kuva.LockBits(New Rectangle(New Point(0, 0), Kuva.Size), _
                                                         Imaging.ImageLockMode.ReadOnly, _
                                                         Kuva.PixelFormat)

    'Luodaan data-taulukko
    Dim data(bitmapData.Stride * Kuva.Height - 1) As Byte

    Runtime.InteropServices.Marshal.Copy(bitmapData.Scan0, data, 0, data.Length)

    Kuva.UnlockBits(bitmapData)

    'Pituus
    Dim pituus As Integer = Net.IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 0))
    Return System.Text.Encoding.UTF8.GetString(data, 4, pituus)
End Function

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim a As Image = TekstiKuvaksi(TextBox1.Text)
    a.Save("kuva.png", Imaging.ImageFormat.Png)
    TextBox1.Text = KuvaTekstiksi(Image.FromFile("kuva.png"))
End Sub

Grez [10.05.2011 22:36:09]

#

Kyllähän tuo toimii hienosti, jos kuvan leveys sattuu olemaan 4 jaollinen. Jos kuvasta tulee vaikka 3x3 niin tuo bitmapdata.Stride on 4 ja siellä on siis aina 3*3 tavua hyötydataa, jonka jälkeen 3 tavua (se neljäs pikseli roskaa) ja sitten taas 3*3 tavua hyötydataa. Nyt et huomioi tuota seikkaa ja mukaan tulee myös roskat.

Ihan vinkkinä: VB.Netissä on helpompia ja toimivampiakin tapoja tallettaa merkkijonoja kiintolevylle.

Hennkka [11.05.2011 07:15:51]

#

Täytyypä kokeilla tuota Stride-juttuu iltapäivällä kun pääsen koneelle. Pitäisikö sen arvo asettaa samaksi kuin kuvan kuvan leveys?

Tiedän, että tekstin tallentamiseen on helpompiakin tapoja, mutta tarkoitus onkin verrata eri kuvatiedostomuotojen eroja.

Grez [11.05.2011 09:56:41]

#

Hennkka kirjoitti:

Täytyypä kokeilla tuota Stride-juttuu iltapäivällä kun pääsen koneelle. Pitäisikö sen arvo asettaa samaksi kuin kuvan kuvan leveys?

Ei vaan kuvadataa pitäisi käsitellä niin, että kullakin rivillä kuvan todellisen piskelimäärän jälkeen pitäisi jättää ne ylimääräiset pisteet pois tuloksesta.

Vastaus

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

Tietoa sivustosta