Oppure

Loading
13/12/10 13:47
Thejuster
Era da tempo che non chiedevo aiuto sul form

avete persente le immagini jpg che se proviamo a colorare il background,
rimangono delle traccie dell'immagine precedente andando ad incasinare la successiva..

hmm guardate.

img171.imageshack.us/img171/350/…

l'immagine a sinistra e quella originale semplicemente modificata con il paint
e cliccando col colore nero su una parte dello sfondo.
come vedete lo sfondo viene rimosso parzialmente e rimane il bianco
sfarfallato

a destra l'immagine modificata tramite l'algoritmo per eliminare automaticamente l'imperfezione dello sfondo.


 private void button2_Click(object sender, EventArgs e)
        {
            SaveFileDialog sv = new SaveFileDialog();
            sv.Filter = "File png(*.png)|*.png|File Bitmap(*.bmp)|*.bmp|File jpg (*.jpg)|*.jpg";

            if (sv.ShowDialog() == DialogResult.OK)
            {
                Bitmap bmp = new Bitmap(file);
                int width = bmp.Width;
                int height = bmp.Height;
                Dictionary<Point, int> currentLayer = new Dictionary<Point, int>();
                currentLayer[new Point(0, 0)] = 0;
                currentLayer[new Point(width - 1, height - 1)] = 0;
                while (currentLayer.Count != 0)
                {
                    //mappatura dell'immagine
                    foreach (Point p in currentLayer.Keys)
                        bmp.SetPixel(p.X, p.Y, Color.Black);
                    Dictionary<Point, int> newLayer = new Dictionary<Point, int>();
                    foreach (Point p in currentLayer.Keys)
                        foreach (Point p1 in Neighbors(p, width, height))
                            if (Distance(bmp.GetPixel(p1.X, p1.Y), Color.White) < 40)
                                newLayer[p1] = 0;
                    currentLayer = newLayer;
                }

                bmp.Save(sv.FileName);
            }
        }


        static int Distance(Color c1, Color c2)
        {
            int dr = Math.Abs(c1.R - c2.R);
            int dg = Math.Abs(c1.G - c2.G);
            int db = Math.Abs(c1.B - c2.B);
            return Math.Max(Math.Max(dr, dg), db);
        }


        static List<Point> Neighbors(Point p, int maxX, int maxY)
        {
            List<Point> points = new List<Point>();
            if (p.X + 1 < maxX) points.Add(new Point(p.X + 1, p.Y));
            if (p.X - 1 >= 0) points.Add(new Point(p.X - 1, p.Y));
            if (p.Y + 1 < maxY) points.Add(new Point(p.X, p.Y + 1));
            if (p.Y - 1 >= 0) points.Add(new Point(p.X, p.Y - 1));
            return points;
        }



purtroppo come vedete dall'immagine alcuni difetti meglio dire residui dell'immagine
rimangono. conoscete un modo migliore per ovviare a questo difetto?

magari qualche consiglio su come implementare o migliorare l'algoritmo usato


Ultima modifica effettuata da Thejuster 13/12/10 13:49
mire.forumfree.it/ - Mire Engine
C# UI Designer
13/12/10 14:22
HeDo
potresti implementare un secchiello "magico" che, dato un pixel di partenza, riempie tutti i vicini che sono dello stesso colore più un delta calibrato sul caso in esame.

non dovrebbe essere difficile implementarlo in C# :)
aaa
13/12/10 15:45
Thejuster
uhm si piu o meno era questo il ragionamento che avevo fatto.
cioè dare una tolleranza minima di un colore che poi tende a verificarne la tonalità con una tolleranza come qui esempio.

if (Distance(bmp.GetPixel(p1.X, p1.Y), Color.White) < 40)

l'idea e stata utile, forse dovrei fare in modo che quando si riscontri una differenza molto notevole allora interrompo se ovviamente si tratti di un canale differente.

provo e ti faccio sapere grazie della dritta saluti :)
mire.forumfree.it/ - Mire Engine
C# UI Designer
13/12/10 16:05
Il Totem
Ti converrebbe trasformare la coordinate RGB nello spazio HSL, che è molto più adatto a verificare la "somiglianza" di colori a causa del parametro hue.
aaa