Zmiana koloru poszczególnego pixela

0

jak w temacie mam do zrobienia programik który po wczytaniu pliku (to mam i nawet działa)

{
            string nazwa;
            OpenFileDialog openFileDialog1 = new OpenFileDialog();


            openFileDialog1.Title = "Otwórz focie :D";


            openFileDialog1.Filter = "jpeg (*.jpeg)|*.jpeg|jpg (*.jpg)|*.jpg|bmp (*.bmp)|*.bmp";

            openFileDialog1.FilterIndex = 2;

            openFileDialog1.RestoreDirectory = true;
            openFileDialog1.FileName = "";
            
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {


                nazwa = openFileDialog1.FileName;
                pictureBox1.Image = Bitmap.FromFile(nazwa);

            }

        }

i po naciśnięciu przycisku zrobi z obrazu negatyw i inne tego typu no i właśnie nie wiem za bardzo jak mam to zrobić
korzystam z Visual studio 2008
i przy okazji polecacie jakieś dobre poradniki??

1
        //using System.Drawing.Imaging;

        struct RGB  { public byte B, G, R; }

        private void Form1_Load(object sender, EventArgs e)
        {
            pictureBox1.Image = Image.FromFile(@"d:\12072001.jpg");
            var bmp = pictureBox1.Image as Bitmap;
            BitmapData bd = bmp.LockBits(new Rectangle(0,0,bmp.Width,bmp.Height),
                                         ImageLockMode.ReadWrite,
                                         PixelFormat.Format24bppRgb);
            for (int y=0; y<bmp.Height; y++) unsafe
            {
               RGB* scanline = (RGB*)((byte*)bd.Scan0 + bd.Stride*y);
               for (int x=0; x<bmp.Width; x++)
               {
                   scanline[x].R = (byte)(255 - scanline[x].R);
                   scanline[x].G = (byte)(255 - scanline[x].G);
                   scanline[x].B = (byte)(255 - scanline[x].B);
               }
            }
            bmp.UnlockBits(bd);
        }

Z tym, że do zabawy wskaźnikami trzeba we właściwościach projektu włączyć „allow unsafe code”.
Można tego uniknąć, ale kod będzie wolniejszy.

0

wielkie dzięki zmieniłem i dodalem jeszcze to

if (nazwa != null)
            {
                pictureBox1.Image = Image.FromFile(nazwa);

żeby się nie krzaczył jak nie ma żadnego pliku wczytanego
ale jak zrobić ze jak 2 raz kliknie się to negatyw to żeby znowu zrobił negatyw czyli wrócił do pierwotnego stanu
bo z tego co rozumiem to za każdym razem po wyborze negatyw on pobiera plik od nowa, a chcę aby korzystał z tego co już jest wczytany

0

o i jak zrobić sepie bo wyczytałem że tak

public void sepia(object sender, EventArgs e)
        {
            if (liczba2 != 0)
            {
                liczba2 = 0;
                pictureBox1.Image = Bitmap.FromFile(nazwa);
            }
            else
            {

                if (pictureBox1.Image != null)
                {
                    pictureBox1.Image = Bitmap.FromFile(nazwa);
                    var bmp = pictureBox1.Image as Bitmap;
                    BitmapData bd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
                                                ImageLockMode.ReadWrite,
                                                PixelFormat.Format24bppRgb);
                    for (int y = 0; y < bmp.Height; y++) unsafe
                        {
                            RGB* scanline = (RGB*)((byte*)bd.Scan0 + bd.Stride * y);

                            for (int x = 0; x < bmp.Width; x++)
                            {

                                if ((scanline[x].R * .393 + scanline[x].G * .769 + scanline[x].B * .189) > 255)
                                    scanline[x].R = 255;
                                else
                                    scanline[x].R = (byte)(scanline[x].R * .393 + scanline[x].G * .769 + scanline[x].B * .189);


                                if ((scanline[x].R * .349 + scanline[x].G * .686 + scanline[x].B * .168) > 255)
                                    scanline[x].G = 255;
                                else
                                    scanline[x].G = (byte)((scanline[x].R) * .349 + (scanline[x].G) * .686 + (scanline[x].B) * .168);

                                if ((scanline[x].R * .272 + scanline[x].G * .534 + scanline[x].B * .131) > 255)
                                    scanline[x].B = 255;
                                else
                                    scanline[x].B = (byte)((scanline[x].R) * .272 + (scanline[x].G) * .534 + (scanline[x].B) * .131);

                            }
                        }
                    bmp.UnlockBits(bd);

                }
                liczba2++;
 
            }
        }
 

ale z tego nie powstaje sepia coś podobnego ale to nie jest to

0

Nie wiem jak zrobić sepię. Ale

liczba2 = 0;

Co to za „liczba2”? Cokolwiek ona robi, tego powinno nie być ;-)

public void sepia(object sender, EventArgs e)

Podziel to sobie na Metody. Wydziel kod grzebiący na grafice np. do czegoś takiego

  void sepia(Bitmap bmp)
  {
    // tu operacje na bmp
  }

i wywołuj

  sepia(pictureBox1.Image as Bitmap);
0

ta liczba jest po to aby 2 klikniecie na sepie wróciło do pierwotnego stanu zdjęcia, bo ta operacją która jest to za każdym razem wczytuje od nowa zdjęcie z pliku i robi sepie, i nie dałoby się wrócić do pierwotnego stanu,
a nie wiedziałem jak to zrobić więc zrobiłem tak :D
a te mnożniki są dobre bo zdjęcie przerobione tym kodem wygląda jak mieszanka sepii z odcieniami szarości
dodaje w załączniku cały projekt

1 użytkowników online, w tym zalogowanych: 0, gości: 1