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
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.
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.