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 SubKyllä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.
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.
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.
Aihe on jo aika vanha, joten et voi enää vastata siihen.